流水账笔记:PE文件格式(重定位表)

来源:互联网 发布:苹果序列号查询软件 编辑:程序博客网 时间:2024/05/16 01:33

重定位表


为什么需要重定位表

如图所示,一个模块在调用 MessageBox 的过程中,传入了字符串,传入字符串的二进制为

68 00104000  

这段代码使用了绝对地址,即 代码定位到的地址 是固定的。

这里写图片描述

如果,该模块的 载入地址 发生了变化,那么 0x00401000 这个位置的数据,就不是我们所想要的了。此时就需要借助 重定位表,来帮助我们修改代码,将该代码定位到正确的位置。

如何修改代码

假设一个 dll 的 ImageBase = 0x10000000,有段字符串的地址为 0x10001000,dll 中有一段代码如下:

汇编代码:push 10001000 ;"hello, world" 字符串二进制:68 00100010 

如果该 dll 被一个程序加载后,其 ImageBase = 0x00400000,那么需要计算出,该字符串在内存中重新分配的地址:

字符串的新地址 = ImageBase(new) - ImageBase(old) + 字符串的旧地址0x00401000 = 0x00400000 - 0x10000000 + 0x10001000

于是就需要修改 00100010 这段代码,修改后:

汇编代码:push 0x00401000;"hello, world" 字符串二进制:68 00104000 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~↓ (方便自己理解的图:)

这里写图片描述
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

重定位表中记录的表项格式

重定位表中,为了节省空间,只用了 2 个字节来存储 修改信息,结构如下:

这里写图片描述

高两位记录了需要修改代码的位数:

值 修改代码 1 高 16 位 2 低 16 位 3 32 位

低 14 位记录了 需要修改的代码 的偏移位置。但是仅仅 14 位,可能无法定位到一段代码。所以,每段 修改信息 是按页来排列的。如在第一段数据中,计算代码位置时需要加上 0x1000 ;在第二段数据中,计算代码位置时需要加上 0x2000…

这里写图片描述

重定位表的一段数据,其结构体如下图:

这里写图片描述

第一个成员代表代码所在分页,第二个成员表示该分页中有多少代码需要修改;在文件中的结构如图, 蓝框 表示分页地址,紫框 表示需要修改的数量,绿框 里记录了需要修改的代码的信息:

这里写图片描述

原创粉丝点击