PE文件结构解析

个人博客:coonaa.cn本文博客同步地址


一. 基本概念

1.1 可执行文件

文件格式
文件格式规定了文件在电脑中的存储格式。
不同的存储格式,按照不同的数据结构,保存不同类型的文件,文件格式与操作系统有关。

可执行文件
可以由操作系统进行加载并执行的文件称为可执行文件。
在不同的操作系统环境下可执行文件的呈现方式不一样:

windows:采用 PE(Portable Executable)文件结构。
Linux:采用 ELF(Executable and Linking Format)文件结构。


1.2 PE 文件简介

PE(Portable Executable)文件,即可移植的可执行文件,是 Windows 操作系统上主流的可执行文件。
常见的 EXE、DLL、OCX、SYS、COM 等文件格式都属于 PE 文件。


1.3 地址的基本概念

VA(Virtual Address):虚拟地址
PE 文件映射到内存空间时,数据在内存空间中对应的地址。

ImageBase:映射基址
PE 文件在内存空间中的映射起始位置,是个 VA 地址。

RVA(Relative Virtual Address):相对虚拟地址
PE 文件在内存中的 VA 相对于 ImageBase 的偏移量。

FA(File Offset Address,FOA):文件偏移地址
PE 文件在磁盘上存放时,数据相对于文件开头位置的偏移量,文件偏移地址等于文件地址。

转换关系:VA = ImageBase + RVA


1.4 PE 文件结构概述

PE 文件的结构图如下:
PE 文件结构图
总结而言,PE 文件主要包括两大部分:“头部”“区块”

头部:包含 DOS 首部、PE 文件头和块表。
区块:包含具体的块数据,用于存储程序代码、数据、资源等信息,同时也可能包含一些调试信息,例如 COFF 符号表等。

下图能更直观地体现 PE 文件的结构信息:
PE 文件结构

二. 文件结构

PE 文件的各个 Header 是 PE 文件中最为重要的部分,一旦掌握了这些 Header,基本上便能掌握整个 PE 文件的结构。
因此下文将详细分析 PE 文件的各个 Header,对于具体的块数据部分,将不再赘述。


除了 DOS_Stub 以外,其它所有的 Header 都能在微软的 winnt.h 头文件中找到相应的结构体定义。

撰写本文时,参考依据为时下微软官网最新的 Windows 10 SDK (10.0.19041.0),如图:
Windows 10 SDK (10.0.19041.0)

微软 winnt.h 头文件官方文档:点击这里查看
微软 winnt.h 头文件在 SDK 中的位置(以上面提到的 SDK 版本为例):
winnt.h 文件位置

2.1 DOS_HEADER

_IMAGE_DOS_HEADER 结构体定义:

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

PE 文件使用 _IMAGE_DOS_HEADER 结构提供程序在 DOS 系统中的执行环境。

部分结构成员:
(1)e_magic: DOS 映像文件格式标记,与 MS-DOS 兼容的 PE 文件都将该值设为 0x4D5A,对应的 ASCII 字符为:MZ。
(2)e_ss: DOS 代码的初始化堆栈。
(3)e_sp: DOS 代码的初始化堆栈指针。
(4)e_ip: DOS 代码的初始化指令入口。
(5)e_cs: DOS 代码的初始化代码段入口。
(6)e_lfanew:PE 文件头 _IMAGE_NT_HEADERS 结构的 FA 偏移地址,即指向 _IMAGE_NT_HEADERS 结构。


2.2 DOS_STUB

_IMAGE_DOS_STUB 结构:
该结构未在 winnt.h 中定义,其内容随着链接时使用的链接器不同而不同,通常用于保存在 DOS 环境中的可执行代码。
例如:该结构中的代码用于显示字符串:“This program cannot run in DOS mode”。


2.3 NT_HEADER

_IMAGE_NT_HEADERS 结构体定义:

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

#ifdef _WIN64
typedef IMAGE_NT_HEADERS64                  IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS64                 PIMAGE_NT_HEADERS;
#else
typedef IMAGE_NT_HEADERS32                  IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32                 PIMAGE_NT_HEADERS;
#endif

PE 文件使用 _IMAGE_NT_HEADER 结构提供程序在 Windows 系统中的执行环境。
可以看到 _IMAGE_NT_HEADER 结构针对 32 位和 64 位有不同的定义。

注:该部分通常也称为 PE Header。

部分结构成员:
(1)Signature:PE 映像文件格式标记。在 winnt.h 中定义的 Signature 如下:

#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
#define IMAGE_OS2_SIGNATURE                 0x454E      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x454C      // LE
#define IMAGE_VXD_SIGNATURE                 0x454C      // LE
#define IMAGE_NT_SIGNATURE                  0x00004550  // PE00

(2)FileHeader:指定 PE 文件头 _IMAGE_FILE_HEADER 结构。
(3)OptionalHeader:指定 PE 可选文件头 _IMAGE_OPTIONAL_HEADER 结构。


2.4 File_HEADER

_IMAGE_FILE_HEADER 结构体定义:

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;

PE 文件使用 _IMAGE_FILE_HEADER 结构提供 PE 文件的物理分布信息。

