PE文件格式
名词
入口点:PE文件执行时的入口点,也就是程序执行的第一行代码
文件偏移地址:磁盘上的PE文件,各数据的地址称做文件偏移地址。文件偏移地址从PE文件第一个字节开始计数,起始为0
相对虚拟地址:某一虚拟地址(VA) = 基地址(ImageBase) + 相对虚拟地址(RVA)
文件格式
MS-DOS头
DOS头是用来兼容MS-DOS操作系统的,目的是当这个文件在MS-DOS上运行时提示一段文字,大部分情况下时:This program cannot be run in DOS mode.
DOS头还有一个作用,就是指明PE头在文件中的位置。
每一个PE文件都是以一个DOS程序开始的,一般不需要额外关注
PE文件头(NT头)
NT头( IMAGE_NT_HEADERS )包含windows PE文件的主要信息,其中包括一个‘PE’字样的签名,PE文件头(IMAGE_FILE_HEADER)和PE可选头(IMAGE_OPTIONAL_HEADER32)
PE头包含许多PE装载器用到的重要字段。PE装载器将从IMAGE_DOS_HEADER结构中的 e_lfanew 字段里找到 PE Header的起始偏移,再加上基址得到PE文件头的指针
PNTHeader = ImageBase + DosHeader->e_lfanew
区块表
区块表时PE文件后续区块的描述,Windows根据节表的描述加载每个区块
区块表中有
- .text段
- .rdata段
- .data段
对于每一个段,在文件偏移处读取大小为SizeofData段块
这块数据会被加载到地址为imageBase+VirtualAddress。大小为VirtualSize的内存块中,并标记特定的Characteristics
区段名含义
区段名 | 含义 |
---|---|
.text | 代码 |
.data | 初始化数据 |
.rdata | Const/read-only(and initialized)data |
.idata | 包含其他外来DLL的函数及数据信息,即输入表 |
.edata | 输出表 |
.rsrc | 包含模块的全部资源,如图标,菜单,位图等 |
.reloc | 重定位表(装在进程的进程地址空间) |
.tls | 线程本地化储存 |
.bss | 未初始化数据 |
PE文件装在过程
加载过程
-
头部
- 解析DOS头部
- 解析PE头部(它的偏移是Dos中的e_lfanew)
- 解析可选头部(位置在PE头部后面)
-
段表
解析段表(位置:可选头部的偏移+SizeOfOptionalHeader)
-
映射
文件映射带内存中
-
导入表
- 解析数据目录
- 解析导入表
-
执行
内存映像
每个程序载入内存后都会包含 .text, .data, .stack, .heap这四个区段
-
程序代码放在 .text 段中
-
全局数据存放在 .data 段中
-
stack 存放一些本地变量和函数参数
-
heap 则是一段可扩展的内存区段, 无论何时程序需要使用更多内存空间时, 都可以使用 heap