Did you know that you can navigate the posts by swiping left and right?
본 글은 이승원이 집필한 「리버싱 핵심원리」 를 읽고 공부(정리)한 내용을 바탕으로 쓰여졌습니다.
IA-32는 Intel Architecture, 32bits의 준말이다. CPU - 레지스터 - 주기억장치(RAM) - 보조기억장치(HDD, SSD) 순으로 정보를 사용.
CPU 내부에서 각종 정보를 저장하기 위해 임시 기억 장치인 레지스터를 사용한다. 레지스터는 사이즈가 작으니깐, 주기억 장치인 메모리(RAM)를 사용한다. RAM은 사이즈도 작고, 휘발성 메모리 컴퓨터 끄면 다 날아감이라서, 비휘발성메모리인 하드디스크요즘은 SSD를 사용한다.
레지스터란 CPU 내부에 존재하는 다목적 저장 공간이다.
CPU가 메모리인 RAM의 데이터에 접근하기 위해서는 물리적으로 복잡하다. 그러므로 레지스터라는 CPU 안의 저장공간을 이용해서 고속으로 데이터를 처리할 수 있도록 한다.
이름 그대로 범용적으로 사용되는 레지스터의 모음. IA-32에서는 각각의 레지스터들의 크기는 32bits (4bytes)이다. 보통은 상수/주소 등을 저장할 때 주로 사용되며, 특정 어셈블리 명령어에서는 특정 레지스터를 조작하기도 한다. 특수한 용도로 사용되는 레지스터도 있다.
EAX(Extended Accumulator Register): 함수의 리턴값을 저장 또는 산술 연산에 사용 EBX(Extended Base Register): 특정 주소를 지정하기 위해 사용 ECX(Extended Counter Register): 반복적인 명령어 수행 시 횟수 저장에 사용 EDX(Extended Data Register): 큰 수의 곱셈, 나눗셈 등의 연산 시 EAX 레지스터와 함께 사용 ESI(Extended Source Index): 문자열 복사, 비교 시 소스 문자열 주소 저장에 사용 EDI(Extended Destination Index): 문자열 복사, 비교 시 목적지 문자열 주소 저장에 사용 EBP(Extended Base Pointer): 함수 인자, 스택 변수에 접근하기 위해 사용 ESP(Extended Stack Pointer): 스택의 크기를 조정할때 사용
EAX, EBX, ECX ,EDX는 주로 산술연산(ADD, SUB, XOR, OR 등) 명령어에서 상수/변수 값의 저장 용도로 많이 사용된다. 어떤 어셈블리 명령어(MUL, DIV, LODS 등)들은 특정 레지스터를 직접 조작하기도 한다. ECX와 EAX는 특수한 용도로도 사용된다. ECX는 반복문 명령어(LOOP)에서 반복 카운트(loop count)로 사용된다. EAX는 일반적으로 함수 리턴 값에 사용된다. (모든 Win32 API 함수는 그렇게 사용됨)
EBP, ESI, EDI, ESP는 주로 메모리 주소를 저장하는 포인터로 사용된다. ESP는 스택 메모리 주소를 가리킨다. 어떤 명령어(PUSH, POP, CALL, RET)들은 ESP를 직접 조작한다. EBP는 함수가 호출되었을 때 순간의 ESP를 저장하고 있다가, 함수가 리턴하기 전에 다시 ESP 값을 되돌려줘서 스택이 깨지지 않도록 한다. (Stack Frame 기법) ESI와 EDI는 특정 명령어들(LODS, STOS, REP MOVS 등)과 함께 주소 메모리 복사에 사용된다.
세그먼트란 메모리를 조각내어 각 조각마다 시작 주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법이다. 또한, 페이징(Paging) 기법과 함께, 가상 메모리를 실제 물리 메모리로 변경할 때 사용된다.
CS(Code Segment): 컴퓨터가 수행할 수 있는 명령어들이 저장. 명령어의 위치 저장 SS(Stack Segment): 지역 변수와 함수 호출 인자를 저장. 메모리 상 스택의 구현을 실현 DS(Data Segment): 전역 변수와 힙(Heap)을 저장하는 메모리 영역. 시작 주소값이 저장. ES(Extra Segment): 추가로 사용된 DS의 주소를 저장. 딱히 저장되어있진 않고, 프로그래머에 의해 결정. FS: ES와 비슷한 용도. 여분의 세그먼트 레지스터. GS: ES와 비슷한 용도. 여분의 세그먼트 레지스터.
컴퓨터의 다양한 상태를 나타내는 비트 포함. 상태 플래그, 제어 플래그, 시스템 플래그로 구성. 각 비트마다 의미를 가지고 있으며 1과 0의 값이 각각 On/Off 또는 True/False를 의미한다.
Zero Flag(ZF): 연산 명령 후에 결과 값이 0이 되면 ZF가 1(True)로 세팅된다. Overflow Flag(OF): 부호 있는 수의 오버플로가 발생했을 때 1로 세팅, MSB(Most Significant Bit)가 변경되었을 때 1로 세팅 Carry Flag(CF): 부호 없는 수의 오버플로가 발생했을 때 1로 세팅
CPU가 처리할 명령어의 주소를 나타내는 레지스터. 크기는 32bits(4bytes)이다. 그래서 Windows 7 32bits에서 램 4G 밖에 인식을 못하나보다. CPU는 EIP에 저장된 메모리 주소의 명령어를 하나 처리하고 난 후 자동으로 명령어의 길이만큼 EIP를 증가한다. EIP는 값을 직접 변경할 수 없도록 되어있으므로 다른 명령어를 통해서 간접적으로 변경해야한다. (JMP, Jcc, CALL, RET 등 또는 interrupt, exception 등)