-
[리버싱 핵심원리 study] 38장 PE32+Reverse Engineering 2021. 2. 2. 19:55
64bit Windows OS에서 사용되는 실행 파일 형식인 PE32+에 대해 알아본다. 예가 필요한 경우 notepad.exe의 32bit 버전과 64bit 버전의 비교를 해보자.
1. PE32+(PE+, PE64)
(1) IMAGE_NT_HEADERS
- 32bit
typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
- 64bit
typedef struct _IMAGE_NT_HEADERS64 { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER64 OptionalHeader; } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
위와 같이 마지막 멤버인 IMAGE_OPTIONAL_HEADER 부분이 32bit 혹은 64bit에 의해 IMAGE_NT_HEADERS32 / IMAGE_NT_HEADERS64로 나뉜다.
(2) IMAGE_FILE_HEADER
typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
PE32에서는 Machine 멤버 값이 014C로 고정되었는데, PE32+에서는 8664(AMD64)로 변경되었다.
(3) IMAGE_OPTIONAL_HEADER
- 32bit
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;
- 64bit
typedef struct _IMAGE_OPTIONAL_HEADER64 { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; ULONGLONG 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; ULONGLONG SizeOfStackReserve; ULONGLONG SizeOfStackCommit; ULONGLONG SizeOfHeapReserve; ULONGLONG SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
PE32+에서 기존과 가장 많이 달라진 부분이다. 달라진 부분은 다음과 같다.
- Magic
기존 PE32에서의 Magic 넘버는 010B이지만 PE32+에서는 020B다.
- ImageBase
ImageBase의 자료형이 ULONGLONG으로 바꼈다. 이는 64bit 환경에서 가상 메모리 크기가 확장되면서 프로세스가 올라갈 수 있는 주소의 범위도 확장되었기 때문이다.
- Stack & Heap
스택과 힙을 위한 데이터의 자료형의 크기 또한 마찬가지 이유로 ULONGLONG으로 변경되었다.
달라진 위 세 부분을 CFF Explorer를 통해 찾아보면 아래와 같다.
(4) IMAGE_THUNK_DATA
typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; DWORD OriginalFirstThunk; } DUMMYUNIONNAME; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; } IMAGE_IMPORT_DESCRIPTOR; typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
IMAGE_IMPORT_DESCRIPTOR 구조체의 INT, IAT에 해당하는 OriginalFirstThunk, FirstThunk는 IMAGE_THUNK_DATA 구조체 리스트의 RVA이다. 이때 기존 PE32는 IMAGE_THUNK_DATA가 4바이트 배열을 이루었지만, PE32+에서는 8바이트 배열이 나타난다.
(5) IMAGE_TLS_DIRECTORY
- 32bit
typedef struct _IMAGE_TLS_DIRECTORY32 { DWORD StartAddressOfRawData; DWORD EndAddressOfRawData; DWORD AddressOfIndex; DWORD AddressOfCallBacks; DWORD SizeOfZeroFill; DWORD Characteristics; } IMAGE_TLS_DIRECTORY32; typedef IMAGE_TLS_DIRECTORY32* PIMAGE_TLS_DIRECTORY32;
-64bit
typedef struct _IMAGE_TLS_DIRECTORY64 { ULONGLONG StartAddressOfRawData; ULONGLONG EndAddressOfRawData; ULONGLONG AddressOfIndex; ULONGLONG AddressOfCallBacks; DWORD SizeOfZeroFill; DWORD Characteristics; } IMAGE_TLS_DIRECTORY64; typedef IMAGE_TLS_DIRECTORY64* PIMAGE_TLS_DIRECTORY64;
위와 같이 몇 멤버가 DWORD(4바이트)에서 ULONGLONG(8바이트)로 변경된 것을 확인할 수 있다.
반응형'Reverse Engineering' 카테고리의 다른 글
[리버싱 핵심원리 study] 41장 ASLR (0) 2021.02.08 [리버싱 핵심원리 study] 40장 64비트 디버깅 (0) 2021.02.08 [리버싱 핵심원리 study] 37장 x64 프로세서 이야기 (0) 2021.02.01 [리버싱 핵심원리 study] 36장 64비트 컴퓨팅 (0) 2021.02.01 [리버싱 핵심원리 study] 34장 고급 글로벌 API 후킹 - IE 접속 제어 (0) 2021.01.29