1 概论
看历史;COM文件,EXE文件,LE格式的可执行文件(Linear executable/线性可执行文件),Windows 9x中的VxD驱动程序也使用LE格式,因为这些驱动程序中也同时包括16位和32位代码。
而在Windows 9x,Windows NT,Windows 2000下,纯32位的可执行文件都使用微软设计的一种新的文件格式——PE格式(Portable Executable File Format/可移植的执行体)。
PE文件的基本结构如图17.1所示,在PE文件中,代码、已初始化的数据、资源和重定位信息等数据被按照属性分类放到不同的节(Section)中,而每个节的属性和位置等信息用一个IMAGE_SECTION_HEADER结构来描述,所有的IMAGE_SECTION_HEADER结构组成一个节表(Section Table),节表数据在PE文件中被放在所有节数据的前面。我们知道,Win32中可以对每个内存页分别指定可执行、可读写等属性,PE文件将同样属性的数据分类放在一起是为了统一描述这些数据装入内存后的页面属性。
由于数据是按照属性在节中放置的,不同用途但是属性相同的数据(如导入表、导出表以及.const段指定的只读数据)可能被放在同一个节中,所以PE文件中还用一系列的数据目录结构IMAGE_DATA_DIRECTORY来分别指明这些数据的位置,数据目录表和其他描述文件属性的数据合在一起称为PE文件头,PE文件头被放置在节和节表的前面。
上面介绍的这些部分是PE文件中真正用于Win32的部分,为了与DOS系统的文件格式兼容,在这部分的前面又加上了一个标准的DOS MZ格式的可执行部分,所有这些部分合起来组成了现在使用的PE文件。下面分别介绍这些组成部分。
PE文件中的DOS部分由MZ格式的文件头和可执行代码部分组成,可执行代码被称为“DOS块”(DOS stub)。一般来说,DOS部分的执行代码只是简单地显示一个“This program cannot be run in DOS mode.”就退出了,这段简单的代码是编译器自动生成的。
MZ格式的文件头由IMAGE_DOS_HEADER结构定义:
_IMAGE_DOS_HEADER = packed record { DOS .EXE header }
e_magic: Word; { Magic number }
e_cblp: Word; { Bytes on last page of file }
e_cp: Word; { Pages in file }
e_crlc: Word; { Relocations }
e_cparhdr: Word; { Size of header in paragraphs }
e_minalloc: Word; { Minimum extra paragraphs needed }
e_maxalloc: Word; { Maximum extra paragraphs needed }
e_ss: Word; { Initial (relative) SS value }
e_sp: Word; { Initial SP value }
e_csum: Word; { Checksum }
e_ip: Word; { Initial IP value }
e_cs: Word; { Initial (relative) CS value }
e_lfarlc: Word; { File address of relocation table }
e_ovno: Word; { Overlay number }
e_res: array [0..3] of Word; { Reserved words }
e_oemid: Word; { OEM identifier (for e_oeminfo) }
e_oeminfo: Word; { OEM information; e_oemid specific}
e_res2: array [0..9] of Word; { Reserved words }
_lfanew: LongInt; { File address of new exe header }
end;
TImageDosHeader = _IMAGE_DOS_HEADER;
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;