PE文件学习系列三-PE头详解
Q Q:408365330 E-Mail:egojit@qq.com
最近比较忙,只能抽节假日去学习和记录自己的学习,这一节我记录自己学习PE头的学习。在这里给大家介绍一本很好的学习PE的书:Windows PE权威指南。上一节我们一起学习DOS头。DOS头很多内容在16位DOS系统下面才会用到。在现在的Win32系统中,这些事冗余。
因此我们关注更多的是PE头而非DOS头。首先上图,对着图片看才够清晰:
以后不管我们学习PE的哪个结构,我们都对着这个图去学习,这样才会有感觉。
上PE头C结构描述,这个结构还是在WinNT.h中:
请查看上面的图片四字节的被称为PE标识符的Signature这四个字节就是图上面的PE00。我猜PE文件的称谓也是这个缘由吧。。_IMAGE_NT_HEADERS 结构的另外两个成员都是结构体,
1.PE标准机构-IMAGE_FILE_HEADER
typedef struct _IMAGE_FILE_HEADER { WORD Machine;//运行平台 WORD NumberOfSections;//PE文件中节的数量 DWORD TimeDateStamp;//文件创建时间和日期 DWORD PointerToSymbolTable;//指向符合表(用于调试) DWORD NumberOfSymbols;//符合表中符号数量(用于调试) WORD SizeOfOptionalHeader;//扩展头结构的长度 WORD Characteristics;//文件属性 } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
我已经给机构成员后面添加了备注,让我们理解这个结构。IMAGE_FILE_HEADER.NumberOfSections。PE节的数量,这个可以对节区信息进行遍历的循环次数。
2.PE扩展头-IMAGE_OPTIONAL_HEADER32
typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic;//魔术字 BYTE MajorLinkerVersion;//连接器版本号 BYTE MinorLinkerVersion; DWORD SizeOfCode; //所有含代码节的总大小 DWORD SizeOfInitializedData;//所有含已初始化数据的节的总大小 DWORD SizeOfUninitializedData;//所有含未初始化数据的节的大小 DWORD AddressOfEntryPoint;//程序执行入口RVA DWORD BaseOfCode;//代码节的起始RVA DWORD BaseOfData;//数据节的起始RVA // // NT additional fields. // DWORD ImageBase; //程序的建议装载地址 DWORD SectionAlignment;//内存节的对齐粒度 DWORD FileAlignment;//文件中节的对齐粒度 WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion;//操作系统版本号 WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage;//内存中PE镜像文件尺寸 DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics;//DLL文件特性 DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes;//下面的数据目录结构的项目数量 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//数据目录 } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
以上我对一些比较关注的机构字段加上了备注。
查看以上机构我们看到这个IMAGE_OPTIONAL_HEADER32结构内容特别丰富,比PE标准结构丰富多了。
SectionAlignment这个字段是内存中节的对齐粒度,在这里我要说明下,Windows系统中(默认32位系统),操作系统能识别4G内存,对于每个进程都有一个独立的4G虚拟内存。在这种4G虚拟内存机制中起到最大的作用是内存分页机制,内存分页机制将一部分硬盘空间作为内存。而这个分页机制中的页大小为4K,也就是16进制的1000H。那么我们很容易知道默认的SectionAlignment值就是1000H,也就是4K。当然PE文件在硬盘上是不一样的,PE文件存磁盘上对齐粒度是200H。
结构最后一个字段IMAGE_DATA_DIRECTORY。该字段定义了PE文件中出现的所有不同类型的数据的目录信息,应用程序中数据被按照用途分成很多种类,如导入表,导出表,资源,重定位表等,DataDirectory数组个数为16。
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress;//数据起始RVA DWORD Size;//数据块长度 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
IMAGE_DATA_DIRECTORY.VirtualAddress虚拟地址指定的是相应节的相对虚拟地址(RVA),PE文件中有16个节,严格讲有15个,最后一个是预留的。
学到这有人会问,看了这么多结构,有什么用呢??这个真的很有用,后期可以写程序区分析这些机构。可以动态改变PE结构,可以给PE文件加密……,等等都是靠对这些机构的理解才能做到。
-----