PE文件是Portable Executable(可移植的可执行文件)的简写,是微软Windows操做系统上的程序文件。EXE、DLL、SYS、COM都是PE文件。
生成PE文件
打开vs2019编写一个helloworld.exe的控制台程序用作例子
#include <iostream> int main() { std::cout << "Hello World!\n"; system("pause"); }
生成exe后运行
利用peview分析
拖入peview,左侧显示格式,右侧显示具体内容
PE头组成
左侧显示出该pe文件的格式,由头部和数据组成组成,头部又分为DOS头,NT头,section头,均以IMAGE开头,而以SECTION开头的就是数据部分
DOS头
DOS头由MZ文件头和DOS块组成
IMAGE_DOS_HEADER
就是MZ文件头,占地址00000000-00003c00
MZ是MS-DOS设计者Mark Zbikowski的姓名缩写。 最后四个字节,表示下一个头部,即NT头的偏移地址,此处该值位 该值是0x000000F0,通过在左侧点击IMAGE_DOS_HEADER查看 e_lfanew内容也可确认
在这里也可以查看其他 MS-DOS环境下运行时所需要的一些参数,已经被解析好了,但有用的一般只有刚刚的MZ 和NT头偏移地址。
MS-DOS Stub Program
就是DOS块,占地址00000040-000000E0
DOS块之所以叫DOS块,是因为这是一段可以在DOS下运行的程序,运行后会显示一段字符串来提示用户PE程序必须在Windows下才能运行。
NT头
NT头包括Signatrue、IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER三部分。
Signatrue
也叫作PE文件的文件签名,共4个字节,其值为0x00004550,即为字符串“PE”,标志该文件的类型为PE。
IMAGE_FILE_HEADER
部分共12字节。
①2个字节表示机器类型,用于标识CPU的类型,后两个字节表示CPU为Intel 386或后继处理器及其兼容处理器;
②接下来的Number of Section表示节的数目,表示本应用程序有5个节(section),从图中能够看出,本应用程序确实有5个节(section);
④Size of optional header这两个字节是IMAGE_OPTIONAL_HEADER,即NT头的下一个部分的大小,其值为0x00E0,就是说OptionalHeader的大小是224字节。
⑤Characteristics表示文件属性,它的每个bit都代表了文件某个属性,其值为0x0102。
Bit 0 :置1表示文件中没有重定向信息。每一个段都有它们本身的重定向信息。
这个标志在可执行文件中没有使用,在可执行文件中是用一个叫作基址重定向目录表来表示重定向信息的,这将在下面介绍。
Bit 1 :置1表示该文件是可执行文件(也就是说不是一个目标文件或库文件)。
Bit 2 :置1表示没有行数信息;在可执行文件中没有使用。
Bit 3 :置1表示没有局部符号信息;在可执行文件中没有使用。
Bit 4 :
Bit 7
Bit 8 :表示但愿机器为32位机。这个值永远为1。
Bit 9 :表示没有调试信息,在可执行文件中没有使用。
Bit 10:置1表示该程序不能运行于可移动介质中(如软驱或CD-ROM)。在这 种状况下,OS必须把文件拷贝到交换文件中执行。
Bit 11:置1表示程序不能在网上运行。在这种状况下,OS必须把文件拷贝到交换文件中执行。
Bit 12:置1表示文件是一个系统文件例如驱动程序。在可执行文件中没有使用。
Bit 13:置1表示文件是一个动态连接库(DLL)。
Bit 14:表示文件被设计成不能运行于多处理器系统中。
Bit 15:表示文件的字节顺序若是不是机器所指望的,那么在读出以前要进行
交换。在可执行文件中它们是不可信的(操做系统指望按正确的字节顺序执行程序)。
IMAGE_OPTIONAL_HEADER
由两部分组成:参数部分和数据目录部分
参数部分包含了产生该PE文件的链接器版本号、代码基地址、数据基地址、镜像基地址等信息;
数据目录部分包含了导出表、导入目录表、资源表等地址和大小
section头
每一个节头的大小是40字节。节头和节一一对应并描述对应节的信息。
对应关系:
.bss 未初始化的数据.data 代码节.edata 导出表.idata 导入表.pdata 异常信息.rdata 只读的已初始化数据(常量).reloc 重定位信息.rsrc 资源目录.sbss 与GP相关的未初始化数据.sdata 与GP相关的已初始化数据.text 默认代码节.idlsym 包含已注册的SEH,以支持IDL
查看默认代码节.text的节头包含的节信息
-
Name表示节头的名称,其大小为8个字节;
-
Virtual Size表示节头对应的节的大小,其大小为4个字节;
-
RVA是Relative Virtual Address的简称,即相对虚拟地址,指定了节头对应节的RVA,其大小为4个字节;
-
Size of Raw Data指的是磁盘文件中已经初始化数据的大小,其大小为4个字节;
-
Pointer to Raw Data、Pointer to Relocations和Pointer to Line Numbers分别保存了节中数据起始地址、重定位项起始地址和行号信息数量的地址,大小均为4个字节;
-
Number of Relocations和Number of Line Numbers分别表示节中重定位项的数量和行号信息的数量,大小均为2个字节,
-
Characteristics是描述节特征的标志,大小为4个字节,,共32位,每位的含义以下。
Characteristics各位含义1-5 未使用 6 此节包含可执行代码7 此节包含已初始化的数据 8 此节包含未初始化的数据9-15 未使用 16 此节包含经过全局指针来引用的数据17-24 未使用 25 此节包含扩展的重定位信息26 此节能够在须要时被丢弃 27 此节不能被缓存28 此节不能被交换到页面文件中 29 此节能够在内存中共享30 此节能够做为代码执行 31 此节可读32 此节可写