IA-32 Register 설명

2019. 9. 10. 04:14Reversing

 CPU 레지스터란?

     - 레지스터(register)란 CPU 내부에 존재하는 다목적 저장 공간입니다.

     - CPU 내부의 RAM 보다 속도가 훨씬 빠르고 작은 다목적 저장 공간

 

레지스터를 알아야하는 이유

  - 어셈블리 명령어의 대부분은 레지스터를 조작하고 그 내용을 검사하는 것들인데

    정작 레지스터를 모르면 명령어 자체도 이해하기 힘들어지기 떄문입니다.

 

 

리버싱에 초 단계에서는 기본 프로그램 실행 레지스터에 대해 알아두어야 합니다.

디버깅을 할 때 가장 많이 보게 될 레지스터 입니다.

 

기본 프로그램 실행 레지스터(Basic program execution register)

- 기본 프로그램 실행 레지스터는 다시 4개의 그룹으로 나눌 수 있습니다.

1. General-Purpose Register(범용 목적 레지스터)

2. Segment Register(세그먼트 레지스터)

3. Program status and Control Register(프로그램 상태와 컨트롤 레지스터)

4. Instruction pointer(명령어 포인터-EIP) 

1) 범용 레지스터 

범용 레지스터는 이름처럼 범용적으로 사용되는 레지스터 입니다.('막 쓰는 레지스터들이라고 생각하면 됩니다.')

IA-32에서 각각의 범용 레지스터들의 크기는 32bit(4byte) 입니다.

보통은 상수/주소 등을 저장할 때 주로 사용되며, 특정 어셈블리 명령어에서는 특정 레지스터를 조작하기도 합니다.

또한, 어떤 레지스터들은 특수한 용도로 사용되기도 합니다.

 


참고

EAX: 32bit

AX: EAX의 하위 16bit

AH: AX의 상위 8bit

AL: AX의 하우 8bit

 

공간을 나누어서 알뜰하게 사용할 수 있습니다.


각 레지스터이 이름과 용도

EAX: Accumulator for operands and result data -피연산자 및 result(결과) data 저장

EBX: Pointer to data in the DS segment -DS 세그먼트에 데이터를 가리키는 포인터

ECX: Counter for string and loop operations -문자열, 루프 연산 카운트

EDX: I/O pointer - 입출력

 

- 위 4개의 레지스터들은 주로 산술연산(ADD, SUB, XOR, OR 등) 명령어에서 상수/변수 값의 

   저장 용도로 많이 사용됩니다.

- 어떤 어셈블리 명령어(MUL, DIV, LODS 등) 들은 특정 레지스터를 직접 조작하기도 합니다.

- ECX와 EAX는 특수한 용도로도 사용됩니다. ECX는 반복문 명령어(LOOP)에서 반복 카운트(Loop count)로 사용됩니다.

  (루푸를 돌 때마다 ECX를 1씩 감소시킵니다.) EAX는 일반적으로 함수 리턴 값에 사용됩니다. 모든 

  win32 API 함수들은 리턴 값을 EAX에 저장한 후 리턴합니다.

 

ESI: source pointer for string operations - 문자열 연산을 위한 포인터

EDI: destination pointer for string operations - 문자열 연산을 위한 포인터
EBP: pointer to data on th stack(in the SS segment) - 스택의 데이터 포인터

ESP: stack pointer(in the SS segment) -스택 포인터

 

위 4개의 레지스터들은 주로 메모리 주소를 저장하는 포인터로 사용됩니다.

ESP는 스택 메모리 주소를 가리키는데 어떤 명령어들은(PUSH, POP, CALL, RET)은 ESP를 직접

조작하기도 합니다.(스택 메모리 관리는 프로그램에서 매우 중요하기 때문에 ESP를

다른 용도로 사용하지 말아야 합니다.)

 

ESP: 스택 메모리주소를 가리킴

EBP: 함수 호출 직전의 ESP의 값을 저장했다가 함수가 리턴하기 직전 다시 EBP에 값을 ESP로 되돌려 준다.

==> stack frame 기법이라고 함

 

ESI와 EDI는 특정 명령어들(LOPS, STOS, RET MOVS 등)과 함께 주로 메모리 복사에 사용됩니다.

 

 

세그먼트 레지스터는 건너뜀


 

2)프로그램 상태와 컨트롤 레지스터

 

EFLAGS: flag register

EFLAGS 레지스터는 위 그림과 같이 각각의 비트마다 의미를 가지고 있습니다.

각 비트가 1 또는 0의 값을 가지는데, 이는  On/Off 혹은 True/False를 의미합니다.

일부 비트는 시스템에서 직접 세팅하고, 일부 비트는 프로그램에서 사용된 명령의 수행 결과에 따라 세팅 됩니다.

 

 

EFLAGS 레지스터의 32개의 각 비트 의미를 전부 이해한다는 것은 상당히 어려우므로

리버싱 입문단계에서는 어플리케이션 디버깅에 필요한 3가지 FLAG(ZF, OF, CF)에 대해서만 잘 이해하면 됩니다.

 

이 3개 플래그가 중요한 이유는 특히 조건 분기 명령어에서 이 3개 플래그 값을 확인하고

그에 따라 동작 수행 여부를 결정하기 때문입니다.

 

zero flag(ZF)

- 연산 명령 후에 결과 값이 0이 되면 1로 세팅

overflow flag(OF)

- 부호 있는 수(signed integer)의 오버플로우가 발생했을 때 1로 세팅

- MSB(most sighificant bit)가 변경되었을 때 1로 세팅됩니다.

carry flag(CF)

- 부호 없는 수의 오버플로우가 발생했을 때 1로 세팅 됩니다.


EIP: instruction pointer

 

 CPU가 처리할 명령어의 주소를 나타내는 레지스터이며, 크기는 32비트이다.

CPU는 EIP에 저장된 메모리 주소의 명령어를 하나 처리하고 난 후 자동으로 그 명령어의

길이만큼 EIP를 증가시킵니다. 이런식으로 계속 명령어를 처리해나갑니다.

 

범용 레지스터와는 다르게 EIP는 그 값을 직접 변경할 수 없도록 되어 있어서 다른 

명령어를 통하여 간접적으로 변경해야 합니다. EIP를 변경하고 싶을 때는 

특정 명령어(JMP, Jcc, CALL, RET)을 사용하거나 인터럽트(새치기), 예외(exception)를 발생시켜야 합니다.  

 

 

리버싱 핵심원리 레지스터 부분 정리

 

'Reversing' 카테고리의 다른 글

abex'crack 1 분석  (0) 2019.10.03
컴퓨터 구조 01 -제어장치와 명령어  (0) 2019.06.25
컴퓨터 메모리&레지스터 구조  (0) 2019.06.19