// 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