部分结构成员:
(1)Machine:平台类型,映像文件只能在指定的平台或模拟指定平台的系统上运行。在 winnt.h 中定义的 Machine 如下:

#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_TARGET_HOST       0x0001  // Useful for indicating we want to interact with the host and not a WoW guest.
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2  // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_ARM64             0xAA64  // ARM64 Little-Endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE

(2)NumberOfSections:Section 的数目,即 Section Table 数组的元素个数。Windows Loader 限制 Section 的数目为 96 。
(3)TimeDateStamp:文件创建的日期和时间。
(4)PointerToSymbolTable:COFF 符号表的 RVA 偏移量,如果 COFF 符号表不存在,则该值为 0 。
(5)NumberOfSymbols:COFF 符号表中的符号个数。
(6)SizeOfOptionalHeader:_IMAGE_OPTIONAL_HEADER 结构的大小,对于 obj 文件,该值为 0 。
(7)Characteristics:PE 文件的属性。在 winnt.h 中定义的 Characteristics 如下:

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved external references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Aggressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

2.5 Option_HEADER

_IMAGE_OPTIONAL_HEADER 结构体定义:

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   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;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_OPTIONAL_HEADER64 {
    WORD        Magic;
    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];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

#ifdef _WIN64
typedef IMAGE_OPTIONAL_HEADER64             IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER64            PIMAGE_OPTIONAL_HEADER;
#else
typedef IMAGE_OPTIONAL_HEADER32             IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER32            PIMAGE_OPTIONAL_HEADER;
#endif

PE 文件使用 _IMAGE_OPTIONAL_HEADER 结构提供 PE 文件的逻辑分布信息。
可以看到 _IMAGE_OPTIONAL_HEADER 针对 32 位和 64 位有不同的结构定义,针对 32 位时,分为标准域和 NT 附加域。

部分结构成员:
(1)Magic:PE 文件类型。在 winnt.h 中定义的 Magic 如下:

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107

(2)MajorLinkerVersion:链接器的主要版本号。
(3)MinorLinkerVersion:链接器的次要版本号。
(4)SizeOfCode:代码段(磁盘对齐)的大小,如果有多个代码段,则为所有这些段的总和。
(5)SizeOfInitializedData:已初始化数据段(不包括代码段)的大小,如果有多个已初始化数据段,则为所有此类段的总和。
(6)SizeOfUninitializedData:未初始化数据段(需要装载但却不占用硬盘空间的区段,通常为 .bss 等)的大小,如果有多个未初始化数据段,则为所有此类段的总和。
(7)AddressOfEntryPoint:PE 文件执行的入口 RVA 地址,设备驱动程序初始化函数的入口地址,对于没有入口函数的 DLL 该值为 0 。
(8)BaseOfCode:代码段(.text)的映射起始 RVA 地址。
(9)BaseOfData:数据段(.data)的映射起始 RVA 地址。
(10)ImageBase:映射基础 VA 地址,值为 64K 字节的整数倍,DLL 默认优先装载 0x10000000,应用程序默认优先装载 0x00400000。
(11)SectionAlignment:内存对齐粒度,即 PE 文件映射到内存时的对齐粒度;默认值为系统页面大小 0x1000(4KB);该值必须大于或等于 FileAligment 的值。
(12)FileAlignment:磁盘对齐粒度,即 PE 文件在磁盘中存储时的对齐粒度;默认值为磁盘页面大小 0x200(512B);如果 SectionAlignment 的值小于系统页面大小,则该值必须与 SectionAlignment 的值相同。
(13)MajorOperatingSystemVersion:操作系统的主要版本号。
(14)MinorOperatingSystemVersion:操作系统的次要版本号。
(15)MajorImageVersion:映像文件的主要版本号。
(16)MinorImageVersion:映像文件的次要版本号。
(17)MajorSubsystemVersion:子系统的主要版本号。
(18)MinorSubsystemVersion:子系统的次要版本号。
(19)Win32VersionValue:该成员为保留成员,必须为 0 。
(20)SizeOfImage:装载整个 PE 文件占用的空间大小(对齐),该值必须是 SectionAlignment 的整数倍。
(21)SizeOfHeaders:装载 PE 文件全部 Header 占用的空间大小(非对齐,实际大小)。
(22)CheckSum:PE 文件的 CRC 校验值。
(23)Subsystem:PE 文件的子系统类型。在 winnt.h 中定义的 Subsystem 如下:

#define IMAGE_SUBSYSTEM_UNKNOWN                  0   // Unknown subsystem.
#define IMAGE_SUBSYSTEM_NATIVE                   1   // Image doesn't require a subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_GUI              2   // Image runs in the Windows GUI subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_CUI              3   // Image runs in the Windows character subsystem.
#define IMAGE_SUBSYSTEM_OS2_CUI                  5   // image runs in the OS/2 character subsystem.
#define IMAGE_SUBSYSTEM_POSIX_CUI                7   // image runs in the Posix character subsystem.
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS           8   // image is a native Win9x driver.
#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI           9   // Image runs in the Windows CE subsystem.
#define IMAGE_SUBSYSTEM_EFI_APPLICATION          10  //
#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER  11  //
#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER       12  //
#define IMAGE_SUBSYSTEM_EFI_ROM                  13
#define IMAGE_SUBSYSTEM_XBOX                     14
#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16
#define IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG        17

