首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

PE 文件格式核心結構完整定義:NT Header、Optional Header、Data Directory、Section Header

     編輯:VC 教學

前言

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[])

完整結構體定義

1. NT Headers


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;

2. File Header (IMAGE_FILE_HEADER) - 20 bytes


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;

3. Optional Header (IMAGE_OPTIONAL_HEADER32) - 224 bytes (PE32)


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;

4. Data Directory (IMAGE_DATA_DIRECTORY) - 8 bytes × 16


typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress; // 目錄資料 RVA (相對 ImageBase)
    DWORD Size;           // 目錄資料大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

索引對照見前文《PE 資源區結構深度研究》Data Directory 表。

5. Section Header (IMAGE_SECTION_HEADER) - 40 bytes


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 區段 HeaderSection Table + i * 40
區段在記憶體位置ImageBase + Section.VirtualAddressRVA → VA
區段在檔案位置Section.PointerToRawDataFOA
SizeOfImage對齊 (最後區段 VA + VirtualSize, SectionAlignment)載入器分配記憶體大小
Entry Point VAImageBase + OptionalHeader.AddressOfEntryPoint執行起始位址

PE32 vs PE32+ (PE64) 差異

項目PE32 (32位)PE32+ (64位)
Magic0x10b0x20b
Optional Header 大小0xE0 (224)0xF0 (240)
BaseOfData存在無 (合併至 SectionAlignment 計算)
ImageBase32位 (通常 0x00400000)64位 (通常 0x0000000140000000)
SizeOfStack/Heap Reserve/Commit32位64位
DataDirectory 數量1616

實戰速查:常見修改欄位

  • 修改進入點:OptionalHeader.AddressOfEntryPoint = 新代碼 RVA
  • 切換 GUI/CUI:OptionalHeader.Subsystem = 2/3
  • 啟用 ASLR:OptionalHeader.DllCharacteristics |= 0x0040 (DYNAMIC_BASE)
  • 啟用 DEP:OptionalHeader.DllCharacteristics |= 0x0100 (NX_COMPAT)
  • 修改堆疊大小:OptionalHeader.SizeOfStackReserve/Commit
  • 新增區段:在 Section Table 末尾新增 IMAGE_SECTION_HEADER,更新 FileHeader.NumberOfSections、OptionalHeader.SizeOfImage

熟記這些結構體定義與欄位含義,是進行 PE 靜態分析、動態調試、殼開發、漏洞利用與防禦的基石語言。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved