您的位置:首页 > 其它

WINDOWS PE文件结构详细介绍(一)

2011-05-12 19:57 447 查看
因为我们现在的c++是在WIN32平台下面运行的,为了以后的学习,有必要先了解一下WINDOWS PE文件结构,这些相关资料来于< Delphi深入Windows编程>这本书。
PE的意思就是Portable Executable (可移值的执行体),是Win32环境自身所带的执行体文件格式。PE的一些特殊性继承自UNIX的COFF(Common Object File Format)文件格式。“Portable Executable”(可移值的执行体)意味着此文件格式是跨Win32平台的,即使Windows动作在非Intel的CPU上,任何Win32平台的PE装载器都能识别和使用该文件格式。当然移值到不同CPU上PE执行体必须会有一些改变。所有Win32执行体(除了VxD和16位的DLL)都使用PE文件格式,包括WindowsNT的内核模式驱动程序(Kernel Mode Drivers)。PE文件的结构如下:



下面来分析一下PE文件格式的总体层次分布。
(1)所有PE文件必须以一个简单的Dos Header(DOS文件头部) 开始,一旦程序在DOS下执行,DOS就能识别出这是有效的执行体,然后运行紧随Dos Header之后的DOS stub(DOS 插桩程序)。DOS stub实际上是个有效的DOS下的EXE代码,在不支持PE文件格式的操作系统中,将简单显示一个错误提示,类似于字符串“This program requires Windows”或者程序员可根据自己的意图实现完整的DOS代码。通常,简单调用中断21h服务9号子功能来显示字符串“This program cannot run is DOS mode”。

(2)紧接着DOS Stub的是PE Header(PE文件头部)。PE Header是PE相关结构IMAGE_NT_HEADER的简称,其中包含了许多PE装载器用到的重要域。在更加深入地研究PE文件格式后,本书将对这些重要域详细地解释。执行体在支持PE文件结构的操作系统中执行时,PE装载器将从DOS Header中找到PE Header的起始偏移量。因而跳过了DOS stub直接定位到真正的文件头PE Header。

(3)PE文件的真正内容划分成块,称为Sections(节)。每节是一块拥有共同属性的数据,例如代码/数据、读/写等。可以把PE文件想像成一个逻辑磁盘,PE Header是磁盘的Boot扇区,而Sections就是各种文件,每种文件自然就有不同属性如只读、系统、隐藏、文档等。值得注意的是,节的划分是基于各组数据的共同属性,而不是逻辑概念。所以,不必太关心节中类似于“data”、“code”或其他的逻辑概念,如果数据和代码拥有相同的属性,就可以被归入同一个节中,亦即节名称仅仅是个区别不同节的符号而已,“data”、“code”等的命名只为了便于识别,惟有节的属性决定了节的特性和功能。如果某块数据想赋为只读属性,就可以将该数据放入为只读的节中,当PE装载器映射节内容时,会检查相关节属性并置对应内存块为指定属性。

(4)如果将PE文件格式视为一个逻辑磁盘,PE Header是Boot扇区,而Sections是各种文件,但仍缺足够信息来定位磁盘上的不同文件。例如,什么是PE文件格式中等价于目录的东西?那就是PE Header接下来的数据结构Section Table(节表)。每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE文件里有5个字节,那么此结构数组内就有5个成员。因此,便可以把节表视为逻辑磁盘中的根目录,每个数组成员等价于根目录中的目录项。

以上就是PE文件格式的物理分布,下面总结一下装载PE文件的主要流程。
(1)当PE文件被执行,PE装载器检查DOS Header里面的PE Header偏移量。如果找到,则跳转到PE Header,否则提示这不是PE文件。
(2)PE装载器检查PE Header的有效性。如果有效,就跳转到PE Header的尾部。
(3)紧跳PE Header的是节表,PE装载器读取其中的节信息,并采用文件映射方法将这些节映射到内存,同时附上节表里指定的节属性。
(4)PE文件映射入内存后,PE装载器将处理PE文件中类似Import Table(引入表的逻辑部分。)

以上便是关于PE文件结构的介绍,下篇,我们将介绍,c++编译器是如何将c++的一些变量和代码组织到pe文件结构里面。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: