为什么在反汇编位置无关代码中有绝对 jmps?

逆向工程 部件 操作系统 男子气概 苹果系统 馅饼
2021-07-03 02:21:12

我在玩 Hopper 并且正在查看otool报告为具有PIE标志的二进制文件的反汇编

我的理解是,因此,可执行基地址将被随机化,因此跳转必须相对于当前指令指针。

然而,在 Hopper 中查看这个 PIE 二进制文件的输出,我看到绝对跳跃是这样的:

00000001000021df    mov      rbx, rax
00000001000021e2    test     rbx, rbx
00000001000021e5    je       0x1000021c0

假设文本段加载在 的标准虚拟地址处0x100000000Hopper 是否只是将相对跳转转换为绝对跳转,或者我是否缺少关于位置无关可执行文件如何工作的概念?

2个回答

正如您在评论中提到的,对应的操作码je 0x1000021c074 D9. 因此,毫无疑问,您正面临一个相对的 JMP。Hopper 正在翻译相关的 JMP,因此逆向工程师可以更轻松地理解代码流,而无需计算地址。

我将通过一个使用radare2 的简单示例来演示Hopper 的作用(尽管您可以使用自己喜欢的工具来做同样的事情)。

首先,我们将打开radare2,并在rwx权限中分配10000个空字节,因此我们将有一个“沙箱”可以玩:

$ r2 malloc://10000

由于我们的基地址是0x00000000我们将寻求(转到),0x000021e5因此我们更容易看到相对跳转:

[0x00000000]> s 0x21e5
[0x000021e5]>

看看我们现在的地址是怎么变成的0x21e5好的 !

现在,让我们将十六进制字节 ( 74 d9)写入当前地址:

[0x000021e5]> wx 74d9

并反汇编此地址中的一条指令:

[0x000021e5]> pd 1
        ╰─< 0x000021e5      74d9           je 0x21c0

如您所见,radare2 与 Hopper 一样,将地址跳转转换0x????21e5je 0x????21c0.

好吧,megabeets 更快,这里是如何在 windbg 中检查它

0:000> ? .
Evaluate expression: 1999570342 = 772f05a6
0:000> EB . 74 D9
0:000> U . L1
ntdll!LdrpDoDebuggerBreak+0x2c:
772f05a6 74d9            je      ntdll!LdrpDoDebuggerBreak+0x7 (772f0581)
0:000> ? 772F0581 - .
Evaluate expression: -37 = ffffffdb
0:000> ? 21E5-21C0
Evaluate expression: 37 = 00000025
0:000>