12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 286|回复: 0

PE文件格式详细解析(六)-- 基址重定位表(Base Relocation Table)

[复制链接]
发表于 2020-9-17 18:06:19 | 显示全部楼层 |阅读模式
PE文件格式详细解析(六)-- 基址重定位表(Base Relocation Table)

一、PE重定位

向进程的虚拟内存加载PE文件时,文件会被加载到PE头的ImageBase所指的地址处。如果是加载的DLL(SYS)文件,且在ImageBase位置处已经加载了DLL(SYS)文件,那么PE装载器就会将其加载到其他未被占用的空间。此时就会发生基址重定位。
使用SDK或VC++创建PE文件,EXE默认的ImageBase为00400000,DLL默认的ImageBase为10000000,使用DDK创建的SYS文件默认的ImageBase为10000。
创建好进程后,因为EXE文件会起首加载进内存,所以EXE文件中无需考虑基址重定位标题。但是需要考虑ASLR(地址随机化)。对于各OS的主要体系DLL,微软会根据不同版本分别赋予不同的ImageBase地址,例犹如一体系的kernel32.dll和user32.dll等会被加载到自身固有的ImageBase,所以体系的DLL实际上也不会发生重定位标题。
二、PE重定位时发生了什么

以下以书上步伐为例(书上是以exe文件举例,纯粹是举例,实际环境中基址重定位多发生在DLL文件中)。

  • 基本信息:
    如下图所示,其ImageBase为01000000

  • 使用OD运行,观察内存:
    下图是步伐的EP代码部分,因为ASLR的缘故原由,步伐被加载到00270000处。

    从图中可以看出,红框内进程的内存地址是以硬编码的方式存在的,地址2710fc、271100是.text节区的IAT区域,地址27c0a4是.data节区的全局变量。因为ASLR的存在,每次在OD中重启步伐,地址值就会随加载地址的不同而发生变化,这种使硬编码在步伐中的内存地址随当前加载地址变化而改变的处理过程就是PE重定位。
    将以上两个图举行对比整理,数据如下表所示:
    文件(ImageBase:01000000)进程内存(加载地址:00270000)0100010fc002710fc01001100002711000100c0a40028c0a4即:因为步伐无法猜测会被加载到哪个地址,所以记载硬编码地址时以ImageBase为准;在步伐运行书简,经过PE重定位,这些地址全部以加载地址为基准举行变换,从而保证步伐的正常运行。
三、PE重定位操作原理

1. 基本操作原理


  • 在应用步伐中查找硬编码的地址位置
  • 读取数值后,减去ImageBase(VA->RVA)
  • 加上实际加载地址(RVA->VA)
上面三个步骤即可完成PE重定位,此中最关键的是查找硬编码地址的位置,查找过程中会使用到PE文件内部的Relocation Tables(重定位表),它记载了硬编码地址便宜,是在PE文件构建中的编译/链接阶段提供的。通过重定位表查找,本质上就是根据PE头的“基址重定位表”项举行的查找。

如上图所示,红框内的硬编码的地址都需要经过重定位再加载到内存中。
2. 基址重定位表

位于PE头的DataDirectory数组的第六个元素,索引为5.如下图所示:

上图中的基址重定位表的RVA为2f000,查看该地址处内容:


3. IMAGE_BASE_RELOCATION结构体

上图中详细罗列了硬编码地址的偏移,读取该表就可以获得准确的硬编码地址偏移。基址重定位表是IMAGE_BASE_RELOCATION结构体数组。
其定义如下:
typedefine struct _IMAGE_BASE_RELOCATION{                DWORD                VirtualAddress;        //RVA值                DOWRD                SizeOfBlock;                //重定位块的大小                //WORD TypeOffset[1];                //以注释形式存在,非结构体成员,表示在该结构体下会出现WORD范例的数组,并且该数组元素的值就是硬编码在步伐中的地址偏移。}IMAGE_BASE_RELOCATION;tydefine IMAGE_BASE_RELOCATION UNALIGEND * PIMAGE_BASE_RELOCATION;4. 基地址重定位表的分析方法

下表列出上图中基址重定位表的部分内容:
RVA数据注释2f00000001000VirtualAddress2f00400000150SizeOfBlock2f0083420TypeOffset2f00a342dTypeOffset2f00c3436TypeOffset以VirtualAddress=00001000,SizeOfBlock=00000150,TypeOffset=3420为例。
TypeOffset值为2个字节,由4位的Type与12位的Offset合成:
范例(4位)偏移(12位)3420高4位指定Type,PE文件中常见的值为3(IMAGE_REL_BASED_HIGHLOW),64位的PE文件中常见值为A(IMAGE_REL_BASED_DIR64)。低12位位真正位移(最大地址为1000),改位移是基于VirtualAddress的位移,所以步伐中硬编码地址的偏移使用以下公式举行盘算:
VirtualAddress(1000) + Offset(420) = 1420(RVA)
下面我们在OD中看一下RVA 1420处是否实际存在要执行PE重定位操作的硬编码地址:

步伐加载的基地址为270000,所以在271420处可以看到IAT的地址(VA,2710c4)。
5. 总结流程


  • 查找步伐中硬编码地址的位置(通过基址重定位表查找)

    可以看到,RVA 1420处存在着步伐的硬编码地址010010c4
  • 读取数值后,减去ImageBase值:
    010010c4 - 01000000 = 000010c4
  • 加上实际加载地址
    000010c4 + 00270000=002710c4
对于步伐内硬编码的地址,PE装载器都做如上的处理,根据实际加载的内存地址修正后,将得到的值覆盖到同一位置上。对一个IMAGE_BASE_RELOCATION结构体的全部TypeOffset都做如上处理,且对RVA 1000~2000地址区域对应的全部硬编码地址都要举行PE重定位处理。如果TypeOffset值为0,说明一个IMAGE_BASE_RELOCATION结构体竣事。至此,完成重定位流程。
四、参考

《逆向工程核心原理》

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-5-20 03:52 , Processed in 0.125976 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表