HT Header-optional Header
PE 헤더 구조체 중에서 가장 크기가 큰 IMAGE_OPTIONAL_HEADER32이다.
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; |
IMAGE_OPTIONAL_HEADER32 구조체에서 주목할 맴버에 대해 살펴보자.
1. Magic
Magic 넘버는 IMAGE_OPTIONAL_HEADER32 구조체인 경우 10B, IMAGE_OPTIONAL_HEADER64 구조체인 경우 20B를 가진다.
2. AddressOfEntryPoint
AdressOfEntryPoint는 EP(EntryPoint)의 RVA(Relative Virtual Address)값을 가지고 있다. 이 값은 프로그램에서 최초로 실행되는 코드의 주소로 매우 중요한 값이다.
3. ImageBase
프로세스의 가상 메모리는 0~FFFFFFFFF 범위이다.(32bit인 경우) ImageBase는 이렇게 광활한 메모리에서 PE 파일이 로딩되는 시작 주소를 나타낸다.
EXE,DLL 파일은 user memory 영역인 0~7FFFFFFFF 범위에 로딩되고 SYS 파일은 kernel memory 영역인 80000000~FFFFFFFFF 범위에 로딩된다. 일반적으로 개발도구들이 만들어내는 EXE 파일의 Image Base 값은 00400000이고 DLL 파일의 ImageBase 값은 10000000이다. PE로더는 PE파일을 실행시키기 위해 프로세스를 생성하고 파일을 메모리에 로딩한 후 EIP 레지스터 값을 ImageBase + AddressOfEntryPoint 값으로 세팅한다.
4. SectionAlignment, FileAlignment
PE 파일의 Body 부분은 섹션으로 나뉘어져있다, 파일에서 섹션의 최소 단위를 나타내는 것이 FileAlignment이고 메모리에서 센셕의 최소 단위를 나타내는 것이 SectionAlignment이다. (하나의 파일에서 FileAliignment 와 SectionAlignment는 다를수 있다.) 파일/메모리 섹션의 크기는 반드시 각각 SectionAlignment/FileAlignment의 배수가 되어야 한다.
5. SizeOfImage
SizeOfImage는 PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기를 나타낸다. 일반적으로 파일의 크기와 메모리에 로딩된 크기는 다르다.
6. SizeOfHeader
SizeOfHeader는 PE헤더의 전체 크기를 나타낸다. 이 값 역시 FileAliignment의 배수여야 한다.
7. SubSystem
이 SubSystem의 값을 보고 시스템 드라이버 파일(*.sys)인지 일반 실행파일(*.exe, *.dll)인지 구분 할 수 있다.
1 : Driver file (*.sys)
2 : GUI (Graphic User Interface) 파일 -> notepad.exe 와 같은 윈도우 기반 어플리케이션
3 : CUI (Console User Interface) 파일 -> cmd.exe 와 같은 콘솔 기반 어플리케이션
8. NumberOfRvaAndSizes
NumberOfRvaAndSizes는 IMAGE_OPTIONAL_HEADER32 구조체의 마지막 맴버인 DataDirecroty 배열의 개수를 나타낸다. 구조체의정의에 분명히 배열 개수가 IMAGE_NUMBEROF_DIRECTORY_ENTRIES (16)라고 명시되어있지만 PE 로더는 .NumberOfRvaAndSizes의 값을 보고 배열의 크기를 인식합니다. 즉 16이 아닐수도 있다는 뜻.
9. DataDirectory
DataDirectory는 IMAGE_DATA_DIRECTORY 구조체 배열로 배열긔 각 항목마다 정의 된 값을 가진다.
'리버스 엔지니어링' 카테고리의 다른 글
RVA to RAW (0) | 2018.01.18 |
---|---|
섹션 헤더 (0) | 2018.01.16 |
PE 헤더 -1 (0) | 2018.01.11 |
PE File Format -1 (0) | 2018.01.10 |
함수 호출 규약 (0) | 2018.01.10 |