为了应用修正,增量计算为首选基地址与实际加载图像的基地址之间的差异。
基本思想是,当在某个地址进行修复时,我们必须知道
- 必须更改哪些内存(“偏移”字段)
- 重定位需要什么值(“delta”值)
- 要使用重定位数据和增量值的哪些部分(“类型”字段)
以下是“类型”字段的一些可能值
HIGH
- 将 delta 的高位字(16 位)添加到“偏移”处的 16 位值
LOW
- 将 delta 的较低字添加到“偏移”处的值
HIGHLOW
- 在“偏移”处将完整的增量添加到 32 位值
换句话说,HIGHLOW
类型告诉程序它正在从这个重定位块*的页面上修复偏移量“偏移量”,并且需要修改一个双字才能使可执行文件正常工作。
* 所有重定位条目都被分组到块中,每个块都有一个页面,在该页面上应用其条目
假设您的代码中有此指令:
section .data
message: "Hello World!", 0
section .code
...
mov eax, message
...
您运行汇编程序,然后立即运行反汇编程序。现在您的代码如下所示:
mov eax, dword [0x702000]
你现在很好奇为什么会这样0x700000
,当你查看文件转储时,你会看到
ImageBase: 0x00700000
现在您了解了这个数字是从哪里来的,并且您已经准备好运行可执行文件了。将可执行文件加载到内存并为它们创建地址空间的加载器发现,内存0x700000
不可用,它需要将该文件放在其他地方。它决定没0xf00000
问题并在那里复制文件内容。
但是,您的程序被链接为仅使用数据工作,0x700000
并且链接器无法知道其输出将被重新定位。正因为如此,装载机必须发挥它的魔力。它
- 计算增量值 - 旧地址(图像库)是
0x700000
但它想要0xf00000
(首选地址)。它从另一个中减去一个并得到0x800000
结果。
- 获取
.reloc
文件的部分
- 检查是否还有另一个页面(4KB 的数据)要重新定位。如果不是,它会继续调用文件的入口点。4.对于当前页面的每次重定位,它
- 在重定位偏移处获取数据
- 添加增量值(以类型字段状态的方式)
- 将新值放在重定位偏移处
- 继续第 3 步
还有更多类型的重定位条目,其中一些是特定于体系结构的。要查看完整列表,请阅读“Microsoft Portable Executable and Common Object File Format, section 6.6.2. Fixup Types”。