PE 文件格式

分析所使用的 exe 程序的源代码见:寻找栈溢出

Release 版本

Release 版本相对于 Debug 版本精简许多,编译器对 Release 版本的程序进行了各种优化,比如精简掉无关的函数调用等,使得程序在文件大小和运行速度上都比较优秀

pe_file_format_1.png

Debug 版本

前面部分中的 DOS MZ 文件头以及 DOS 插桩程序和 Release 版本一样,这一部分是 PE 文件格式通用格式。MS-DOS Stub Program 之后的近百个字节的作用不知用处。

地址 0x3C 处的 D0 标识了 PE 文件真正的开始位置,从 0xD0 开始,PE 头前面的文件头标识,也就是 signature 都是相同的,之后就是 PE 文件头信息

pe_file_format_2.png

文件头标识了运行环境 i386 ,节的数量 5,这个文件的符号表指针和符号数量均为 0 ,可选头信心的大小 00E0 ,文件特征值 010E ,二进制 0000 0001 0000 1110 的含义: 0002(exe 文件)+ 0004(不存在行信息)+ 0008(不存在符号信息)+ 0100(32 位机器),以二进制位取值来对 PE 文件进行说明

pe_file_format_3.png

可选头大小 224 字节,标识了代码区、数据区、栈区、堆区的大小,还有程序入口点地址 Address of Entry Point 位于文件 0xF8 处,值为 00001650 。还包含了某些节表的地址和大小信息

pe_file_format_4.png

节表,提供每一节的具体信息,在文件的其实位置、大小,内存映射关系、节表类型等。节表的结构都是一样的。 含义:

  • 节名;
  • 未知的 8 字节;
  • 实际使用的区块大小;
  • 相对虚拟地址;
  • 该节在磁盘文件中所占的空间大小;
  • 相对于文件的偏移量;
  • 重定位信息的偏移量(exe 中无意义);
  • 重定位数目;
  • 行号数目;
  • 特征值(和 PE 头中相似,采用二进制位来标识)。
pe_file_format_5.png

再之后就是节的具体内容。地址映射从这时就要开始执行了,虚拟基址 0x00400000 ,第一节的虚拟地址 00001000,被装载到 0x00401000 ,其他节类似。不同节有不同的用处,存放着程序运行所需的信息。

.idata 节中有导入函数地址表和导入函数目录表,这两个表标明了程序所需的外部函数以及这些函数如何正确被调用。 IAT 表由导入 DLL 的函数个数决定,每个 IAT 项占 4 个字节,指向对应外部函数的内存相对虚拟地址, DLL 间用双字 0 分隔

pe_file_format_6.png

IDT 表记录 PE 文件要导入的库文件及函数的信息,实验所用的这个文件只导入了 kernel32.dll 这一个 dll 文件。表项先指出 IAT 的 RVA,和 PE 头中的完全对应。之后两个不清楚,在之后是 dll 文件名这个字符串的 RVA,命名表的 RVA。表项 2 全为 0

pe_file_format_7.png
湘ICP证019014083号