Understanding PE Headers: A Complete Guide to the Windows Portable Executable Format
2025-1-4 20:0:0 Author: www.hackingdream.net(查看原文) 阅读量:4 收藏

Introduction

The Portable Executable (PE) format is an essential structure for Windows binaries such as executables (EXE) and dynamic link libraries (DLLs). It consists of a set of PE headers, each playing a crucial role in how the file loads, executes, and interacts with the operating system. This guide explores the key PE headers, their specific purposes, internal structures, and sizes, offering a comprehensive understanding for developers, reverse engineers, and cybersecurity professionals. By mastering the PE file format, you can gain deeper insights into PE file analysis and enhance your understanding of system programming.



What is the Portable Executable (PE) Format?

The Portable Executable (PE) format is a structure used by Windows binaries to ensure efficient execution on the system. From PE headers to section headers, each component is designed for a specific purpose, whether it’s managing metadata, memory mapping, or optimizing runtime behavior. Understanding the PE format structure helps in analyzing how Windows executables and DLLs operate within the system.


PE File Structure Overview

A PE file comprises several headers and sections:

  1. DOS Header
  2. PE Signature
  3. File Header
  4. Optional Header
  5. Data Directories
  6. Section Headers
  7. Sections

Headers and Sections in Detail

1. DOS Header

  • Purpose: A legacy header from MS-DOS that contains the "MZ" magic number and a pointer to the PE header.
  • Structure Name: IMAGE_DOS_HEADER
  • Size: 64 bytes

Key Fields:

  • e_magic: Identifies the file as an executable with the "MZ" signature.
  • e_lfanew: Points to the NT headers.
typedef struct _IMAGE_DOS_HEADER {
    WORD  e_magic;      /* 00: MZ Header signature */
    WORD  e_cblp;       /* 02: Bytes on last page of file */
    WORD  e_cp;         /* 04: Pages in file */
    WORD  e_crlc;       /* 06: Relocations */
    WORD  e_cparhdr;    /* 08: Size of header in paragraphs */
    WORD  e_minalloc;   /* 0a: Minimum extra paragraphs needed */
    WORD  e_maxalloc;   /* 0c: Maximum extra paragraphs needed */
    WORD  e_ss;         /* 0e: Initial (relative) SS value */
    WORD  e_sp;         /* 10: Initial SP value */
    WORD  e_csum;       /* 12: Checksum */
    WORD  e_ip;         /* 14: Initial IP value */
    WORD  e_cs;         /* 16: Initial (relative) CS value */
    WORD  e_lfarlc;     /* 18: File address of relocation table */
    WORD  e_ovno;       /* 1a: Overlay number */
    WORD  e_res[4];     /* 1c: Reserved words */
    WORD  e_oemid;      /* 24: OEM identifier (for e_oeminfo) */
    WORD  e_oeminfo;    /* 26: OEM information; e_oemid specific */
    WORD  e_res2[10];   /* 28: Reserved words */
    DWORD e_lfanew;     /* 3c: Offset to extended header */
}

1.1 DOS Stub

  • Purpose: Displays a message such as "This program cannot be run in DOS mode" when executed in a DOS environment.
  • Size: Variable, typically ~128 bytes.

2. PE Signature

  • Purpose: Marks the file as a Portable Executable file.
  • Structure Name: Not a structure but a constant value ("PE\0\0").
  • Size: 4 bytes

3. File Header (PE Header)

  • Purpose: Contains metadata about the file, such as the target machine and number of sections.
  • Structure Name: IMAGE_FILE_HEADER
  • Size: 20 bytes

Key Fields:

  • Machine: Specifies the target architecture (e.g., x86 or x64).
  • NumberOfSections: Indicates the number of sections in the file.
  • Characteristics: Describes file attributes, like whether it’s an executable or DLL.
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;

4. Optional Header

  • Purpose: Despite its name, this header is mandatory. It provides details about the entry point, memory layout, and subsystem requirements of the file.
  • Structure Name: IMAGE_OPTIONAL_HEADER (32-bit or 64-bit variants).
  • Size:
    • 32-bit: 96 bytes
    • 64-bit: 112 bytes

Key Fields:

  • AddressOfEntryPoint: Specifies the entry point of the executable.
  • ImageBase: Preferred memory address for loading the file.
  • Subsystem: Indicates whether the file requires a console or GUI environment.
typedef struct _IMAGE_OPTIONAL_HEADER64 {
  WORD  Magic; /* 0x20b */
  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];
}

5. Data Directories

  • Purpose: Part of the Optional Header, these pointers direct the loader to key structures, such as imports, exports, and resources.
  • Structure Name: IMAGE_DATA_DIRECTORY
  • Size: 8 bytes per entry (16 entries = 128 bytes)

Key Fields:

  • VirtualAddress: Points to the table/structure in memory.
  • Size: Specifies the size of the table/structure.
typedef struct _IMAGE_DATA_DIRECTORY {
  DWORD VirtualAddress;
  DWORD Size;
} IMAGE_DATA_DIRECTORY;

6. Section Headers (Section Table)

  • Purpose: Describe individual sections like .text (code), .data (initialized data), and .rdata (read-only data).
  • Structure Name: IMAGE_SECTION_HEADER
  • Size: 40 bytes per section

Key Fields:

  • Name: Name of the section (e.g., .text, .data).
  • VirtualSize: Size of the section in memory.
  • SizeOfRawData: Size of the section on disk.
typedef struct _IMAGE_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;
}


7. Sections

Sections store the actual content of the executable (code, data, imports, exports, etc.). The specific sections and their contents include:

