본문 바로가기
[보안 Archive] ~2017/리버싱 핵심 원리

[1주] 3장~4장 - 리틀엔디언, IA-32 레지스터

by Joy L. 2015. 3. 9.
반응형

리버싱 핵심 원리

                              [1주]




3장 - 리틀 엔디언 표기법


바이트 오더링(Byte Ordering)은 데이터를 저장하는 방식.

크게 2가지 방식이 있다 : 

1. 빅 엔디언(Big Endian)

2. 리틀 엔디런(Little Endian)


어떻게 다른지 보자



1바이트의 자료형을 저장할떄는 차이가 없다. 자료형의 크기가 2바이트 이상이면 차이가 난다.


 빅 엔디언

 리틀 엔디언

 데이터를 저장할 때 앞에서부터 순차적으로 저장  한다.

 저장되는 바이트의 순서가 뒤집혀 있다.

 RISC 계열의 CPU에서 사용됨.

 네트워크 프롵콜에서 사용됨.

 Intel x86 CPU에서 사용됨.

 장점 : 사람이 보기에 직관적이다

 장점 : 산술 연산과 데이터의 타입이 확장/축소될  때 더 효율적이다. 


str 문자열은 엔디언 형식과 상관없이 동일하다. 문자열은 캐릭터(char) 배열이기 때문에 각 바이트를 하나씩 연속해서 저장하기 때문.


※ 네트워크 프로토콜에서 빅 엔디언이 사용되고 x86 계열의 응용 프로그램은 리틀 엔디언을 사용하기 때문에 애플리케이션의 개발에 사용된 데이터를 네트워크로 송수신할 때 엔디언 타입을 변경해야 한다.


실제로 OllyDbg에서 Dump창을 보면 값들이 리틀 엔디언 형식으로 저장된걸 확인할 수 있다.




4장 - IA-32 Register 기본 설명

(IA-32 = Intel Architecture 32비트)


IA-32는 많은 레지스터가 있는데, 디버깅 할 때 제일 많이 보게 되는 레지스터는 Basic program execution register다.


Basic program execution register는 4개로 나눌 수 있다:

1. 범용 레지스터 (General purpose registers) (32비트 - 8개)

2. Segment Registers (16비트 -6개)

3. Program Status and Control Register (32비트 - 1개)

4. Instruction Pointer (32비트 - 1개)





1. 범용 레지스터 (General Purpose Registers)


막(?) 쓰이는 레지스터다



EAX : Accumulator for operands and results data

EBX : Pointer to data in the DS segment

ECX : Counter for string and loop operations

EDX : I/O pointer


EAX, EBX, ECX, EDX 는 산술연산(ADD, SUB, XOR, OR 등) 명령어에서 상수/변수 값의 저장 용도로 많이 쓰임.

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)


EBP, ESI, EDI, ESP는 주로 메모리 주소를 저장하는 포인터로 사용됨.

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

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




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


세그먼트란?

* IA-32 보호모드에서 세그먼트란 메모리를 조각내어 각조각마다 시작주소, 범위,접근권한 등을 부여해서 메   모리를 보호하는 기법이다.

* 세그먼트는 Paging 기법과 함께 가상 메모리를 실제 물리 메모리로 변경할 때 사용된다.

* 세그먼트 메모리는 Segment Descriptor Table(SDT)이라고 하는 곳에 기술되어 있는데,세그먼트 레지스터   는 바로 이 SDT의 index를 가지고 있다.



세그먼트 레지스터는 6개 CS, SS, DS, ES, FS, GS. 각각 16비트.


각 세그먼트 레지스터가 가리키는 세그멘트 디스크립터(Segment Descriptor)와 가상 메모리가 조합되어 선형주소(Linear Address)가 된다. ( 세그먼트 디스크립터 + 가상 메모리 =  선형주소). 그리고 페이징 기법에 의해서 선형주소가 최종적으로 물리주소(Physical Address)로 변환된다. ( 선형주소 --(페이징기법)--> 물리주소 )


CS : Code Segment 

SS : Stack Segment

DS : Data Segment 

ES : Extra(Data) Segment

FS : Data Segment

GS Data Segment


※ FS 레지스터는 SEH(Structure Exception Handling), TEB(Thread Environment Block), PEB(Process Environment Block) 등의 주소를 계산할 때 사용됨.




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


EFLAGS : Flag Register

각 비트마다 의미를 가지고 있다.



ZF(Zero Flag) : 연산 명령 후에 결고 값이 0이 되면 ZF가 1(True)로 세팅된다.

OF(Overflow Flag) : Signed integer의 오버플로우가 발새했을 때 1로 세팅됨. MSB(Most Significant Bit)가 변경되었을 때 1로 세팅됨.

CF(Carry Flag) : Unsigned integer의 오버플로우가 발생했을 때 1로 세팅됨. 




4. Instruction Pointer


EIP - Instruction Pointer


CPU가 처리할 명령어의 주소를 나타내는 레지스터. CPU는 EIP에 저장된 메모리의 주소의 명령어 하나를 처리하고 난 후 자동으로 그 명령어 길이만큼 EIP를 증가 시킨다.


※ EIP는 그 값을 직접적으로 변경할 수 없도록 되어있다. 다른 명령어를 통해 간접적으로 변경해야한다. 변경하고 싶을 때는 특정 명령어 (JMP, Jcc, CALL, RET)를 사용하거나 interrupt, exception을 발생시켜야 한다.


반응형

'[보안 Archive] ~2017 > 리버싱 핵심 원리' 카테고리의 다른 글

[2주] 7장- 스택 프레임  (0) 2015.03.16
[1주] 5장~6장 - 스택 & abex crackme #1  (0) 2015.03.09
[1주] 1장~2장  (0) 2015.03.09

댓글