文章目录
  1. 1. 0x00 口胡
  2. 2. 0x01 PE的前身-COFF
    1. 2.1. IMAGE_FILE_HEADER
    2. 2.2. IMAGE_SECTION_HEADER
    3. 2.3. 黑魔法1-.drectve段
    4. 2.4. 黑魔法2-调试信息
    5. 2.5. COFF符号表
  3. 3. 0x02 Windows下的ELF-PE
    1. 3.1. IMAGE_DOS_HEADER的引导作用
    2. 3.2. IMAGE_NT_HEADERS
  4. 4. 0x03 小结

0x00 口胡

怎么说呢,看到PE,满满的都是感动,想起了一年前,自己刚开始接触计算机时躲在被窝里怒刷汇编视频与PE视频的岁月了。。。当时自己还是傻白甜,看不懂就看很多遍,强行建立PE姿势,很感谢当初认真的自己吧,也感谢陪伴我度过日子的鱼C论坛,虽然现在很少逛了,希望它越办越好吧。。。

这篇不会讲太多,类似于过渡篇把。结构上的东西也不会讲太多,主要还是记录点有意思的东西。PE都被讲烂了,直接用一些PE工具看结构吧,挺直观的。。。

0x01 PE的前身-COFF

PE是32位windows的,PE32+是win64的。然而新的PE32+并没有添加任何结构,最大的变化就是把那些原来32位的字段变成了64位,呵呵。。。

给出COFF目标文件格式:

COFF文件的文件头部包括了两部分,一个是描述文件总体结构和属性的映像头(Image Header/IMAGE_FILE_HEADER),另外一个是描述该文件中包含的段属性的段表(Section Table/IMAGE_SECTION_HEADER)。

IMAGE_FILE_HEADER


IMAGE_SECTION_HEADER



黑魔法1-.drectve段

.drectve段实际上是Directive的缩写,它的内容是编译器传递给链接器的指令(Directive),即编译器希望告诉链接器应该怎样链接这个目标文件。.drectve段的标志位是”0x100A00”,是一些标志位的组合:

即该段是信息段,并非程序数据;该段可以在最后链接成可执行文件的时候被抛弃;该段在文件中的对齐方式是1个字节对齐。

我们可以用dumpbin对.drectve进行解析,给出内容:

黑魔法2-调试信息

COFF文件中所有以”.debug”开始的段都包含着调试信息。这些段中往往有一些意想不到的信息,也可以算是一个坑点

比如,”.debug$S”表示包含的是符号(Symbol)相关的调试信息段;”.debug$P”表示包含预编译头文件(Precompiled Header Files)相关的调试信息段;”.debug$T”表示包含类型(Type)相关的调试信息段。

给出.debug$S段的输出信息:

COFF符号表

COFF文件的符号表包含的内容几乎跟ELF文件的符号表一样,主要就是符号名、符号的类型、所在的位置等。

给出符号表的输出信息:



0x02 Windows下的ELF-PE

PE文件是基于COFF的扩展,它比COFF文件多了几个结构。最主要的变化有两个:第一个是文件最开始的部分不是COFF文件头,而是DOS_MZ可执行文件格式的文件头和桩代码(DOS MZ File Header and Stub,比较有意思的一个结构);第二个变化是原来的COFF文件头中的”IMAGE_FILE_HEADER”部分扩展成了PE文件的文件头结构”IMAGE_NT_HEADERS”。这个结构包括了原来的”Image Header”及新增的PE扩展头部结构(PE Optional Header)。

给出PE文件的结构:

为了所谓的兼容性-兼容DOS,PE文件的魔数是”MZ”,因为DOS下的可执行文件格式是”MZ”。PE文件中”Image DOS Header”和”DOS Stub”这两个结构也是为了兼容DOS。

“IMAGE_DOS_HEADER”结构其实跟DOS的”MZ”可执行结构的头部完全一样,所以从某个角度看,PE文件其实也是一个”MZ”文件。”IMAGE_DOS_HEADER”的结构中的前两个字节是”e_magic”结构,它是里面包含了”MZ”这两个字母的ASCII码;”e_cs”和”e_ip”两个成员指向程序的入口地址。

当PE可执行映像在DOS下被加载的时候,DOS系统检测到该文件,发现最开始两个字节是”MZ”,于是认为他是一个”MZ”可执行文件。然后DOS系统就将PE文件当做正常的”MZ”文件开始执行。DOS系统会读取”e_cs”和”e_ip”这两个成员的值,以跳转到程序的入口地址。然而PE文件中,”e_cs”和”e_ip”这两个成员并不指向程序真正的入口地址,而是指向文件中的”DOS stub”。”DOS stub”是一段可以在DOS下运行的一小段代码,这段代码的唯一作用是向终端输出一行字:”This program cannot be run in DOS”,然后退出程序,表示该程序不能在DOS下运行。这是PE文件结构兼容DOS “MZ”可执行文件结构的体现。

IMAGE_DOS_HEADER的引导作用

IMAGE_NT_HEADERS

这里有必要强调一下,IMAGE_NT_HEADERS包括IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER两个结构,NT才是爸爸,我老是搞混。。。

给出IMAGE_OPTIONAL_HEADER(x64下叫IMAGE_OPTIONAL_HEADER64)结构定义:


里面有很多成员,我们捡一些有意思的说,其他的字段也很重要,可以去MSDN查详细信息。总之,这个结构很重要

Windows在装载PE可执行文件时,往往需要很快的找到一些装载所需要的数据结构,比如导入表导出表资源重定位表。这些重要的数据的位置和长度都被保存在一个叫数据目录(Data Directory)的结构里面,其实他就是前面”IMAGE_OPTIONAL_HEADER”结构里面的”DataDirectory”成员,这个成员是一个”IMAGE_DATADIRECTORY”的结构数组(又是数组→→)

给出_IMAGE_DATA_DIRECTORY结构的定义:


数组中还包含其他的表,比如导入表、资源表、异常表、重定位表、调试信息表、线程私有存储(TLS)等的地址和长度。这些表多数跟装载和DLL动态链接有关,都很重要。通过解析DataDirectory结构就可以了解这些表的位置和长度

0x03 小结

介绍了Windows下的可执行文件和目标文件格式PE/COFF,与ELF文件很相似。COFF有个很有意思的段叫”.drectve段”,保存的是编译器传递给链接器的命令行参数,可以通过这个段实现指定运行库等功能。

下面即将进入有意思的动态链接与装载部分。。。

文章目录
  1. 1. 0x00 口胡
  2. 2. 0x01 PE的前身-COFF
    1. 2.1. IMAGE_FILE_HEADER
    2. 2.2. IMAGE_SECTION_HEADER
    3. 2.3. 黑魔法1-.drectve段
    4. 2.4. 黑魔法2-调试信息
    5. 2.5. COFF符号表
  3. 3. 0x02 Windows下的ELF-PE
    1. 3.1. IMAGE_DOS_HEADER的引导作用
    2. 3.2. IMAGE_NT_HEADERS
  4. 4. 0x03 小结