Section Purpose Contents Characteristics
.text Code section Executable instructions (machine code). Execute
.rdata Read-only data Import Table, Export Table, strings, constants. Read
.data Initialized data Global/static variables with initial values. Read
.bss Uninitialized data Global/static variables without initial values. Read
.idata Import-related data Import Address Table (IAT), descriptors. Read
.edata Export-related data Export Directory Table, exported symbols. Read
.reloc Relocation information Base Relocation Table. Read
.rsrc Resources Icons, dialogs, menus, etc. Read

7.1. .text (Code Section)

  • Purpose: Contains the executable instructions (machine code) of the program.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Compiled machine instructions.
    • Entry point code for the program.
  • Characteristics:
    • IMAGE_SCN_CNT_CODE: Indicates this is a code section.
    • IMAGE_SCN_MEM_EXECUTE: The section is executable.
    • IMAGE_SCN_MEM_READ: The section is readable.
  • Key Fields in Section Header:
    • Name: Typically ".text".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.2. .rdata (Read-Only Data Section)

  • Purpose: Contains read-only data, such as constants, strings, and sometimes import/export-related data.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Strings and constants.
    • Import Table (Import Address Table, Import Lookup Table).
    • Export Table (if not in .edata).
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: Read-only data.
  • Key Fields in Section Header:
    • Name: Typically ".rdata".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.3. .data (Initialized Data Section)

  • Purpose: Stores global and static variables with initial values.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Initialized global/static variables.
    • Writable data used by the program.
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: The section is readable.
    • IMAGE_SCN_MEM_WRITE: The section is writable.
  • Key Fields in Section Header:
    • Name: Typically ".data".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.4. .bss (Uninitialized Data Section)

  • Purpose: Stores uninitialized global and static variables.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Uninitialized global/static variables.
    • Memory is zero-initialized at runtime.
  • Size:
    • File size: Typically 0 (uninitialized data is not stored in the file).
    • Virtual size: Rounded to SectionAlignment.
  • Characteristics:
    • IMAGE_SCN_CNT_UNINITIALIZED_DATA: Contains uninitialized data.
    • IMAGE_SCN_MEM_READ: The section is readable.
    • IMAGE_SCN_MEM_WRITE: The section is writable.
  • Key Fields in Section Header:
    • Name: Typically ".bss".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Usually 0 (since no raw data is stored in the file).
    • Characteristics: Attributes for the section.

7.5. .idata (Import Section)

  • Purpose: Contains information about imported functions and libraries.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Import Address Table (IAT).
    • Import Lookup Table (ILT).
    • IMAGE_IMPORT_DESCRIPTOR structures.
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: Readable.
  • Key Fields in Section Header:
    • Name: Typically ".idata".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.6. .edata (Export Section)

  • Purpose: Contains information about exported functions and symbols.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • IMAGE_EXPORT_DIRECTORY structure.
    • Addresses of exported symbols.
    • Symbol names and ordinals.
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: Readable.
  • Key Fields in Section Header:
    • Name: Typically ".edata".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.7. .reloc (Relocation Section)

  • Purpose: Contains relocation information for fixing addresses when the PE file is loaded at a non-preferred base address.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • IMAGE_BASE_RELOCATION structures.
    • Relocation entries for specific addresses.
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: Readable.
  • Key Fields in Section Header:
    • Name: Typically ".reloc".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.

7.8. .rsrc (Resource Section)

  • Purpose: Stores application resources, such as icons, menus, dialogs, and strings.
  • Structure Name: IMAGE_SECTION_HEADER
  • Contents:
    • Resource data in a hierarchical format.
  • Characteristics:
    • IMAGE_SCN_CNT_INITIALIZED_DATA: Contains initialized data.
    • IMAGE_SCN_MEM_READ: Readable.
  • Key Fields in Section Header:
    • Name: Typically ".rsrc".
    • VirtualSize: Size of the section in memory.
    • PointerToRawData: Offset of the section's raw data in the file.
    • Characteristics: Attributes for the section.


Summary Table

Header/Section Structure Name Size (Bytes) Purpose
DOS Header `IMAGE_DOS_HEADER` 64 Legacy; points to PE header.
PE Signature Constant (`"PE\0\0"`) 4 Identifies the file as PE.
File Header `IMAGE_FILE_HEADER` 20 File metadata.
Optional Header `IMAGE_OPTIONAL_HEADER32`/
`IMAGE_OPTIONAL_HEADER64`
96 / 112 Detailed executable info.
Section Headers `IMAGE_SECTION_HEADER` 40 per section Describes file sections.
Data Directories `IMAGE_DATA_DIRECTORY` 128 Points to tables like import/export.
Import Descriptor `IMAGE_IMPORT_DESCRIPTOR` 20 per entry Details about imported DLLs/functions.
Export Directory `IMAGE_EXPORT_DIRECTORY` 40 Details about exported symbols.
Base Relocation Table `IMAGE_BASE_RELOCATION` Varies Relocation info for memory mapping.
Resource Directory `IMAGE_RESOURCE_DIRECTORY` Varies Resource data (icons, strings, etc.).
Debug Directory `IMAGE_DEBUG_DIRECTORY` 28 per entry Debugging info pointers.


Summary

The Portable Executable (PE) format is the backbone of Windows executable files, facilitating efficient interaction between applications and the Windows operating system. Understanding its components—such as PE headers, section headers, and data directories—is essential for anyone involved in PE file analysis. From the DOS Header to the Section, each section defines the structure and behavior of the file during runtime.

Whether you're a developer optimizing your code, a reverse engineer dissecting Windows binaries, or a cybersecurity professional investigating potential threats, mastering the PE format is key to navigating and manipulating Windows executables effectively. This guide provides a foundational understanding to help you advance your skills in binary analysis, PE file analysis, and system programming.



文章来源: https://www.hackingdream.net/2025/01/understanding-pe-headers-complete-guide.html
如有侵权请联系:admin#unsafe.sh