출처 : http://www.reversecore.com/
IMAGE_NT_HEADERS : IMAGE_OPTIONAL_HEADER32
IMAGE_OPTIONAL_HEADER32는 PE header 구조체 중에서 가장 크기가 크다.
(64bit PE 파일의 경우 IMAGE_OPTIONAL_HEADER64 구조체를 사용한다.)
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
* 출처 : Microsoft 의 Visual C++ 에서 제공하는 winnt.h |
IMAGE_OPTIONAL_HEADER32 구조체에서 주목해야 할 멤버들은 다음과 같다.
이 값들 역시 파일 실행에 필수적인 값들이기 때문에 잘못 세팅되면 파일이 정상적으로 실행되지 않는다.
#1. Magic
IMAGE_OPTIONAL_HEADER32인 경우 10Bh, IMAGE_OPTIONAL_HEADER64인 경우 20Bh 값을 가진다.
#2. AddressOfEntryPoint
EP(Entry Point)의 RVA(Relative Virtual Address) 값을 가진다.
#3. ImageBase
프로세스의 가상 메모리는 0 ~ FFFFFFFFh 범위이다. (32 bit의 경우)
ImageBase 는 이렇게 광활한 메모리 내에서 PE 파일이 로딩(매핑)되는 시작 주소를 나타낸다.
EXE, DLL 파일은 user memory영역인 0 ~ 7FFFFFFFh에 위치하고,
SYS 파일은 kernel memory 영역인 80000000h ~ FFFFFFFFh에 위치한다.
일반적으로 개발 도구(VB/VC++/Delphi)들이 만들어내는 EXE 파일의 ImageBase 값은 00400000h 이고,
DLL 파일의 ImageBase 값은 01000000h이다. (다른 값도 가능)
PE loader 는 PE 파일을 실행시키기 위해 프로세스를 생성하고 파일을 메모리에 로딩(매핑) 시킨 후
EIP 레지스터 값을 ImageBase + AddressOfEntryPoint 값으로 세팅한다.
#4. SectionAlignment, FileAlignment
PE 파일은 섹션으로 나뉘어져 있는데, 파일에서 섹션의 최소단위를 나타내는 것이 FileAlignment이고,
메모리에서 섹션의 최소단위를 나타내는 것이 SectionAlignment이다.
(하나의 파일에서 FileAlignment 와 SectionAlignment 값은 같을 수도 있고 다를 수도 있다.)
따라서 파일 / 메모리의 섹션 크기는 반드시 각각 FileAlignment / SectionAlignment의 배수가 되어야 한다.
#5. SizeOfImage
PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기를 나타낸다.
일반적으로 파일의 크기와 메모리에 로딩된 크기는 다르다.
(각 섹션의 로딩 위치와 메모리 점유 크기는 나중에 소개할 Section Header에 정의 되어 있다.)
#6. SizeOfHeader
PE header의 전체 크기를 나타낸다. (이 값 역시 FileAlignment의 배수여야 한다.)
파일 시작에서 SizeOfHeader 오프셋만큼 떨어진 위치에 첫 번째 섹션이 위치하게 된다.
#7. Subsystem
1 : Driver file (*.sys)
2 : GUI (Graphic User Interface) 파일 -> notepad.exe 와 같은 윈도우 기반 어플리케이션
3 : CUI (Console User Interface) 파일 -> cmd.exe 와 같은 콘솔 기반 어플리케이션
#8. NumberOfRvaAndSizes
마지막 멤버인 DataDirectory 배열의 개수
구조체 정의에 분명히 배열 개수가 IMAGE_NUMBEROF_DIRECTORY_ENTRIES (16) 이라고 명시 되어 있지만,
PE loader 는 NumberOfRvaAndSizes의 값을 보고 배열의 크기를 인식한다.
#9. DataDirectory
IMAGE_DATA_DIRECTORY 구조체의 배열로써, 배열의 각 항목마다 정의된 값을 가지게 된다.
다음은 각 배열 항목을 나열한 것이다.
DataDirectory[0] = EXPORT Directory
DataDirectory[1] = IMPORT Directory
DataDirectory[2] = RESOURCE Directory
DataDirectory[3] = EXCEPTION Directory
DataDirectory[4] = SECURITY Directory
DataDirectory[5] = BASERELOC Directory
DataDirectory[6] = DEBUG Directory
DataDirectory[7] = COPYRIGHT Directory
DataDirectory[8] = GLOBALPTR Directory
DataDirectory[9] = TLS Directory
DataDirectory[A] = LOAD_CONFIG Directory
DataDirectory[B] = BOUND_IMPORT Directory
DataDirectory[C] = IAT Directory
DataDirectory[D] = DELAY_IMPORT Directory
DataDirectory[E] = COM_DESCRIPTOR Directory
DataDirectory[F] = Reserved Directory
여기서 말하는 Directory란 그냥 어떤 구조체의 배열이라고 생각하면 된다.
빨간색으로 표시한 EXPORT, IMPORT, RESOURCE, TLS Directory를 눈여겨 보자.
특히 IMPORT와 EXPORT Directory 구조는 PE header 에서 매우 중요하다. (나중에 다시 살펴볼 것이다.)
나머지는 중요하지 않기 때문에 크게 신경쓰지 않아도 된다.
이제 실제로 notepad.exe 의 IMAGE_OPTIONAL_HEADER32를 확인해 보자.
구조체 멤버 값과 설명은 다음과 같다.
[ IMAGE_OPTIONAL_HEADER ] - notepad.exe
offset value description --------------------------------------------------------------------------- 000000F8 010B magic 000000FA 07 major linker version 000000FB 0A minor linker version 000000FC 00007800 size of code 00000100 00008C00 size of initialized data 00000104 00000000 size of uninitialized data 00000108 0000739D address of entry point 0000010C 00001000 base of code 00000110 00009000 base of data 00000114 01000000 image base 00000118 00001000 section alignment 0000011C 00000200 file alignment 00000120 0005 major OS version 00000122 0001 minor OS version 00000124 0005 major image version 00000126 0001 minor image version 00000128 0004 major subsystem version 0000012A 0000 minor subsystem version 0000012C 00000000 win32 version value 00000130 00014000 size of image 00000134 00000400 size of headers 00000138 000126CE checksum 0000013C 0002 subsystem 0000013E 8000 DLL characteristics 00000140 00040000 size of stack reserve 00000144 00011000 size of stack commit 00000148 00100000 size of heap reserve 0000014C 00001000 size of heap commit 00000150 00000000 loader flags 00000154 00000010 number of directories 00000158 00000000 RVA of EXPORT Directory 0000015C 00000000 size of EXPORT Directory 00000160 00007604 RVA of IMPORT Directory 00000164 000000C8 size of IMPORT Directory 00000168 0000B000 RVA of RESOURCE Directory 0000016C 00008304 size of RESOURCE Directory 00000170 00000000 RVA of EXCEPTION Directory 00000174 00000000 size of EXCEPTION Directory 00000178 00000000 RVA of SECURITY Directory 0000017C 00000000 size of SECURITY Directory 00000180 00000000 RVA of BASERELOC Directory 00000184 00000000 size of BASERELOC Directory 00000188 00001350 RVA of DEBUG Directory 0000018C 0000001C size of DEBUG Directory 00000190 00000000 RVA of COPYRIGHT Directory 00000194 00000000 size of COPYRIGHT Directory 00000198 00000000 RVA of GLOBALPTR Directory 0000019C 00000000 size of GLOBALPTR Directory 000001A0 00000000 RVA of TLS Directory 000001A4 00000000 size of TLS Directory 000001A8 000018A8 RVA of LOAD_CONFIG Directory 000001AC 00000040 size of LOAD_CONFIG Directory 000001B0 00000250 RVA of BOUND_IMPORT Directory 000001B4 000000D0 size of BOUND_IMPORT Directory 000001B8 00001000 RVA of IAT Directory 000001BC 00000348 size of IAT Directory 000001C0 00000000 RVA of DELAY_IMPORT Directory 000001C4 00000000 size of DELAY_IMPORT Directory 000001C8 00000000 RVA of COM_DESCRIPTOR Directory 000001CC 00000000 size of COM_DESCRIPTOR Directory 000001D0 00000000 RVA of Reserved Directory 000001D4 00000000 size of Reserved Directory |
'정상을향해 > Program Analysis' 카테고리의 다른 글
Python Hacking Programming (3) (0) | 2013.11.10 |
---|---|
Python Hacking Programming (2) (0) | 2013.11.10 |
Python Hacking Programming (1) (0) | 2013.11.10 |
PE File Format (3) (0) | 2013.11.10 |
PE File Format (2) (0) | 2013.11.10 |
PE File Format (1) (0) | 2013.11.10 |