본문 바로가기
reversing

CPU 레지스터

by 코끼리_땃쥐 2021. 11. 4.
반응형

레지스터란 cpu내부에 존재하는 다목적 저장 공간입니다. 우리가 일반적으로 일반적으로 메모리라고 얘기하는 RAM(Random Access Memory)과는 조금 성격이 다릅니다. CPU가 RAM에 있는 데이터를 엑세스(Access)하기 위해서는 물리적으로 먼 길을 돌아가야 하기 때문에 시간이 오래 걸립니다. 하지만 레지스터는 CPU와 한 몸이기 때문에 고속으로 데이터를 처리할 수 있습니다.

 

1. 범용 레지스터

범용 레지스터(General Purpose Registers)는 이름처럼 범용적으로 사용되는 레지스터들입니다.('막'쓰는 '막'레지스터들이라고 생각하면 됩니다.) IA-32에서 각각의 범용 레지스터들의 크기는 32비트(4바이트)입니다. 보통은 상수/주소 등을 저장할 때 주로 사용되며, 특정 어셈블리 명령어에서는 특정 레지스터를 조작하기도 합니다. 또한 어떤 레지스터들은 특수한 용도로 사용되기도 합니다.

각 레지스터의 이름은 아래와 같습니다.

 

EAX : Accumulator for operands and result data

EBX : Pointer to data in the DS segment

ECX : Counter for string and loop operations

EDX : I/O pointer

 

위 4개의 레지스터들은 주로 산술연산 (ADD, SUB, XOR, OR 등) 명령어에서 상수/변수 값의 저장 용도로 많이 사용됩니다. 어떤 어셈블리 명렁어(MUL, DIV, LODS등)들은 특정 레지스터를 직접조작하기도 합니다.(이런 명령어가 실행된 이후에 특정 레지스터들의 값이 변경됩니다.)

그리고 추가적으로 ECX와 FAX는 특수한 용도로도 사용됩니다. ECX는 반복문 명령어(LOOP)에서 반복 카운트(loop count)로 사용됩니다.(루프를 돌 때마다 ECX를 1씩 감소시킵니다.) EAX는 일반적으로 함수 리턴 값에 사용됩니다. 모든 Win32 API함수들은 리턴 값을 EAX에 저장한 후 리턴합니다.

나머지 범용 레지스터들의 이름은 아래와 같습니다.

 

EBP : Pointer to data on the stack (in the SS segment)

ESI : source pointer for string operations

EDI : destination pointer for string operations

ESP : Stack pointer (in the SS segment)

 

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

ESP는 스택 메모리 주소를 가리킵니다. 어떤 명령어들(PUSH, POP, CALL, RET)은 ESP를 직접 조작하기도 합니다.(스택 메모리 관리는 프로그램에서 매우 중요하기 때문에 ESP를 다른 용도로 사용하지 말아야 합니다.)

EBP는 함수가 호출 되었을 때 그 순간의 ESP를 저장하고 있다가, 함수가 리턴 하기 직전에 다시 ESP에 값을 되돌려줘서 스택이 깨지지 않도록 합니다.(이것을 Stack Frame 기법이라고 합니다.)

 

2. 세그먼트 레지스터

세그먼트(Segment)란 IA-32의 메모리 관리 모델에서 나오는 용어입니다.

IA-32 보호 모드에서 세그먼트란 메모리를 조각 내어 각 조각마다 시작 주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법을 말합니다. 또한 세그먼트는 페이징(Paging) 기법과 함께 가상 메모리를 실제 물리 메모리로 변경할 때 사용됩니다. 세그먼트 메모리는 Segment Descriptor Table(SDT)이라고 하는 곳에 기술되어 있는데, 세그먼트 레지스터는 바로 이 SDT의 index를 가지고 있습니다.

세그먼트 레지스터는 총 6개(CS, SS, DS, ES, FS, GS)이며 각각의 크기는 16비트(2바이트)입니다. 각 세그먼트 레지스터가 가리키는 세그먼트 디스크립터(Segment Discriptor)와 가상 메모리가 조합되어 선형주소(Linear Address)가 되며, 페이징 기법에 의해서 선형 주소가 최종적으로 물리주소(Physical Address)로 변환됩니다.

각 세그먼트 레지스터의 이름은 아래와 같습니다.

 

CS : Code Segment

SS : Stack Segment

DS : Data Segment

EX : Extra(Data) Segment

FS : Data Segment

GS : Data Segment

 

이름 그대로 CS는 프로그램의 코드 세그먼트를 나타내며, SS는 스택 세그먼트, DS는 데이터 세그먼트를 나타냅니다. ES, FS, GS 세그먼트는 추가적인 데이터 세그먼트입니다.

FS 레지스터는 애플리케이션 디버깅에도 자주 등장하는데 SEH(Structrured Ex-ception Handling), TEB(Thread Environment Block), PEB(Process Environ-ment Block) 등의 주소를 계산할 때 사용되며 이들은 모두 고급 디버깅 주제 입니다.

 

3. 프로그램 상태와 컨트롤 레지스터

EFLAGS : Flag Register

플래그(Flag) 레지스터의 이름은 EFLAGS이며 32비트(4바이트) 크기입니다.(EFLAGS 레지스터 역시 16비트 FLAGS 레지스터의 32비트 확장 형태입니다.) EFLAGS 레지스터는 각각의 비트마다 의미를 가지고 있습니다. 각 비트는 1 또는 0 의 값을 가지는데, 이는 On/Off 혹은 True/False를 의미합니다. 일부 비트는 시스템에 직접 세팅하고, 일부 비트는 프로그램에서 사용됨 명령의 수행 결과에 따라 세팅됩니다.

 

- Zero Flag(ZF)

  연산 명령 후에 결과 값이 0이 되면 ZF가 1(True)로 세팅 됩니다.

 

- Overflow Flag(OF)

  부호 있는 수(signed integer)의 오버플로가 발생했을 때 1로 세팅됩니다.

  그리고 MSB(Most Significant Bit)가 변경되었을 때 1로 세팅됩니다.

 

- Carry Flag(CF)

  부호 없는 수(unsigned integer)의 오버플로가 발생했을 때 1로 세팅됩니다.

 

4. instruction Pointer

EIP : Instruction pointer

Instruction Pointer는 CPU가 처리할 명령어의 주소를 나타내는 레지스터이며, 크기는 32비트(4바이트)입니다.(16비트의 IP레지스터의 확장 형태입니다.) CPU는 EIP에 저장된 메모리 주소의 명령어(instruction)를 하나 처리하고 난 후 자동으로 그 명령어 길이 만큼 EIP를 증가시킵니다. 이런 식으로 계속 명령어를 처리해 나갑니다.

범용 레지스터들과는 다르게 EIP는 그 값을 직접 변경할 수 없도록 되어있어서다른 명령어를 통하여 간접적으로 변경해야합니다. EIP를 변경하고 싶을 때는 특정명렁어(JMP, Jcc, CALL, RET)를 사용하거나 인터럽트(interrupt), 예외(exception)를 발생시켜야 합니다.

반응형

'reversing' 카테고리의 다른 글

Hook ? (훅 이란 ?)  (0) 2022.02.24
함수호출 규약(Calling Convention)  (0) 2021.11.09
스택 프레임  (0) 2021.11.08
스택  (0) 2021.11.04
기초 리버싱  (0) 2021.11.02

댓글