PE头部的解析(总结于小甲鱼)

上次讲到DOS现在讲下紧跟在DOS头部后面的PE头:

PE头映射的是IMAGE_NT_HEADER结构,里面包含PE装载器用到的重要字段


下图是IMAGE_NT_HEADER结构体原型有三个成员:

PE头部的解析(总结于小甲鱼)


Signature字段:在一个有效的PE文件里,Signature字段被设置为'00 00 45 50',ASCII码字符是‘PE00’。标志着PE文件头的开始:

PE头部的解析(总结于小甲鱼)

IMAGE_FELE_HEADER也是一个结构体:

PE头部的解析(总结于小甲鱼)


Machine成员 下图'01 4C'说明了可执行文件目标CPU类型:

PE头部的解析(总结于小甲鱼)

Machine:
0x014c    x86
0x0200   Intel Itanium
0x8664   x64


NumberOfSections成员 下图'00 08'说明了区块的数目,这里说明区块数目为8:

PE头部的解析(总结于小甲鱼)


TimeDateStamp成员 下图'2A 42 5E 19'说明了文件的创建时间,是以格林威治时间1970,1,1开始计算按秒:

PE头部的解析(总结于小甲鱼)


下边说明名了这七个成员的内存中偏移位置:


PE头部的解析(总结于小甲鱼)


SizeOfOptionalHeader成员:OfOptionalHeader数据结构的大小;对于32位PE文件,这个值通常是'00 E0';对于64位这个PE32+文件,这个值是‘00 f0’


IMAGE_IPTIONAL_HEADER32结构:在IMAGE_FELE_HEADER这个结构体上加了很多东西


typedef struct_IMAGE_OPTIONAL_HEADER
{
/*
Standard fields
*/
+18H WORD Majic; //标志字,ROM映像(0107H),普通可执行文件(010bH)
+1aH BYTE MajorLinkerVersion; //链接程序的主版本号
+1bH BYTE MinorLinkerVersion; //链接程序的次版本号
+1cH DWORD SizeOfCode; //所有含代码的节的总大小
+20H DWORD SizeOfInitializedData //所有含已初始化数据的节的总大小
+24H DWORD SizeOfUninitializedData;//所有含未初始化数据的节的大小
+28H DWORD AddressOfEntryPoint; //程序执行入口RVA
+2cH DWORD BaseOfCode; //代码区块的起始RVA
+30H DWORD BaseOfData; //数据的区块的起始RVA

/*
NT additional fields. 以下是属于NT结构增加的领域
*/
+34H DWORD ImageBase; //程序的首选装载地址
+38H DWORD SectionAlignment; //内存中的区块的对齐大小
+3cH DWORD FileAlignment; //文件中的区块的对齐大小
+40H WORD MajorOperatingSystemVersion;//要求操作系统最低版本号的主版本号
+42H WORD MinorOperatingSystemVersion;//要求操作系统最低版本号的副版本号
+44H WORD MajorImageVersion; //可运行于操作系统的主版本号
+46H WORD MinorImageVersion; //可运行于操作系统的次版本号
+48H WORD MajorSubsystemVersion; //要求最低子系统版本的主版本号
+4aH WORD MinorSubsystemVersion; //要求最低子系统版本的次版本号
+4cH DWORD Win32VersionValue; //莫须有字段,不被病毒利用的话一般为0
+50H DWORD SizeOfImage; //映像装入内存后的总尺寸
+54H DWORD SizeOfHeaders; //所有头 + 去块表的尺寸大小
+58H DWORD CheckSum; //映像的效验和
+5cH WORD Subsystem; //可执行文件期望的子系统
+5eH WORD DllCharacteristics; //DllMain()函数何时被调用,默认为0
+60H DWORD SizeOfStackReserve; //初始化时的栈大小
+64H DWORD SizeOfStackCommit; //初始化实际提交的栈大小
+68H DWORD SizeOfHeapReserver; //初始化时保留的堆大小
+6cH DWORD SizeOfHeapCommit; //初始化时实际提交的堆大小
+70H DWORD LoaderFlags; //与调试有关,默认为0
+74H DWORD NumberOfRvaAndSizes; //下边数据目录的项数,这个字段自Windows NT发布以来一直是16
+78H IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];  //数据目录表
}IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;