PE文件头的结构

PE文件是windows下可移植的可执行文件,常见的有exe、dll后缀文件都是PE文件。PE文件头是对整个PE文件数据存储的说明和文件信息的阐述,是一种数据组织方式。32位系统的PE头包括以下结构:DOS MZ头,DOS Stub,PE头,PE头,节表和节内容。

DOS MZ头 IMAGE_DOS_HEADER

PE文件头的结构_第1张图片
在32位系统中,IMAGE_DOS_HEADER包括以上内容,我们使用HelloWorld.exe程序作为样例,用winHex查看其字节码。
在这里插入图片描述
特别关注第一个e_magic和最后一个e_lfanew,第一个是exe标志,最后一个是PE头相对于文件的偏移地址。可以看到它的值是 00000080 这表明PE头的Signature就是从整个位置开始的。
紧跟MZ头的是DOS Stub。这里主要是一些垃圾值以及编译器填充的一些“is program cannot be run in DOS mode.”或“This program must be run under Win32”等信息。
在这里插入图片描述

PE头 IMAGE_FILE_HEADER

之后就是由e_lfanew指向的PE标识,它是PE头开始的标志。
在这里插入图片描述
这部分数据的意义如下图:其中的偏移是基于e_lfanew的值所指的位置。
PE文件头的结构_第2张图片
其中Machine用来指定PE文件的运行平台,如Intel, Sun, Dec, IBM等。
可以通过该结构得到PE文件中节的总量(NumberOfSections),这样在遍历节区信息时就可以有确定的循环次数。
此外还有Characteristics字段,它的不同数据位定义了不同的文件属性,具体如下:
PE文件头的结构_第3张图片

拓展PE头 IMAGE_OPINIONAL_HEADER32

该部分数据包含着十分丰富的信息,如下图:、
PE文件头的结构_第4张图片
PE文件头的结构_第5张图片
其偏移量也是基于e_lfanew指向地址的。

其中比较重要的信息有:
Magic:用于说明文件类型,如果为010BH,则表示该文件为PE32;如果为0107H,则表示文件为ROM映像;如果为020BH,则表示文件为PE64。
AddressOfEntryPoint:该字段是一个相对虚拟内存地址(RVA),它记录了启动代码距离该PE加载后的起始位置到底有多少个字节。
BaseOfCode:代码节的起始RVA,表示映像被加载进内存时代码节的开头相对于映像基址的偏移地址。一般情况下代码节紧跟在PE头部后面。
BaseOfData.:数据节的起始RVA,表示映像被加载进内存时数据节的开头相对于映像基地址的偏移地址。

数据目录项IMAGE_DATA_DIRECTORY的字段

HelloWorld.exe中该部分字段如下:
PE文件头的结构_第6张图片
该部分主要是记录PE文件出现的所有不同类型的数据的目录信息,从Windows NT 3.1操作系统开始到现在,该数据目录中定义的数据类型一直都是16种。每种数据类型在该数据结构中有两个属性,分别是特定类型数据的起始RVA和特定数据块长度。
PE文件头的结构_第7张图片
包含的数据类型如下:
PE文件头的结构_第8张图片
PE文件头的结构_第9张图片

节表项IMAGE_DATA_DIRECTORY的字段

节表就是节的内容,节表的个数由IMAGE_FILE_HEADER中的NumberOfSections确定。
每个节表中有十个字段,如下:
PE文件头的结构_第10张图片
用WinHex可以读取HelloWorld.exe中的NumberOfSections的值:
在这里插入图片描述
其值为0x000F,所以有15个节表。
用作者自己写的文件解析器解析:
PE文件头的结构_第11张图片
以下是对部分字段的说明:
Misc:该字段是一个union型的数据,这是节在没有对其前的真实尺寸。不过很多PE文件里该值并不准确。
VirtualAddress:节区的RVA地址。
SizeOfRawData:节在文件中对齐后的尺寸。在Helloworld.exe中,数据量不太大的节,其大小一般为200h。
PointerToRawData:节区起始数据在文件中的偏移。
Characteristics:节的属性,该字段不同数据位代表了不同的属性,具体如下:
PE文件头的结构_第12张图片
以上就是PE文件头的所有结构。

你可能感兴趣的:(安全,windows)