【发布时间】:2017-11-15 03:20:50
【问题描述】:
我对汇编比较陌生,遇到了一个让我难过的函数。在调试过程中,我发现 $rdi 寄存器最初设置为 0x55555575a1b8。本质上,我希望返回任何值,但不是负值或零。最初,似乎将 $esi 设置为 0x5575a1b8 会返回 0x1。实际上它返回-1。进一步检查发现有几个两个递归函数调用,每个都将返回值保存到寄存器中以供以后比较:
r12 = Find(*(rdi + 0x8), rsi);
rax = Find(*(rdi + 0x10), rsi);
在这之后,我迷失在代码中......
0000000000001b62 <Find>:
1b62: 48 85 ff test %rdi,%rdi
1b65: 74 3c je 1ba3 <Find+0x41>
1b67: 39 37 cmp %esi,(%rdi)
1b69: 74 3e je 1ba9 <Find+0x47>
1b6b: 41 54 push %r12
1b6d: 55 push %rbp
1b6e: 53 push %rbx
1b6f: 89 f5 mov %esi,%ebp
1b71: 48 89 fb mov %rdi,%rbx
1b74: 48 8b 7f 08 mov 0x8(%rdi),%rdi
1b78: e8 e5 ff ff ff callq 1b62 <Find>
1b7d: 41 89 c4 mov %eax,%r12d
1b80: 48 8b 7b 10 mov 0x10(%rbx),%rdi
1b84: 89 ee mov %ebp,%esi
1b86: e8 d7 ff ff ff callq 1b62 <Find>
1b8b: 45 85 e4 test %r12d,%r12d
1b8e: 7e 09 jle 1b99 <Find+0x37>
1b90: 43 8d 04 24 lea (%r12,%r12,1),%eax
1b94: 5b pop %rbx
1b95: 5d pop %rbp
1b96: 41 5c pop %r12
1b98: c3 retq
1b99: 85 c0 test %eax,%eax
1b9b: 7e 12 jle 1baf <Find+0x4d>
1b9d: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
1ba1: eb f1 jmp 1b94 <Find+0x32>
1ba3: b8 ff ff ff ff mov $0xffffffff,%eax
1ba8: c3 retq
1ba9: b8 01 00 00 00 mov $0x1,%eax
1bae: c3 retq
1baf: b8 ff ff ff ff mov $0xffffffff,%eax
1bb4: eb de jmp 1b94 <Find+0x32>
非常感谢任何对该方法行为的洞察。
【问题讨论】:
-
0x55555575a1b8看起来像是在 Linux 上使用 ASLR 的与位置无关的可执行文件中指向静态数据的指针(因此每次运行程序时它都可能不同)。例如如果您在gdb中运行程序并在某处设置断点,则代码地址也将是0x555...。如果这是一个二进制炸弹,那么使用-pie构建它(这些天在某些发行版中默认在 gcc 中启用)可能会更令人困惑,因为反汇编地址与运行时不匹配。