Re----PE文件格式
以上两张图是PE文件的基本概况,在Windows下所谓PE文件即Portable Executable,意为可移植的可执行的文件。常见的.EXE、.DLL、.OCX、.SYS、.COM都是PE文件。PE文件有一个共同特点:前两个字节为4D 5A(MZ)。如果一个文件前两个字节不是4D 5A则其肯定不是可执行文件。
在可执行文件中,要指定内存的地址,在PE文件中的地址是虚拟地址(为了避免有确定的的内存地址而带来的问题,如空间利用和移植性)
Visual C++ 建立的EXE文件基地址默认是00400000h,DLL文件基地址是10000000h
在PE文件中,虚拟地址=基地址+相对虚拟地址
以上是一种映射关系,大家可以自己悟一下,任何在执行的虚拟地址都是映射而来的
基本概念已经清楚了,我们按照图10.1逐步开始分析
1. DOS部首
主要是两部分 DOS stub、DOS MZ,DOS部首具体如下
主要的就是两个,一个是e_magic,它提供了PE文件的标识符,用来表示自身是PE文件;第二个是e_lfanew,里面的数据表示真正PE文件头的偏移量
2. PE头(我用PEview随便打开了一个PE文件)
我们可以看到DOS部首接下去就是PE头,又可以称他为IMAGE_NT_HEADERS,包含三块,Signature、FILE_HEADER、OPTIONAL_HEADER
2.1 Signature
Signature就是设置了一个字符串“PE00”,做个标识
2.2 FILE_HEADER
这一段我在PEview里面无法显示出来,不过就是显示了一下PE文件的基本信息,然后表明了OPTIONAL_HEADER的大小
2.3 OPTIONAL_HEADER
其实OPTIONAL_HEADER和FILE_HEADER都是来表名PE文件的属性的,可以结合起来看,我们看一下j具体的OPTIONAL_HEADER
这里其实这么多属性百度都是可以找到的,提几个重要的好了:
Address of Entry Point --程序执行入口RVA;
Base of Code--代码段的起始RVA;
Base of Data--数据段的起始RVA;
Image Base--文件在内存中的首选装入地址;
SectionAlignment--装入内存时的区块对应大小;
Number of Data Directions--数据目录表的项数,一直是16,接下来就是16个数据块,每个目录包括两个元素,数据块起始RVA和数据块长度
每个数据块都的解释还是比较清楚的
3. 区块表
接下来就是各种块表了,本例有三个块表
每个区块表里面有关于该块的信息
还是比较清楚的,分析这个区块表,大小为19A,相对虚拟地址RVA为1000,实际在磁盘块中占用了200,磁盘块中偏移为400…………………………
每个区块有不同的名字,不是一定存在的,有好多……
4. 输入表结构
代码执行的时候需要调用不在程序中,但在内存中的函数,PE文件装载时,经常要调用别的DLL函数,所有的要装载的DLL函数的地址都在IAT(输入地址表)中来便于调用
PE文件头的OPTIONAL_HEADER中的数据目录表的第二个成员指向输入表,输入表的第一个数组是IMAGE_IMPORT_DESCRIPTOR(IID),每个IID包含五个双字,第一个双字指向输入名称表(INT),第四个双字表示库函数名称,最后一个双字指向IAT
PE文件装载内存后,所有的IMAGE_THUNK_DATA里的元素就全部由IAT中的具体地址替换,所以最终访问IAT就好了
5. 输入表结构
知道了输入表,那显然有输出表,DLL文件和一些EXE文件都存在,用了别人的函数,有时候也是要奉献的嘛,输出表也在
OPTIONAL_HEADER中的数据目录表中,是第一个成员
输入表中的IID对应到输出表中就是IED,还有ENT,EAT,如下图
其中Name就是DLL的名字,AddressOfFunction就是EAT的RVA,AddressOfNames就是ENT的RVA,找起来还是比较清晰的
6. 基址重定位
重定位的原因是什么呢:当生成PE文件,如果装入时按默认的值作为基地址装入,就不需要重定位;若可执行文件不再首选的地址装入,就需要重定位
重定位地址表(Base Relocation Table)可以从数据目录表中找到
这个用LordPE打开
这里可以显示出那些数据需要重定位,这里是00402000和00403030,等加载程序进行重定位时,会将PE文件的需要重定位的地址跳到需要的内存地址上
7. 资源结构
Windows界面中的什么图标,菜单,工具栏等等都算作是资源,PE文件中的资源是有特定的结构的,存放在rsrc区段中
PE文件中资源的结构主要分为四层,接下来的两张图分别从概念以及PEview中的具体识别来直观介绍
我觉得从PEview的介绍更直观:资源类型->资源名->资源语言->资源数据的位置和大小
每一层具体的参数大家可以用PEview去分析,很简洁明了