PE的基本概念
PE文件将可执行程序分为不同的块,区块中包含代码和数据,各个区块按页边界对齐。区块没有大小限制,是一个连续的结构。每个块都有他自己在内存中的一套属性,例如这个块是否包含代码,是否只读或可读/写等。
基地址(ImageBase)
PE文件通过Windows加载器加载入内存。
模块(Module):内存中的版本。
模块句柄(hModule):映射文件的起始地址(这个地址也可以称为是基地址ImageBase),可以通过模块句柄访问其他的数据结构。
内存中的模块代表进程将这个可执行文件所需的代码、数据、资源、输入表、输出表及其他有用的数据结构所使用的内存都放到一个连续的内存块中,程序员只需要知道装载程序文件映像到内存后的及地址即可。
EXE文件的默认基地址是400000h、DLL文件的默认基地址是10000000h。可以在文件生成时改变。
GetModuleHandle函数
函数功能:获取一个可执行文件或DLL文件被加载到进程地址空间的地址
HMODULE GetModuleHandle(LPCTSTR lpModuleName);
参数为dll文件的名字,返回dll文件的地址空间的地址。
如果传入参数为NULL则返回调用该函数的文件的基地址。
虚拟地址(VA)
在Windows系统中,PE文件被系统加载映射到内存中,每个程序都有自己的虚拟空间,这个虚拟空间的内存地址称为虚拟地址(Virtual Address VA)。
相对虚拟地址(RVA)
虚拟地址(VA)=基地址+相对虚拟地址(RVA)
文件偏移地址
PE存储在磁盘中时,某个数据相对于文件头的偏移量称为文件偏移地址(File Offset)或物理地址(RAW Offset)。
MS-DOS头部
PE文件从DOS开始执行。
其中e_magic是MZ,是MS—DOS创始人之一Mark Zbikowski名字的缩写。
e_lfanew 是PE文件头偏移量,它采用的是Little—Endian类。
PE文件头
PE文件头(PNTHeader)
PNTHeader=ImageBase+dosHeader->e_lfanew
IMAGE_NT_HEADER
Signature字段
Signature字段是0x00004550,ASCII是“PE00”。
IMAGE_FILE_HEADER结构
- Machine:可执行文件的目标CPU类型
- NumberOfSections:区块的数目
- TimeDateStamp:文件创建时间(GMT秒数)
- PointerToSymbolTable:COFF符号表的文件偏移位置。(可能有可能没有,没有则为0)
- NumberOfSymbols:如果有COFF符号表,它代表其中的符号数目。
- SizeOfOptionalHeader:表示数据的大小(32位文件>=00E0h,64位文件>=00F0h)
- Characteristics:文件属性。
IMAGE_OPTIONAL_HEADER结构
虽然IMAGE_OPTIONAL_HEADER是可选头,但IMAGE_FILE_HEADER结构不够定义PE文件属性,所以IMAGE_OPTIONAL_HEADER是不可或缺的。
可选映像头定义了很多数据,他与IMAGE_FILE_HEADER连起来就是一个完整的"PE文件头结构"。
采用LordPE工具可以查看PE结构。
数据目录表
区块
在PE文件头与原始数据之间存在一个区块表。区块表周昂包含每个块在映像中的信息,分别指向不同的区块实体。
区块表
在IMAGE_NT_HEADERS后面是区块表,他是一个IMAGE_SECTION_HEADER结构数组。每个IMAGE_SECTION_HEADER结构包含所关联的区块的信息,例如位置、长度、属性,该数组的数目由IMAGE_NT_HEADERS.FileHeader.NumberOfSections指出。
常见区块与区块合并
区块中数据逻辑通常是关联的。PE文件一般有两个区块,一个是代码块,一个是数据块。以下是常见区块
连接器具有合并区块的特性,如果两个区块有相似或一致的属性,那么就能合并成一个区块。合并区块的好处是节省空间。减少内存页的使用。
区块的对齐值
区块在内存中、磁盘里都需要对齐,FileAlignment定义了磁盘区块的对齐值,SectionAlignment定义了内存中区块的对齐值
文件偏移与虚拟地址转换
文件偏移地址(File Offset)=相对虚拟地址(RVA)-k
输入表
可执行文件使用来自其他DLL的代码或数据的动作称为输入。当PE文件被载入时,Windows加载器的工作时定位所有被输入的函数和数据,并让正在载入的文件可以使用那些地址。
输入函数的调用
输入函数(Import Functions):输入函数是被程序调用但其执行代码不在程序中的函数。
输入表的结构
在PE文件头的可选映像头中,数据目录表的第二个成员指向输入表。输入表以IMAGE_IMPORT_DESCRIPTOR(IID)数组开始。
IID结构
** 输入地址表**
输入表实例分析
输出表
DLL创建时,就创建了一组能被EXE,DLL调用的函数,当DLL被另一个EXE或DLL文件使用时,他就被输出了。
输出表结构
IMAGE_EXPORT_DIRECTORY(IED)
输出地址表(EAT)
输出表实例分析
基地址重定位
当PE文件将默认值作为基地址载入,不需要基地址重定位。但当PE文件被载入到虚拟内存的另一个地址中,那么就要进行重定位。
基地址重定位的概念
由于DLL文件会被其他文件引用,所以DLL文件需要重定位。
基地址重定位表的结构
基地址重定位表实例分析
资源
Windows程序的各种界面称为资源,包括加速键、位图、光标、对话框、图标、菜单、串表、工具栏和版本信息等。
资源结构
资源用类似磁盘目录结构的方式保存,目录包含三层。第一层为根目录,每个根目录下的条目总是在它自己权限下的一个目录。
- 资源目录结构
IMAGE_DIRECTORY_ENTRY_RESOURCE条目中包含资源的RVA和大小。
IMAGE_RESOURCE_DIRECTORY结构
2. 资源目录入口结构
- 资源数据入口
资源结构实例分析