// PE file format // IMAGE_DOS_HEADER // - sizeof(IMAGE_DOS_HEADER): 64 bytes struct IMAGE_DOS_HEADER { WORD e_magic; // 0x00 Magic number (0x5A4D; "MZ") WORD e_cblp; // 0x02 Bytes on last page of file WORD e_cp; // 0x04 Pages in file WORD e_crlc; // 0x06 Number of relocations WORD e_cparhdr; // 0x08 Size of header in paragraphs WORD e_minalloc; // 0x0A Minimum extra paragraphs needed WORD e_maxalloc; // 0x0C Maximum extra paragraphs needed WORD e_ss; // 0x0E Initial (relative) SS value WORD e_sp; // 0x10 Initial SP value WORD e_csum; // 0x12 Checksum WORD e_ip; // 0x14 Initial IP value WORD e_cs; // 0x16 Initial (relative) CS value ┌──────────WORD e_lfarlc; // 0x18 File address of relocation table (RELOC offset) │ WORD e_ovno; // 0x1A Overlay number │ WORD e_res1[4]; // 0x1C Reserved words │ WORD e_oemid; // 0x24 OEM identifier (for e_oeminfo) │ WORD e_oeminfo; // 0x26 OEM information; e_oemid specific │ WORD e_res2[10]; // 0x28 Reserved words │┌─────────LONG e_lfanew; // 0x3C File address of new exe header (PE offset) ││ }; ││ ││ ││ ││ ││ // DOS Stub Program ││ // - sizeof(DOS stub dummy bytes): 64 bytes ││ └─────→0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ........!..L.!Th │ 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno │ 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS │ 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$....... │ │ │ │ │ // Rich Header │ // - Contains version information of linked libraries │ │ DWORD XORedDanS; // XOR-Encoded 0x536E6144 ("DanS") │ BYTE XORedZeros[12]; // XOR-Encoded zeros-padding for alignment on 16 bytes │ struct RICH_ENTRY_1 { │ DWORD compid; // Linker version │ DWORD count; // Linking frequency │ }; │ struct RICH_ENTRY_2; │ struct RICH_ENTRY_3; │ ... │ DWORD RichSignature; // 0x68636952; "Rich" │ DWORD XorMask; // Used for encrypting Rich header entries │ BYTE DummyBytes[]; // Consists of zeros │ │ │ │ │ // IMAGE_NT_HEADERS │ // - sizeof(IMAGE_NT_HEADERS): 248 bytes │ │ struct IMAGE_NT_HEADERS { └────────→DWORD Signature; // 0x00004550; "PE\0\0" struct IMAGE_FILE_HEADER { // sizeof(IMAGE_FILE_HEADER) = 20 bytes WORD Machine; // 0x00 System architecture on build WORD NumberOfSections; // 0x02 Number of sections DWORD TimeDateStamp; // 0x04 Datetime on build DWORD PointerToSymbolTable; // 0x08 DWORD NumberOfSymbols; // 0x0C WORD SizeOfOptionalHeader; // 0x10 224 bytes(0x00E0) WORD Characteristics; // 0x12 }; struct IMAGE_OPTIONAL_HEADER { // sizeof(IMAGE_OPTIONAL_HEADER) = 224 bytes // Standard fields WORD Magic; // 0x00 32-bit(0x010B), 64-bit(0x020B) BYTE MajorLinkerVersion; // 0x02 BYTE MinorLinkerVersion; // 0x03 DWORD SizeOfCode; // 0x04 DWORD SizeOfInitializedData; // 0x08 DWORD SizeOfUninitializedData; // 0x0C DWORD AddressOfEntryPoint; // 0x10 ┌─────────────DWORD BaseOfCode; // 0x14 .text section ┌──────────────DWORD BaseOfData; // 0x18 .rdata section ││ ││ // NT additional fields ││ DWORD ImageBase; // 0x1C ││ DWORD SectionAlignment; // 0x20 ││ DWORD FileAlignment; // 0x24 Unit size of each section ││ WORD MajorOperatingSystemVersion;// 0x28 ││ WORD MinorOperatingSystemVersion;// 0x2A ││ WORD MajorImageVersion; // 0x2C ││ WORD MinorImageVersion; // 0x2E ││ WORD MajorSubsystemVersion; // 0x30 ││ WORD MinorSubsystemVersion; // 0x32 ││ DWORD Win32VersionValue; // 0x34 ││ DWORD SizeOfImage; // 0x38 ││ DWORD SizeOfHeaders; // 0x3C Total header size of file (not memory) ││ DWORD CheckSum; // 0x40 ││ WORD Subsystem; // 0x44 Driver(1) GUI(2) CLI(3) ││ WORD DllCharacteristics; // 0x46 ││ DWORD SizeOfStackReserve; // 0x48 ││ DWORD SizeOfStackCommit; // 0x4C ││ DWORD SizeOfHeapReserve; // 0x50 ││ DWORD SizeOfHeapCommit; // 0x54 ││ DWORD LoaderFlags; // 0x58 ││ DWORD NumberOfRvaAndSizes; // 0x5C Number of Data Directories ││ ││ // Data directory tables ││ struct IMAGE_DATA_DIRECTORY_1 { // 0x60 IMAGE_DIRECOTRY_ENTRY_EXPORT ┌───────────────────DWORD VirtualAddress; // Relative virtual address from ImageBase │││ DWORD Size; │││ }; │││ struct IMAGE_DATA_DIRECTORY_2 { // 0x68 IMAGE_DIRECOTRY_ENTRY_IMPORT ┌────────────────────DWORD VirtualAddress; // Relative virtual address from ImageBase ││││ DWORD Size; ││││ }; ││││ struct IMAGE_DATA_DIRECTORY_3; // 0x70 IMAGE_DIRECOTRY_ENTRY_RESOURCE ││││ struct IMAGE_DATA_DIRECTORY_4; // 0x78 IMAGE_DIRECOTRY_ENTRY_EXCEPTION ││││ struct IMAGE_DATA_DIRECTORY_5; // 0x80 IMAGE_DIRECOTRY_ENTRY_SECURITY ││││ struct IMAGE_DATA_DIRECTORY_6; // 0x88 IMAGE_DIRECOTRY_ENTRY_BASERELOC ││││ struct IMAGE_DATA_DIRECTORY_7; // 0x90 IMAGE_DIRECOTRY_ENTRY_DEBUG ││││ struct IMAGE_DATA_DIRECTORY_8; // 0x98 IMAGE_DIRECOTRY_ENTRY_ARCHITECTURE ││││ struct IMAGE_DATA_DIRECTORY_9; // 0xA0 IMAGE_DIRECOTRY_ENTRY_GLOBALPTR ││││ struct IMAGE_DATA_DIRECTORY_10; // 0xA8 IMAGE_DIRECOTRY_ENTRY_TLS ││││ struct IMAGE_DATA_DIRECTORY_11; // 0xB0 IMAGE_DIRECOTRY_ENTRY_LOAD_CONFIG ││││ struct IMAGE_DATA_DIRECTORY_12; // 0xB8 IMAGE_DIRECOTRY_ENTRY_BOUND_IMPORT ││││ struct IMAGE_DATA_DIRECTORY_13 { // 0xC0 IMAGE_DIRECOTRY_ENTRY_IAT ││├──────────────────DWORD VirtualAddress; // Relative virtual address from ImageBase ││││ DWORD Size; ││││ }; ││││ struct IMAGE_DATA_DIRECTORY_14; // 0xC8 IMAGE_DIRECOTRY_ENTRY_DELAY_IMPORT ││││ struct IMAGE_DATA_DIRECTORY_15; // 0xD0 IMAGE_DIRECOTRY_ENTRY_COM_DESCRIPTOR ││││ struct IMAGE_DATA_DIRECTORY_16; // 0xD8 NULL ││││ }; ││││ }; ││││ ││││ ││││ ││││ ││││ // Multiple IMAGE_SECTION_HEADERs ││││ // - sizeof(IMAGE_SECTION_HEADER): 40 bytes ││││ ││││ struct IMAGE_SECTION_HEADER_1 { // .text section header ││││ BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // #typedef IMAGE_SIZEOF_SHORT_NAME 8 ││││ union { ││││ DWORD PhysicalAddress; ││││ DWORD VirtualSize; ││││ } Misc; │││├─────────DWORD VirtualAddress; ││││ DWORD SizeOfRawData; ││││ DWORD PointerToRawData; ││││ DWORD PointerToRelocations; ││││ DWORD PointerToLinenumbers; ││││ WORD NumberOfRelocations; ││││ WORD NumberOfLinenumbers; ││││ DWORD Characteristics; // Memory access permission ││││ }; ││││ struct IMAGE_SECTION_HEADER_2 { // .rdata section header ││││ BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ││││ union { ││││ DWORD PhysicalAddress; ││││ DWORD VirtualSize; ││││ } Misc; ││├──────────DWORD VirtualAddress; ││││ DWORD SizeOfRawData; ││││ DWORD PointerToRawData; ││││ DWORD PointerToRelocations; ││││ DWORD PointerToLinenumbers; ││││ WORD NumberOfRelocations; ││││ WORD NumberOfLinenumbers; ││││ DWORD Characteristics; // Memory access permission ││││ }; ││││ struct IMAGE_SECTION_HEADER_3; // .data section header ││││ struct IMAGE_SECTION_HEADER_4; ││││ ... ││││ ││││ ││││ ││││ ││││ // SECTION .text ││││ // - Holds program code ││││ │││└────→PROGRAM CODE... │││ │││ │││ │││ │││ // SECTION .rdata │││ // - Holds IAT, EAT, const variables, and strings │││ │││ // IMPORT Address Table (IAT) ││└─────→DWORD AddressOfData_1;─┐ // RVA from ImageBase (PIMAGE_IMPORT_BY_NAME) ││ DWORD AddressOfData_2; │ ││ DWORD AddressOfData_3; │ ││ ... │ ┌││────────────────────────────────┘ │││ │││ (중간 생략) │││ │││ // EXPORT directory structure │││ struct IMAGE_EXPORT_DIRECTORY { ││└──────────→DWORD Characteristics; ││ DWORD TimeDateStamp; ││ WORD MajorVersion; ││ WORD MinorVersion; ││ DWORD Name; ││ DWORD Base; ││ DWORD NumberOfFunctions; ││ DWORD NumberOfNames; ││┌───────────DWORD AddressOfFunctions; // Relative virtual address from ImageBase │││┌──────────DWORD AddressOfNames; // Relative virtual address from ImageBase ││││┌─────────DWORD AddressOfNameOrdinals; // Relative virtual address from ImageBase │││││ }; │││││ │││││ // EXPORT Address Table (EAT) (Sorted by ordinal number) ││└──────→PVOID pfnFunctionB; ││ ││ PVOID pfnFunctionC; ││ ││ PVOID pfnFunctionA; ││ ││ ... ││ ││ ││ ││ // EXPORT Name Pointer Table (Alphabetically Sorted) ││ └─────→char *szFunctionNameA;─┐ // Relative virtual address from ImageBase ││ │ char *szFunctionNameB; │ // Relative virtual address from ImageBase ││ │ char *szFunctionNameC; │ // Relative virtual address from ImageBase ││ │ ... │ ││ ┌│────────────────────────────┘ ││ ││ //EXPORT Ordinal Table (Alphabetically Sorted) ││ │└────→SHORT nFunctionOrdinalA; ││ │ SHORT nFunctionOrdinalB; ││ │ SHORT nFunctionOrdinalC; ││ │ ... ││ │ ││ │ // EXPORT Function name strings (Alphabetically Sorted) ││ └─────→"ExportFunctionA\0" // NULL-terminated string ││ "ExportFunctionB\0" // NULL-terminated string ││ "ExportFunctionC\0" // NULL-terminated string ││ ... ││ ││ // IMPORT Directory Table ││ struct IMAGE_IMPORT_DESCRIPTOR_1 { // One structure to one imported DLL module │└───────────→union { │ DWORD Characteristics; │ ┌─────────────DWORD OriginalFirstThunk; // RVA from ImageBase (PIMAGE_THUNK_DATA32) │ │ } DUMMYUNIONNAME; │ │ DWORD TimeDateStamp; │ │ DWORD ForwarderChain; │ │ DWORD Name; │ │ DWORD FirstThunk; │ │ }; │ │ struct IMAGE_IMPORT_DESCRIPTOR_2; │ │ struct IMAGE_IMPORT_DESCRIPTOR_3; │ │ ... │ │ │ │ // IMPORT Name Table │ │ struct IMAGE_THUNK_DATA32_1 { │ └────────→union { │ DWORD ForwarderString; │ DWORD Function; │ DWORD Ordinal; ├─────────────────DWORD AddressOfData; // RVA from ImageBase (PIMAGE_IMPORT_BY_NAME) │ } u1; │ }; │ struct IMAGE_THUNK_DATA32_2; │ struct IMAGE_THUNK_DATA32_3; │ ... │ │ // IMPORT Hints/Name & DLL Names (IMAGE_IMPORT_BY_NAME structures) └────────→WORD Hint_1; "ImportFunctionA\0" WORD Hint_2; "ImportFunctionB\0" WORD Hint_3; "ImportFunctionC\0" ... // SECTION .data // - Holds global variables excepting const and static local variables (이하 생략)
References
- Microsoft's Rich Signature (undocumented)
- Print compiler information stored in Rich Header of PE executables.
- Microsofts Rich Header
- PEVIEW – 실행 파일 구조, PE HEADER 분석