文档01—-PE文件格式

此文档只是记录,加深记忆所用

PE文件的基本概念

1、PE文件的框架结构图示
2、专有术语:

  • 模块(Moudule):PE文件通过Windows加载器被装入内存后,内存中的版本就称为模块
  • 模块句柄(hMoudule):映射文件的起始地址
  • 基地址(ImageBase):初始内存地址
  • 相对虚拟地址(RVA【Relative Virtual Address】):相对内存文件起始地址的偏移量

虚拟地址(VA)【也是实际的内存地址】= ImageBase + RVA

  • 文件偏移地址(File Offset)& 物理地址(RVA Offset):PE文件存储在磁盘上时,某个数据位置相对于文件头的偏移量

分块解释PE文件的结构

文件从磁盘中映射到内存中

MS-DOS头部

DOS头部由两部分组成:

  • DOS_HEADER
  • DOS_STUB
    在这里插入图片描述

DOS头部可以判断是否为有效执行体
其中有两个字段很重要
1、e_magic :字段(一个字的大小)需要被设置为值5A4Dh 它的ASCII值为 “MZ”
2、e_lfanew: 其是真正PE文件头相对偏移(RVA),其指出真正的PE文件头的偏移位置,占用4个字节,位于文件偏移3Ch字节中】
注意:Intel CPU属于little-endian类 字符存储时,低位在前高位在后(磁盘里面的存储)

PE文件头
  • PE Header 紧随DOS stub之后,是IMAGE_NT_HEADERS的简称

获取PE 文件头的指针
PNTHeader = ImageBase + dosHeader->e_lfanew

  • IMAGE_NT_HEADER由三部分组成
  • 1、Signature(PE文件标识)

在有效的PE文件里,Signature字段为00004550h,ASCII码字符是“PE00”,‘PE00’是文件头的开始,DOS中的e_lfanew就是指向“PE00”

  • 2、IMAGE_FILE_HEADER(映像文件头)

其中包含PE文件中的一些信息,最重要的是指出了IMAGE_OPTIONAL_HEADER的大小


3、IMAGE_OPTIONAL_HEADER(可选映像头)

fileheader和optonalheader共同构成PE文件头结构

  • 在这里插入图片描述

两个重要的对齐
1、SectionAlignment :当被装入内存时的区块对齐大小(ox1000h整数倍)
2、FileAlignment : 磁盘上PE文件内的区块对齐大小
SizeofImage: 映像装入内存之后的总尺寸

  • 可从图中看出SectionAlignmen、FileAlignment的大小在这里插入图片描述
  • 也可以看出文件偏移与虚拟地址转换

Fie OffSet = RVA - 差值K
file offset = VA - imageBase - 差值K

  • DataDirectory[]:数据目录表,有数个相同的IMAGE_DATA_DIRECTORY结构构成,指向输出表,输入表、资源块等数据
    在这里插入图片描述
  • PE文件中定位输出表、输入表和资源等重要数据时,就是从IMAGE_DATA_GIRTECTORY结构开始的。
区块表(Section Table)

区块表紧随IMAGE_NT_HEADERS之后,是一个IMAGE_SECTION_HEADER结构数组
其结构定义如下:在这里插入图片描述

VirtualSize:指出实际的。被使用的区块的大小,是区块在没对齐处理前的实际大小
VirtualAddress:该块装载到内存中的RVA,其数值总是sectionalignment的整数倍
sizeofrawdata:该块在磁盘文件中所占大小
pointertorawdata:该块在磁盘文件中的偏移,这个字段用于给出原始数据在文件中的偏移【字母大小写忽略】
characteristics:块属性(代码/数据/可读/可写等

  • 块属性

.text 默认的代码区块
.data默认的读/写数据区块,全局变量、静态变量一般放在这里
.rdata :默认的只读数据区块
.idata : 包含其他外来的DDL的函数及数据信息,即输入表
== .edata==: 输出表
.rsrc :资源
.reloc : 可执行文件的基址重定位

输入表(import Table 简称IT 也叫导入表)

  • 可执行文件使用来自其他的DLL的数据或函数时,称为输入
  • 输入函数(import function) : 就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码是位于相关的DLL文件中,在调用者程序中只保留相关的函数信息,如函数名、DLL文件名等。对于在磁盘上的PE文件来说,它无法得知这些输入函数在内存中的地址,只有当PE文件被装入内存后,Windows加载器才将相关的DLL装入,并将调用函数的指令和函数实际所处的地址联系起来。.
  • 调用DLL时有两种过程:
    1、隐式链接,这个过程完全由WIndows加载器完成
    2、显式链接,意味着必须确定目标DLL已经被加载,然后通过调用LoadLibrary和getprocaddress来寻找API的地址。
  • 输入表地址(Import Address Table简称 IAT) :每一个被引入的API在IAT中都有它自己要保留的位置,在那里它将被Windows加载器写入输入函数的地址。
输入表结构
  • 数据目录表中的第二成员指向输入表,第一成员指向输出表
  • 输入表以一个IMAGE_IMPORT_DESCRIPTOR(简称IID)的数组开始
  • 每个被PE文件隐式链接进来的DLL都有一个IID
  • IDD结构如下:在这里插入图片描述
    在这里插入图片描述

Original FirstThunk(Characterristics):包含指向输入名称表(简称INT)的RVA
FirstThunk: 包含指向输入地址表(IAT)的RVA

输入地址表(IAT) 在这里插入图片描述

PE装载器首先搜索Original FirstThunk,如果找到,加载程序迭代搜索数组中的每个指针,找到每个IMAGE_IMPORT_BY_NAME结构所指向的输入函数的地址,然后加载器用函数真正入口地址来替代由FirstThunk指向的IMAGE_THUNK_DATA数组中的元素。故此时,程序依靠IAT提供的函数地址就可以正常运行了啦。

输出表(Import Table)
  • 当一个DLL函数能被另一个DLL文件或EXE使用时,它就被称为输出了(exported)。其中输出信息被保存在输出表中,DLL文件通过输出表向系统提供函数输出函数名、序号和入口地址等信息。
  • 输出表是数据目录表中第一个成员,指向IMAGE_EXPORT_DIRECTORY(简称IED)在这里插入图片描述
  • 相关术语解释如下:
    在这里插入图片描述
基址重定位

在这里插入图片描述

差值 = 870000h-400000 = 470000(加载器会比较基址和实际装入地址1,计算出一个差值)
402000 + 470000 = 872000
403030 + 470000 = 873030

基址重定位结构定义
  • 基址重定位表(Base Relocation Table)位于 .reloc的区块 中,通过IMAGE_DIRECTORY_ENTRY_BASERELOC条目来找到它们。
  • IMAGE_BASE_RELOCATION结构由三部分构成在这里插入图片描述

1、VirtualAddress是这一组重定位数据开始的RVA地址。各重定位项的地址加上这个值才是该重定位项完整的RVA地址。
2、SizeofBlock 是当前重定位结构的大小,因为VirtualAddress和SizeofBlock 的大小都是固定的·4个字节,故这个项减去8,就是Typeoffset的大小。
3、Typeoffset是一个数组,数组每一项的大小为两个字节,共16位。又分为高4位(代表重定位类型),低12位(重定位地址)加上VirtualAddress即是指向PE映像中需要修改的的地址数据的指针。

实例分析

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值