PE 的意思是 Portable Executable(可移植的执行体),它是 Win32环境自身所带的执行文件格式。在Win32系统中,PE文件可以认为.exe、.dll、.sys 、.scr类型的文件,这些文件在磁盘上存贮的格式都是有一定规律的。
PE格式的文件通过16进制数对文件的数据内容进行表示。
PE结构可以理解:Windows系统对文件进行识别后,按照固定的数据组织形式进行解读,然后在该系统下进行某些操作。这种系统识别的固定数据组织形式被称为PE文件结构。故,学习PE文件就是学习Windows系统的这种固定的数据组织形式。
下面是一个用16进制工具UE打开的pe文件后,我们所看到的样子。UltraEdit工具
Sys:系统文件,如驱动文件。
一个完整的PE文件主要有上面4个部分组成。
1、Dos部分主要用来对非FE格式文件的处理,DOS时代遗留的产物,是PE文件的一个遗传基因,主要用来对非FE格式文件的处理.
2、PE头部分用于宏观上记录文件的一些信息,分用于宏观上记录文件的一些信息,运行平台,大小,创建日期,属性等.
3、节表部分用于对各中类型的数据进行定义分段。用于对各中类型的数据进行定义分段.
4、节数据不言而喻就是文件的数据部分,实际上我们编写程序的过程中就是对该部分的数据进行编写。
而其他的部分则是由编译器依照我们编写的部分进行相应的填写而得到的。
DOS部分由如下两部分构成: Dos头和Dos块。
Dos头:长度40h,4行*16,
Dos块:长度不定DOS插桩代码,是DOS下的16位程序代码,只是为了显示上面的提示数据。这段代码是编译器在程序编译过程中自动添加的。
Dos头对于非pe结构的文件将指引dos可执行程序部分,也就指引到dos块。而对于PE结构的文件将指引到PE结构部分。具体如何指引是通过dos头结构进行指定的。
• e_magic WORD ? ;DOS可执行文件标记,固定为“MZ”
• e_cblp WORD ?
• e_cp WORD ?
• e_crlc WORD ?
• e_cparhdr WORD ?
• e_minalloc WORD ?
• e_maxalloc WORD ?
• e_ss WORD ? ;DOS代码的初始化堆栈段
• e_sp WORD ? ;DOS代码的初始化堆栈指针
• e_csum WORD ?
• e_ip WORD ? ;DOS代码的入口IP
• e_cs WORD ? ;DOS代码的入口CS
• e_lfarlc WORD ?
• e_ovno WORD ?
• e_res WORD 4 dup(?)
• e_oemid WORD ?
• e_oeminfo WORD ?
• e_res2 WORD 10 dup(?)
• e_lfanew DWORD ? ;指向PE文件的头部
•IMAGE_DOS_HEADER ENDS
这里是对dos头结构的完整定义,该字段的长度固定为40h(该40是16进制表示)。4行*16
第一项是字段的名称,第二项是字段的度量单位,第三项是字段的是数据内容,由于这里是介绍该结构用?表示,?前面的数字表示该字段的长度。有一个是4个长度的有一个是10个长度的。对于研究PE结构而言,该结构的定义中对我们有意义的字段只有最后一个(也就是红色的那一行),该字段的内容是一个长度为4个字节的地址,用于指向PE结构部分。
dosHeader->e_lfanew是DWORD类型,指出真正PE头相对于文件基地址的偏移值,即偏移多少个字节.
对于该字段在文件中如何查找,需要计算该字段E_lfanew的偏移(就是3Ch)。偏移的计算方法很简单,就是计算从结构头部到该字节的长度。下面我们来计算下这个字段的偏移。
E_lfanew字段前面共有18个字段,每个字段的单位都是word(也就是2个字节)长度有一个是4,一个是10,那么e_lfanew字段相对该结构首地址的偏移就是(可调用系统的计算器进行计算转换)(18-2+4+10)x2=60,转换成16进制就是3C,也可以利用一个更简单的方法来计算,该结构的长度为40, e_lfanew字段的长度为4,相减就得到了e_lfanew字段的偏移是3c。
由于该结构的各个字段都是固定的, e_lfanew字段的偏移在不同的PE文件中都是不变的。但不同的pe 文件该字段中的数据内容并不一定相同。 (也就是说不同文件的PE头结构的首地址不一定相同)
http://lwglucky.blog.51cto.com/1228348/283812
待续....