PE文件相关内容
1.PE header:
如何加载到内存、从何处开始运行、运行中需要的DLL文件有哪些、需要多大的栈/堆内存等,大量信息以结构体形式存储在PE头中。
PE文件格式如下:
DOS头+DOS存根+节区头=PE头
1.DOS头
在PE头最前面的是IMAGE_DOS_HEADER结构体,用来扩展已知的的DOS EXE头,该结构体共40个字节,我们必须要知道其中两个重要成员,分别是:
-
e_magic
代表DOS签名,其16进制值为4D5A(ASCII值为“MZ”) -
e_flanew
指示NT头的偏移(根据不同的文件拥有可变值)
Intel系列的CUP使用逆序存储数据(小端序)
2.DOS存根
DOS存根是可选项,大小不固定,即使没有DOS存根文件也能正常运行。由代码和数据混合而成,但是其中代码被忽略不会执行。
3.NT头
NT头结构体是IMAGE_NT_HEADERAS,其由三个成员组成,分别是:Signature结构体、File Header、OptionalHeader结构体。
-
Signature结构体
签名结构体,其值为50450000h("PE"00) -
FIle Header
文件头是表现文件大致属性的IMAGE_FILE_HEADER结构体
以下四种成员变量十分重要,若设置不正确将导致文件无法正常运行
1.Machine
每个CPU都有唯一的Machine码,可以在winnt.h中查看定义的Machine码。
2.NumberOfSectons
用来指出文件中存在的节区数量。该值一定要大于0,且定义的节区数量与实际节区不同时,将发生运行错误。
3.SizeOfOptionalHeader
其用来指出可选头(IMAGE_OPTIONAL_HEADER32)的长度。
PE32+格式的文件中使用的是IMAGE_OPTIONAL_HEADER64结构体,而不是IMAGE_OPTIONAL_HEADER32结构体,两者的尺寸是不同的,所以需要在SizeOfOptionalHeader成员中明确指出结构体的大小。
4.Characteristics
该字段用来标识文件的属性,文件是否是可运行的形态、是否为DLL文件等信息,若该值为0x0002,代表文件是可执行的,若值为0x2000,则代表该文件是DLL文件。 -
Optional Header
IMAGE_OPTIONAL_HEADER32结构体很大,在其中我们需要关注以下成员:
1.Magic
为IMAGE_OPTIONAL_HEADER32结构体时,Magic码为10B,为IMAGE_OPTIONAL_HEADER64时,Magic码为20B。
2.AddressOfEntryPoint
持有EP的RVA(相对虚拟地址)值。该值指出程序最先执行的代码起始地址,相当重要。
3.ImageBase
指出文件的优先装入地址。执行PE文件时,PE装载器先创建进程,再将文件载入内存,然后把EIP寄存器的值设置为ImageBase+AddressOfEntryPoint(对于操作系统来说都是虚拟地址)
4.SectionAlignment,FileAlignment
FileAlignment指定了节区在磁盘文件中的最小单位,SectionAlignment指定了节区在内存中的最小单位。磁盘文件或内存的节区大小必定为FileAlignment或SectionAlignment值的整数倍。
5.SIzeOfImage
指定了PE Image在虚拟内存中所占空间的大小。文件的大小与加载到内存中的大小一般是不同的。
6.SizeOfHeader
指出整个PE头的大小。
7.Subsystem
用来区分系统驱动文件(.sys)与普通可执行文件(.exe,*.dll)。
8.NumberOfRvaAndSizes
用来指定DataDirectory数组的个数
#9.DataDirectory
是由IMAGE_DATA_DIRECTORY结构体组成的数组,数组的每项都有被定义的值。
4.节区头
节区头中定义了各节区的属性。