PE (Portable Executable) 格式是 Windows 可執行檔的標準。本文提供 PE 核心結構體的完整 C/C++ 定義,涵蓋 IMAGE_NT_HEADERS、IMAGE_FILE_HEADER、IMAGE_OPTIONAL_HEADER32、IMAGE_DATA_DIRECTORY、IMAGE_SECTION_HEADER,並標註每個欄位的含義、典型值與實戰用途,作為逆向分析、殼開發、二進位修補的速查手冊。
DOS Header (IMAGE_DOS_HEADER)
e_lfanew ──────► NT Headers (IMAGE_NT_HEADERS)
├─ Signature ("PE\0\0")
├─ File Header (IMAGE_FILE_HEADER)
├─ Optional Header (IMAGE_OPTIONAL_HEADER32)
│ └─ Data Directory[16] (IMAGE_DATA_DIRECTORY)
└─ (隱含) Section Table (IMAGE_SECTION_HEADER[])
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; // 0x00004550 "PE\0\0"
IMAGE_FILE_HEADER FileHeader; // 實體檔案屬性
IMAGE_OPTIONAL_HEADER32 OptionalHeader; // 邏輯映像屬性
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; // 0x014c (I386), 0x8664 (AMD64), 0x01c0 (ARM), 0xaa64 (ARM64)
WORD NumberOfSections; // 區段數量
DWORD TimeDateStamp; // Unix timestamp 建立時間
DWORD PointerToSymbolTable; // COFF 符號表偏移 (除錯用)
DWORD NumberOfSymbols; // 符號數
WORD SizeOfOptionalHeader; // OptionalHeader 大小 (PE32=0xE0, PE32+=0xF0)
WORD Characteristics; // 屬性旗標
// 0x0001 RELOCS_STRIPPED 無重定位資訊
// 0x0002 EXECUTABLE_IMAGE 可執行映像 (EXE)
// 0x0004 LINE_NUMS_STRIPPED 無行號
// 0x0008 LOCAL_SYMS_STRIPPED 無本地符號
// 0x0010 AGGRESIVE_WS_TRIM 激進工作集修剪
// 0x0020 LARGE_ADDRESS_AWARE 支援 >2GB 位址空間
// 0x0080 BYTES_REVERSED_LO 位元組反轉 (LO)
// 0x0100 32BIT_MACHINE 32位機器
// 0x0200 DEBUG_STRIPPED 無除錯資訊
// 0x0400 REMOVABLE_RUN_FROM_SWAP 可移動媒體從交換檔執行
// 0x0800 NET_RUN_FROM_SWAP 網路從交換檔執行
// 0x1000 SYSTEM 系統檔案
// 0x2000 DLL 動態連結庫
// 0x4000 UP_SYSTEM_ONLY 單處理器系統
// 0x8000 BYTES_REVERSED_HI 位元組反轉 (HI)
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
// 標準欄位
WORD Magic; // 0x10b (PE32), 0x20b (PE32+), 0x107 (ROM)
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode; // 所有代碼區段總大小 (對齊 FileAlignment)
DWORD SizeOfInitializedData; // 初始化資料總大小
DWORD SizeOfUninitializedData; // 未初始化資料總大小 (.bss)
DWORD AddressOfEntryPoint; // 程式進入點 RVA (關鍵!)
DWORD BaseOfCode; // 代碼區段起始 RVA
DWORD BaseOfData; // 資料區段起始 RVA (PE32+ 無此欄位)
// NT 額外欄位
DWORD ImageBase; // 建議載入基址 (EXE: 0x00400000, DLL: 0x10000000)
DWORD SectionAlignment; // 記憶體區段對齊 (通常 0x1000 = 4KB)
DWORD FileAlignment; // 檔案區段對齊 (通常 0x200 = 512B)
WORD MajorOperatingSystemVersion; // 通常 4.00 (Win95/NT4+)
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion; // 使用者定義版本
WORD MinorImageVersion;
WORD MajorSubsystemVersion; // 子系統版本 (4.0 以上才有 3D UI)
WORD MinorSubsystemVersion;
DWORD Win32VersionValue; // 保留,必須 0
DWORD SizeOfImage; // 映像在記憶體總大小 (含 Header、區段、對齊)
DWORD SizeOfHeaders; // DOS Header + PE Header + Section Table 大小 (對齊 FileAlignment)
DWORD CheckSum; // 校驗和 (驅動程式/系統檔必填)
WORD Subsystem; // 子系統類型
// 1 NATIVE 驅動程式/原生
// 2 WINDOWS_GUI 圖形介面 (無控制台)
// 3 WINDOWS_CUI 控制台介面
// 5 OS2_CUI OS/2 字元介面
// 7 POSIX_CUI POSIX 字元介面
// 9 WINDOWS_CE_GUI Windows CE GUI
// 10 EFI_APPLICATION UEFI 應用
// 11 EFI_BOOT_SERVICE_DRIVER
// 12 EFI_RUNTIME_DRIVER
// 13 EFI_ROM
// 14 XBOX
// 16 WINDOWS_BOOT_APPLICATION
WORD DllCharacteristics; // DLL 特性旗標
// 0x0020 HIGH_ENTROPY_VA 高熵 ASLR
// 0x0040 DYNAMIC_BASE ASLR 啟用
// 0x0080 FORCE_INTEGRITY 強制簽名驗證
// 0x0100 NX_COMPAT DEP 相容
// 0x0200 NO_ISOLATION 無隔離
// 0x0400 NO_SEH 無 SEH
// 0x0800 NO_BIND 不綁定
// 0x1000 APPCONTAINER AppContainer
// 0x2000 WDM_DRIVER WDM 驅動
// 0x4000 GUARD_CF Control Flow Guard
// 0x8000 TERMINAL_SERVER_AWARE 終端機伺服器感知
DWORD SizeOfStackReserve; // 堆疊保留大小
DWORD SizeOfStackCommit; // 堆疊初始提交大小
DWORD SizeOfHeapReserve; // 堆積保留大小
DWORD SizeOfHeapCommit; // 堆積初始提交大小
DWORD LoaderFlags; // 保留
DWORD NumberOfRvaAndSizes; // 固定 16 (IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
IMAGE_DATA_DIRECTORY DataDirectory[16]; // 關鍵目錄表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; // 目錄資料 RVA (相對 ImageBase)
DWORD Size; // 目錄資料大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
索引對照見前文《PE 資源區結構深度研究》Data Directory 表。
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[8]; // 區段名 (無結尾 null,如 ".text\0\0\0")
DWORD VirtualSize; // 區段在記憶體實際大小
DWORD VirtualAddress; // 區段 RVA (相對 ImageBase)
DWORD SizeOfRawData; // 區段在檔案大小 (對齊 FileAlignment)
DWORD PointerToRawData; // 區段在檔案偏移 (對齊 FileAlignment)
DWORD PointerToRelocations; // COFF 重定位表偏移 (通常 0)
DWORD PointerToLinenumbers; // COFF 行號表偏移 (通常 0)
WORD NumberOfRelocations; // 重定位項數
WORD NumberOfLinenumbers; // 行號項數
DWORD Characteristics; // 區段屬性旗標
// 0x00000020 CNT_CODE 包含代碼
// 0x00000040 CNT_INITIALIZED_DATA 包含初始化資料
// 0x00000080 CNT_UNINITIALIZED_DATA 包含未初始化資料
// 0x02000000 MEM_DISCARDABLE 可捨棄
// 0x04000000 MEM_NOT_CACHED 不快取
// 0x08000000 MEM_NOT_PAGED 不分頁
// 0x10000000 MEM_SHARED 共享
// 0x20000000 MEM_EXECUTE 可執行
// 0x40000000 MEM_READ 可讀
// 0x80000000 MEM_WRITE 可寫
// 常見組合:
// .text 0x60000020 (CODE | EXECUTE | READ)
// .data 0xC0000040 (INIT_DATA | READ | WRITE)
// .rdata 0x40000040 (INIT_DATA | READ)
// .bss 0xC0000080 (UNINIT_DATA | READ | WRITE)
// .rsrc 0x40000040 (INIT_DATA | READ)
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
| 計算項目 | 公式 | 說明 |
|---|---|---|
| NT Headers 位置 | DOS Header + DOS Header.e_lfanew | 通常 0x80, 0x100, 0x200 |
| Optional Header 位置 | NT Headers + 4 (Signature) + 20 (FileHeader) | |
| Section Table 位置 | Optional Header 位置 + FileHeader.SizeOfOptionalHeader | |
| 第 i 區段 Header | Section Table + i * 40 | |
| 區段在記憶體位置 | ImageBase + Section.VirtualAddress | RVA → VA |
| 區段在檔案位置 | Section.PointerToRawData | FOA |
| SizeOfImage | 對齊 (最後區段 VA + VirtualSize, SectionAlignment) | 載入器分配記憶體大小 |
| Entry Point VA | ImageBase + OptionalHeader.AddressOfEntryPoint | 執行起始位址 |
| 項目 | PE32 (32位) | PE32+ (64位) |
|---|---|---|
| Magic | 0x10b | 0x20b |
| Optional Header 大小 | 0xE0 (224) | 0xF0 (240) |
| BaseOfData | 存在 | 無 (合併至 SectionAlignment 計算) |
| ImageBase | 32位 (通常 0x00400000) | 64位 (通常 0x0000000140000000) |
| SizeOfStack/Heap Reserve/Commit | 32位 | 64位 |
| DataDirectory 數量 | 16 | 16 |
OptionalHeader.AddressOfEntryPoint = 新代碼 RVAOptionalHeader.Subsystem = 2/3OptionalHeader.DllCharacteristics |= 0x0040 (DYNAMIC_BASE)OptionalHeader.DllCharacteristics |= 0x0100 (NX_COMPAT)OptionalHeader.SizeOfStackReserve/CommitIMAGE_SECTION_HEADER,更新 FileHeader.NumberOfSections、OptionalHeader.SizeOfImage熟記這些結構體定義與欄位含義,是進行 PE 靜態分析、動態調試、殼開發、漏洞利用與防禦的基石語言。