PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)。
PE文件大体结构如下图:
PE文件使用平面地址空间,代码数据组合在一起形成一个较大结构,文件的内容被分为不同的区块(secession),区块中包含代码和数据,各区块按页对齐,没有大小限制,每个块在内存有自身的属性,比如其中是否包含代码,是否只读或可写等。
PE文件并非作为单一文件被映射到内存中,由windows装载器决定PE文件的哪一部分被映射,映射是将文件较高偏移位置映射到较高位置的内存中,磁盘文件到内存的映射过程如下图:
基地址
PE文件装入内存后,内存中的文件被成为模块,映射文件在内存中的起始地址被称为模块句柄(hMoudle),可以通过模块句柄访问内存中的其他数据结构,这个初始内存即基地址(Imagebase)。
模块代表进程将这个可执行文件的代码、数据、资源、输入输出表及其他数据结构都放入到一个连续的内存中,程序员只需要知道基地址即可(有点像单向链表)。
虚拟地址
PE文件被映射到内存中的虚拟空间,在该空间中的地址为虚拟地址。
相对虚拟地址
尽管给PE文件分配了虚拟空间,但还有许多地方需要指定内存地址,比如全局变量的引用,虽然PE文件有基地址可以用于访问内存其他空间,但因为它可以访问内存任何地址(书上写的,不咋明白),所以需要一个不依赖PE载入地址的方法来指定地址。
为避免在PE文件中引入绝对地址,引入了相对虚拟地址,Relative Virual Address,简称RVA,表示此段代码在内存中相对于基地址的偏移,即:相对虚拟地址(RVA)=虚拟地址(VA)-基址(ImageBase)。
Q:基地址不是绝对地址吗,那么绝对地址加偏移地址不还是绝对地址吗?
文件偏移地址
PE文件存储在磁盘时,数据文件相对于文件头的偏移量。