PE结构头以及结构大小和偏移(附带地址)
以win11系统记事本(notepad.exe)为例
记事本为32位应用
1. DOS头(00000000h-0000003fh)
DOS_HEADER
DOS头 是用来兼容 MS-DOS 操作系统的,目的是当这个文件在 MS-DOS 上运行时提示一段文字,大部分情况下是:This program cannot be run in DOS mode. 还有一个目的,就是指明 NT 头在文件中的位置。
偏移 | 大小 | 地址 | 英文名 | 中文名 | 描述 |
---|---|---|---|---|---|
0 | 2 | 00000000h-000000001h | MZ_HEADER | MZ头 | .EXE可执行文件的识别数 |
60 | 4 | 00000003ch-00000040h | E_lfanew | PE的偏移量 | PE文件签名的偏移地址 |
2. NT头
NT头 包含 windows PE 文件的主要信息,其中包括一个 PE 字样的签名,PE文件头(PE_HEADER)和 PE可选头(OPTIONAL_PE_HEADER)。
2.1 PE头
PE_HEADER
偏移 | 大小 | 地址 | 英文名 | 中文名 | 描述 |
---|---|---|---|---|---|
0 | 4 | 00000100h-000000103h | PE_HEADER | PE头 | PE文件的标识 |
4 | 2 | 00000104h-000000105h | Machine | 机器数 | 标识CPU的数字 |
6 | 2 | 00000106h-000000107h | NumberOfSections | 节数 | 节的数目。Windows加载器限制节的最大数目为96。 |
20 | 2 | 00000114h-00000115h | SizeOfOptionalHeader | 可选头 | 可选PE头大小,32位PE文件默认E0h(224字节),64位默认F0h(240字节) |
2.2 PE可选头
OPTIONAL_PT_HEADER
偏移 | 大小 | 地址 | 英文名 | 中文名 | 描述 |
---|---|---|---|---|---|
0 | 2 | 00000118h-000000119h | Magic | 魔数 | 这个无符号整数指出了镜像文件的状态。 0x10B表明这是一个32位镜像文件。 0x107表明这是一个ROM镜像。 0x20B表明这是一个64位镜像文件。 |
16 | 4 | 00000128h-00000012bh | AddressOfEntryPoint | 入口点 | 当可执行文件被加载进内存时其入口点RVA。对于一般程序镜像来说,它就是启动地址。为0则从ImageBase开始执行。对于dll文件是可选的。 |
28 | 4 | 00000134h-000000137h | ImageBase | 镜像基址 | 当加载进内存时镜像的第1个字节的首选地址。它必须是64K的倍数。DLL默认是10000000H。Windows CE 的EXE默认是00010000H。Windows 系列的EXE默认是00400000H。 |
32 | 4 | 00000138h-00000013bh | SectionAlignment | 内存对齐 | 当加载进内存时节的对齐值(以字节计)。它必须 ≥FileAlignment(文件对齐)。默 认是相应系统的页面大小。 |
36 | 4 | 0000013ch-00000013fh | FileAlignment | 文件对齐 | 用来对齐镜像文件的节中的原始数据的对齐因子(以字节计)。它应该是界于512和64K之间的2的幂(包括这两个边界值)。默认是512。如果SectionAlignment小于相应系统的页面大小,那么FileAlignment必须与SectionAlignment相等。 |
56 | 4 | 00000150h-000000153h | SizeOfImage | 镜像大小 | 当镜像被加载进内存时的大小,包括所有的文件头。向上舍入为SectionAlignment的倍数。 |
60 | 4 | 00000154h-000000157h | SizeOfHeaders | 头大小 | 所有头的总大小,向上舍入为FileAlignment的倍数。可以以此值作为PE文件第一节的文件偏移量。 |
3. 节表目录头
SECTION_HEADER
PE节表位于PE头的下面,PE节表中记录了各个节表的起始位置、大小,以及在内存中偏移位置和属性。
偏移 | 大小 | 地址 | 英文名 | 中文名 | 描述 |
---|---|---|---|---|---|
0 | 8 | 000001f8h-0000001ffh | NAME | 节名 | 这是一个8字节ASCII编码的字符串,不足8字节时用NULL填充,必须使其达到8字节。如果它正好是8字节,那就没有最后的NULL字符。可执行镜像不支持长度超过8字节的节名。 |
8 | 4 | 00000200h-000000203h | VirtualSize | 节表大小 | 该节表在对齐前的大小也是在内存中的大小。 |
12 | 4 | 00000205h-000000207h | VirualAddress | 节表在内存中偏移 | 内存中节表真正偏移=内存地址+ 节偏移 |
16 | 4 | 00000208h-00000020bh | SizeOfRawData | 已初始化数据大小 | 对齐后的大小也是文件中的大小 |
20 | 4 | 0000020ch-00000020fh | PointerToRawData | 节表在文件中偏移 | 节表在文件中的偏移 |
36 | 4 | 0000021ch-00000021fh | Characteristics | 节特征 | 描述节特征的标志。 |