minhui study
32bit Register (범용, 세그먼트, EFLAGS...) 본문
CPU 레지스터란?
레지스터란 CPU 내부에 존재하는 다목적 저장공간이다. CPU가 RAM에 있는 데이터를 Access하기 위해서는 물리적으로 먼 길을 돌아가야 하기 때문에 시간이 오래 걸리지만 레지스터는 CPU와 한 몸이기 때문에 고속으로 데이터를 처리할 수 있다.
IA-32
IA-32는 인텔의 32비트 마이크로프로세서에서 사용하는 명령 집합 아키텍처를 말한다. IA-32에서 지원하는 기능은 매우 많고 그 만큼 레지스터의 수도 많다. 어플리케이션 디버깅의 초급 단계에서는 Basic Program Execution Registers에 대해서 알아야 하는데 그 이유는 디버깅 할 때 가장 많이 보게 될 레지스터이기 때문이다.
Basic program execution registers
Basic Program Execution Register는 다음과 같이 4개의 그룹으로 나눌 수 있다.
● General Purpose Registers (32bit - 8개)
● Segment Registers (16bit - 6개)
● Program Status and Control Register (32bit - 1개)
● Instruction Pointer (32bit - 1개)
1) 범용 레지스터(General Purpose Registers)
· 범용 레지스터는 이름처럼 범용처럼 사용되는 레지스터이다. IA-32에서 각각의 범용 레지스터들의 크기는 32비트이다.
· 보통은 상수/주소 등을 저장할 때 주로 사용되며, 특정 어셈블리 명령어에서는 특정 레지스터를 조작하기도 한다.
· 논리, 수리 연산에 사용되는 피연산자, 주소를 계산하는 데 사용되는 피연산자, 메모리 포인터가 저장되는 레지스터
· 아래 4개의 레지스터는 주로 산술연산 명령어에서 상수/변수 값의 저장용도로 많이 사용된다. 어떤 어셈블ㄹ 명령어(NUL, DIV 등)들은 특정 레지스터를 직접 조작하기도 한다.
① EAX : Accumulator for operands and results data 피연산자와 연산 결과의 저장소
→ 일반적으로 함수 리턴 값에 사용된다. 모든 Win32 API함수들은 리턴 값을 EAX에 저장한 후 리턴한다.
② EBX : Pointer to data in the DS segment DS segment안의 데이터를 가리키는 포인터
③ ECX : Counter for string and loop operations 문자열 처리나 루프를 위한 카운터
→ 반복문 명령어에서 반복 카운트로 사용되며 루프를 돌 때마다 ECX를 1씩 감소시킨다.
④ EDX : I/O pointer I/O 포인터
· 나머지 범용 레지스터들의 이름은 아래와 같다. 주로 메모리 주소를 저장하는 포인터로 사용되고, ESI와 EDI는 특정 명령어들(LODS, STOS, REP MOVS 등)과 함께 주로 메모리 복사에 사용된다.
① EBP : Pointer to data on the stack(in the SS segment)
→ SS 레지스터가 가리키는 스택 상의 한 데이터를 가리키는 포인터 ( 스택 프레임의 시작 주소 가리킴 )
→ 함수가 호출되었을 때 그 순간의 ESP를 저장하고 있다가 함수가 리턴하기 직전에 다시 ESP에 값을 되돌려줘서 스택이 깨지지 않도록 한다.
② ESI : source pointer for string operations
→ DS 레지스터가 가리키는 data segment 내의 어느 데이터를 가리키고 있는 포인터, 문자열 처리에서 source
③ EDI : destination pointer for string operations
→ ES 레지스터가 가리키는 data segment 내의 어느 데이터를 가리키고 있는 포인터, 문자열 처리에서 destination
④ ESP : Stack pointer (in the SS segment) SS레지스터가 가리키는 stack segment의 맨 꼭대기를 가리키는 포인터
→ 스택 메모리 주소를 가리킨다. 어떤 명령어들(PUSH, POP, CALL, RET)은 ESP를 직접 조작하기도 한다.
(스택 메모리 관리는 프로그램에서 매우 중요하기 때문에 ESP를 다른 용도로 사용하지 말아야 한다.)
2) 세그먼트 레지스터( Segment Registers )
· 세그먼트 레지스터는 현재 세그먼트라고 하는 메모리의 한 영역에 대한 주소지정을 제공한다.
· IA-32 보호 모드에서 세그먼트란 메모리는 조각내어 각 조각마다 시작 주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법을 말한다.
· 세그먼트는 페이징 기법과 함께 가상 메모리를 실제 물리 메모리로 변경할 때 사용된다.
· 세그먼트 메모리는 Segment Descriptor Tabe(SDT)이라고 하는 곳에 가술되어 있는데 세그먼트 레지스터는 바로 이 SDT의 index를 가지고 있다.
① CS : 코드 세그먼트를 나타낸다.
② SS : 스택 세그먼트로 메모리 상에 스택의 구현을 가능하게 한다.
③ DS : 데이터 세그먼트의 시작 주소를 포함하여 명령어는 이 주소를 사용하여 데이터의 위치를 알아낸다.
④ ES : 추가적인 데이터 세그먼트로 메모리 주소지정을 다루는 스트링 연산에서 사용된다.
⑤ FS : 추가적인 데이터 세그먼트
⑥ GS : 추가적인 데이터 세그먼트
3) 프로그램 상태와 컨트롤 레지스터
▶ EFLAGS : Flag Register
-
플래그 레지스터의 이름은 EFLAGS 이며 32비트(4바이트) 크기이다
-
각각 비트마다 의미를 가지고있고 각 비트는 1 또는 0 값을 가지는데 on/off or 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비트이다. CPU는 EIP에 저장된 메모리 주소의 명령어를 하나 처리하고 난 후 자동으로 그 명령어 길이만큼 EIP를 증가시킨다.
범용 레지스터들과는 다르게 EIP는 그 값을 직접 변경할 수 없도록 되어 있어서 다른 명령어를 통하여 간접적으로 변경해야 한다. EIP를 변경하고 싶을 때는 특정 명령어(JMP, CALL, RET, Jcc)를 사용하거나 인터럽트, 예외를 발생시켜야 한다.
<참고 자료>
리버싱 핵심원리 (이승원 지음)
'Hacking > Reversing' 카테고리의 다른 글
[WEEK1] 어셈블리어 C언어로 변환하기 (0) | 2020.09.13 |
---|---|
Wargame 'Dreamhack' rev-0 (0) | 2020.09.13 |
Crackme #1 (0) | 2020.09.13 |
[WEEK1]호출규약(32bit/64bit) 정리 (0) | 2020.09.11 |
Stack구조 및 Stack Frame (0) | 2020.09.03 |