(24)DllCharacteristics:DLL 特征。在 winnt.h 中定义的 DllCharacteristics 如下:

#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA    0x0020  // Image can handle a high entropy 64-bit virtual address space.
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040        // DLL can move.
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY    0x0080  // Code Integrity Image
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT    0x0100        // Image is NX compatible
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200        // Image understands isolation and doesn't want it
#define IMAGE_DLLCHARACTERISTICS_NO_SEH       0x0400        // Image does not use SEH.  No SE handler may reside in this image
#define IMAGE_DLLCHARACTERISTICS_NO_BIND      0x0800        // Do not bind this image.
#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER 0x1000        // Image should execute in an AppContainer
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER   0x2000        // Driver uses WDM model
#define IMAGE_DLLCHARACTERISTICS_GUARD_CF     0x4000        // Image supports Control Flow Guard.
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE      0x8000

(25)DataDirectory[]:指向 _IMAGE_DATA_DIRECTORY 结构数组(数据目录表)中第一个 _IMAGE_DATA_DIRECTORY 结构的指针。


2.6 DATA_DIRECTORY

_IMAGE_DATA_DIRECTORY 结构体定义:

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

PE 文件使用 _IMAGE_DATA_DIRECTORY 结构提供 PE 文件中数据结构(输入表、输出表等)的地址和大小信息。

部分结构成员:
(1)VirtualAddress:数据结构(表)的起始 RVA 偏移地址。
(2)Size:数据结构(表)的大小。


2.7 SECTION_HEADER

_IMAGE_SECTION_HEADER 结构体定义:

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;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

PE 文件使用 _IMAGE_SECTION_DIRECTORY 结构提供各个 Section 的位置、大小、属性等信息。

部分结构成员:
(1)Name[]:该 Section 的名称。
(2)PhysicalAddress:该 Section 的物理地址。
(3)VirtualSize:该 Section 加载到内存中时的真实大小。
(4)VirtualAddress:该 Section 加载到内存中时的 RVA 偏移地址。
(5)SizeOfRawData:,该 Section 在磁盘上占用的空间大小(对齐),该值必须是 FileAlignment 值的整数倍。
(6)PointerToRawData:该 Section 的 FA 偏移地址,该值必须是 FileAlignment 值的整数倍。
(7)PointerToRelocations:指向该 Section 重定位开头的文件指针。
(8)Characteristics:该 Section 的属性,包括可执行、可读、可写、初始化数据、未初始化数据等。在 winnt.h 中定义的 Characteristics 如下:

//      IMAGE_SCN_TYPE_REG                   0x00000000  // Reserved.
//      IMAGE_SCN_TYPE_DSECT                 0x00000001  // Reserved.
//      IMAGE_SCN_TYPE_NOLOAD                0x00000002  // Reserved.
//      IMAGE_SCN_TYPE_GROUP                 0x00000004  // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD                0x00000008  // Reserved.
//      IMAGE_SCN_TYPE_COPY                  0x00000010  // Reserved.

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.

#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA                0x00008000
//      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    0x00010000
#define IMAGE_SCN_MEM_PURGEABLE              0x00020000
#define IMAGE_SCN_MEM_16BIT                  0x00020000
#define IMAGE_SCN_MEM_LOCKED                 0x00040000
#define IMAGE_SCN_MEM_PRELOAD                0x00080000

#define IMAGE_SCN_ALIGN_1BYTES               0x00100000  //
#define IMAGE_SCN_ALIGN_2BYTES               0x00200000  //
#define IMAGE_SCN_ALIGN_4BYTES               0x00300000  //
#define IMAGE_SCN_ALIGN_8BYTES               0x00400000  //
#define IMAGE_SCN_ALIGN_16BYTES              0x00500000  // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES              0x00600000  //
#define IMAGE_SCN_ALIGN_64BYTES              0x00700000  //
#define IMAGE_SCN_ALIGN_128BYTES             0x00800000  //
#define IMAGE_SCN_ALIGN_256BYTES             0x00900000  //
#define IMAGE_SCN_ALIGN_512BYTES             0x00A00000  //
#define IMAGE_SCN_ALIGN_1024BYTES            0x00B00000  //
#define IMAGE_SCN_ALIGN_2048BYTES            0x00C00000  //
#define IMAGE_SCN_ALIGN_4096BYTES            0x00D00000  //
#define IMAGE_SCN_ALIGN_8192BYTES            0x00E00000  //
// Unused                                    0x00F00000
#define IMAGE_SCN_ALIGN_MASK                 0x00F00000

#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

参考资料:
https://developer.microsoft.com/zh-cn/windows/downloads/windows-10-sdk/
https://docs.microsoft.com/en-us/windows/win32/api/winnt/

特别感谢:
Winder (School of software, Yunnan University)

相关文章:《 PE 文件映射解析》

如有错误遗漏之处,欢迎补充交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值