首先转载一幅别人的图片
此图非常详细,可以看到每个字段的内容和大概含义,根据此图动手实践了PE文件结构,下面给出我自己理解的简约结构:
为了更加形象生动,特把实验过程记录如下,从实验过程中我们可以发现不小细节:
图中没有列出DOS头信息,直接跳到了NT头的Image_File_Header,其中Machine=014C,有四个段,可选头大小为EO;其他是一些标志位。
接下来是可选头部分image base=400000也就是镜像文件载入地址为400000,段落对齐1000(1024字节),文件对齐200(512字节),还有一些堆栈默认大小;
接下来是可选头里面的Data Directory数据目录,这个目录表明了导入表的虚拟地址:2244(此表在PE文件是.rdata段,地址:E44,.rdata的地址为C00,也就是.rdata偏移244就可找到导入表,因为.rdata虚拟地址是2000所以导入表虚拟地址为2000+244=2244),以及导出表、IAI等的虚拟地址计算方法同上。
接下来就是一个段表,里面标示了有几个段落,每个段落的PE文件地址是多少,大小多少,虚拟地址多少,虚拟地址空间中大小多少等信息。
.txt段落PE地址400,大小800,虚拟地址1000,大小7B6,为什么大小一会儿是800,一会儿是7B6呢?7B6为段实际大小,PE文件要求段对齐为200,400+7B6 = BB6,那么下一个段起址是BB7,不符合200的倍数关系,C00才是200的倍数,因此填充了一些无用的0使下一个段地址为200的整数倍;这个段放的都是代码,实际映射到进程的地址空间是1000。
.rdat段,PE地址C00,大小800,虚拟地址2000,大小656。这个段放的是一些只读量,里面就有导入表中的函数虚拟地址的值。因此修改这个值就可以HOOK API;还有字符串常量,例如char * a = "wo shi shui",这个字符串就放在这里面。
.data PE地址1400,大小200,虚拟地址3000,大小394,这里394>200是因为有些变量没有分配空间,所以没有占磁盘空间,但是到虚拟地址中就必须为其预留空间。也就是说PE文件将全局变量压缩存储了。这个段都是数据,有全局初始化数据和未初始化数据,有静态变量。
.rsrc PE地址1600,大小200,虚拟地址4000,大小1AC。这个段是资源段,可能用来存放图片。
在接下来就是各个具体段的数据了.txt,.rdat,.data,.rsrc,而导入表信息在.rdat里面存放着。
接下来是填充,为了让PE文件512字节对齐,从而进行填充。
然后PE文件结束了。
好了,下面来具体看看PE文件:
下图是用WINHEX打开PE文件后的实际情况:
下面是NT头开始的数据,包含了image file header、image optional header、四个段的信息表、以及四个段的具体数据
上图已经圈出了头部的数据结构,每个颜色代表一个头,最下面是各段的具体数据,当然首先是被全0填充的,直到400才开始是真实的段数据。
未完待续
转自:http://www.cnblogs.com/maplewan/p/PE%E7%BB%93%E6%9E%84.html