■扩展头(可选标头仅限映像文件)
OptionalHeader字段描述了可执行文件的更多细节和布局信息,如图像基址、入口点、数据目录、节表等。它的具体结构取决于文件的机器架构,可以是IMAGE_OPTIONAL_HEADER32(32位)或IMAGE_OPTIONAL_HEADER64(64位)结构体。
PE文件的扩展头位于文件头之后,其结构可以根据具体的文件类型和操作系统的架构而有所不同。
每个映像文件都有一个用于向加载程序提供信息的可选标头。 此标头是可选标头,因为某些文件(特别是obj对象文件)没有此标头。 对于映像文件,此标头是必需的。对象文件可以具有可选标头,但通常此标头在对象文件中没有函数,只是为了增加其大小。
注意
1.可选标头的大小不是固定的。 COFF 标头中的 SizeOfOptionalHeader 字段必须用于验证对特定数据目录的文件的探测是否未超出 SizeOfOptionalHeader。 有关详细信息,请参阅MSDN COFF 文件标头(对象和映像)。
2.还应该使用可选标头的 NumberOfRvaAndSizes 字段(数据目录的项目数量)来确保对特定数据目录条目的探测不会超出可选标头。 此外,请务必验证可选标头魔数,以确保格式兼容性。
可选标头魔数确定映像是 PE32 还是 PE32+ (64位PE)可执行文件。
魔数 |
PE 格式 |
0x10b |
PE32 |
0x20b |
PE32+ |
PE32+ 映像允许使用 64 位地址空间,同时会将映像大小限制为 2 GB。 其他 PE32+ 修改会在各自的部分中进行介绍。
可选标头本身具有三个主要部分。
偏移量 (PE32/PE32+) |
大小 (PE32/PE32+) |
标头部分 |
说明 |
0 |
28/24 |
标准字段 |
为 COFF 的所有实现(包括 UNIX)定义的字段。 |
28/24 |
68/88 |
特定于 Windows 的字段 |
用于支持 Windows(例如子系统)的特定功能的其他字段。 |
96/112 |
变量 |
数据目录 |
在映像文件中找到并由操作系统使用的特殊表(例如,导入表和导出表)的地址/大小对。 |
●可选标头标准字段(仅限映像)
可选标头的前八个字段是为 COFF 的每个实现定义的标准字段。 这些字段包含可用于加载和运行可执行文件的常规信息。 对于 PE32+ 格式,它们保持不变。
Offset |
大小 |
字段 |
说明 |
0 |
2 |
Magic |
标识映像文件状态的无符号整数。 最常见的数字是 0x10B,它将映像文件标识为普通可执行文件。 0x107 将映像文件标识为 ROM 映像,0x20B 将映像文件标识为 PE32+ 可执行文件。 |
2 |
1 |
MajorLinkerVersion |
链接器主版本号。 |
3 |
1 |
MinorLinkerVersion |
链接器次要版本号。 |
4 |
4 |
SizeOfCode |
代码(文本)段的大小,或者如果有多个部分,则是所有代码段的和。 |
8 |
4 |
SizeOfInitializedData |
初始化数据部分的大小,或者如果有多个数据部分,则是所有此类部分的和。 |
12 |
4 |
SizeOfUninitializedData |
未初始化数据部分 (BSS) 的大小,或者如果有多个 BSS 部分,则是所有此类部分的和。 |
16 |
4 |
AddressOfEntryPoint |
可执行文件加载到内存中时相对于映像基址的入口点地址。 对于程序映像,这是起始地址。 对于设备驱动程序,这是初始化函数的地址。 入口点对于 DLL 是可选的。 不存在入口点时,此字段必须为零。 |
20 |
4 |
BaseOfCode |
加载到内存中后相对于代码开头部分映像基址的地址。 |
【注】PE32 包含位于 BaseOfCode 之后的此附加字段,此字段在 PE32+ 中不存在。
Offset |
大小 |
字段 |
说明 |
24 |
4 |
BaseOfData |
加载到内存中后相对于数据开头部分映像基址的地址。 |
●可选标头 Windows 特定字段(仅限映像)
接下来的 21 个字段是 COFF 可选标头格式的扩展。 它们包含 Windows 中的链接器和加载程序所需的其他信息。
偏移量 (PE32/PE32+) |
大小(PE32/PE32+) |
字段 |
说明 |
28/24 |
4/8 |
ImageBase |
映像加载到内存中后第一个字节的首选地址;必须是 64 K 的倍数。DLL 的默认值为 0x10000000。 Windows CE EXE 的默认值为 0x00010000。 Windows NT、Windows 2000、Windows XP、Windows 95、Windows 98 和 Windows Me 的默认值为 0x00400000。 |
32/32 |
4 |
SectionAlignment |
各部分加载到内存中时的对齐值(以字节为单位)。 它必须大于或等于 FileAlignment(4KB)。 默认值为体系结构的页面大小。 |
36/36 |
4 |
FileAlignment |
用于使映像文件中各部分的原始数据一致的对齐系数(以字节为单位)。 该值应为 2 的幂次方,介于 512 和 64K 之间(含)。 默认值为 512。 如果 SectionAlignment 小于体系结构的页面大小,则 FileAlignment 必须与 SectionAlignment 匹配。 |
40/40 |
2 |
MajorOperatingSystemVersion |
所需操作系统的主版本号。 |
42/42 |
2 |
MinorOperatingSystemVersion |
所需操作系统的次要版本号。 |
44/44 |
2 |
MajorImageVersion |
映像的主版本号。 |
46/46 |
2 |
MinorImageVersion |
映像的次要版本号。 |
48/48 |
2 |
MajorSubsystemVersion |
子系统的主版本号。 |
50/50 |
2 |
MinorSubsystemVersion |
子系统的次要版本号。 |
52/52 |
4 |
Win32VersionValue |
保留,必须为零。 |
56/56 |
4 |
SizeOfImage |
映像加载到内存中时的映像大小(以字节为单位 |