上次讲到DOS现在讲下紧跟在DOS头部后面的PE头:
PE头映射的是IMAGE_NT_HEADER结构,里面包含PE装载器用到的重要字段
下图是IMAGE_NT_HEADER结构体原型有三个成员:
Signature字段:在一个有效的PE文件里,Signature字段被设置为'00 00 45 50',ASCII码字符是‘PE00’。标志着PE文件头的开始:
IMAGE_FELE_HEADER也是一个结构体:
Machine成员 下图'01 4C'说明了可执行文件目标CPU类型:
Machine:
0x014c x86
0x0200 Intel Itanium
0x8664 x64
NumberOfSections成员 下图'00 08'说明了区块的数目,这里说明区块数目为8:
TimeDateStamp成员 下图'2A 42 5E 19'说明了文件的创建时间,是以格林威治时间1970,1,1开始计算按秒:
下边说明名了这七个成员的内存中偏移位置:
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;