您的位置:首页 > 其它

PE文件学习系列三-PE头详解

2013-10-04 23:45 176 查看
合肥程序员群:49313181。 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)
Q Q:408365330 E-Mail:egojit@qq.com
最近比较忙,只能抽节假日去学习和记录自己的学习,这一节我记录自己学习PE头的学习。在这里给大家介绍一本很好的学习PE的书:Windows PE权威指南。上一节我们一起学习DOS头。DOS头很多内容在16位DOS系统下面才会用到。在现在的Win32系统中,这些事冗余。

因此我们关注更多的是PE头而非DOS头。首先上图,对着图片看才够清晰:





以后不管我们学习PE的哪个结构,我们都对着这个图去学习,这样才会有感觉。

上PE头C结构描述,这个结构还是在WinNT.h中:

typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
请查看上面的图片四字节的被称为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文件加密……,等等都是靠对这些机构的理解才能做到。

-----

版权:归博客园和Egojit所有,转载请标明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: