0

我正在尝试为我的计算机体系结构课程解决稍微修改的 Bomb Lab 问题。我应该为这些函数编写等效的 C 语言,但被困在第 5 阶段。这与这个问题非常相似,我确实已经弄清楚了该函数的大部分功能。

    105b:   56                      push   %esi
    105c:   53                      push   %ebx
    105d:   83 ec 10                sub    $0x10,%esp
    1060:   e8 6b fa ff ff          call   ad0 <__x86.get_pc_thunk.bx>
    1065:   81 c3 fb 3e 00 00       add    $0x3efb,%ebx
    106b:   8b 74 24 1c             mov    0x1c(%esp),%esi
    106f:   56                      push   %esi
    1070:   e8 bf 02 00 00          call   1334 <string_length>
    1075:   83 c4 10                add    $0x10,%esp
    1078:   83 f8 06                cmp    $0x6,%eax
    107b:   75 2e                   jne    10ab <phase_5+0x50>
    107d:   89 f0                   mov    %esi,%eax
    107f:   83 c6 06                add    $0x6,%esi
    1082:   b9 00 00 00 00          mov    $0x0,%ecx
    1087:   0f b6 10                movzbl (%eax),%edx
    108a:   83 e2 0f                and    $0xf,%edx
    108d:   03 8c 93 00 da ff ff    add    -0x2600(%ebx,%edx,4),%ecx
    1094:   83 c0 01                add    $0x1,%eax
    1097:   39 f0                   cmp    %esi,%eax
    1099:   75 ec                   jne    1087 <phase_5+0x2c>
    109b:   83 f9 34                cmp    $0x34,%ecx
    109e:   74 05                   je     10a5 <phase_5+0x4a>
    10a0:   e8 38 05 00 00          call   15dd <explode_bomb>
    10a5:   83 c4 04                add    $0x4,%esp
    10a8:   5b                      pop    %ebx
    10a9:   5e                      pop    %esi
    10aa:   c3                      ret    
    10ab:   e8 2d 05 00 00          call   15dd <explode_bomb>
    10b0:   eb cb                   jmp    107d <phase_5+0x22>

它是一个接受 6 个字符的字符串的函数(如果没有,炸弹就会爆炸)并执行某种形式的循环算法来产生一个数字。最后,如果循环结果不等于 52 (0x34),则炸弹再次爆炸。但是,我无法理解代码的某个部分:

    108d:   03 8c 93 00 da ff ff    add    -0x2600(%ebx,%edx,4),%ecx

显然,它通过某种未知算法屏蔽字符串中每个字符的 ASCII 等价物来抵消您获得的数字。现在,我已经为每个字符制作了一个偏移量表,并设法获得了一个可接受的字符串,aaaabb但我想知道代码的 C 等效项是什么样的。

4

1 回答 1

1

就像在 Jester 的回答中一样,它正在索引一个数组。 ecx += table[edx],static int table[]; 因为是 4,所以 EDX 索引在寻址模式中按 4 缩放sizeof(int);asm 需要字节偏移,C 索引使用元素偏移。


-0x2600 + %ebx是一个静态数组,与0x804a4a0链接问题中的相同。但在静态反汇编中更难找到,因为创建此可执行文件的人烦人地将其编译为 32 位 PIE(与位置无关的可执行文件)。

32 位 PIC / PIE 很糟糕,因为 PC 相对寻址是 x86-64 的新功能,所以这对于逆向工程来说是不必要的复杂。

它将 GOT(全局偏移表)地址获取到 EBX:首先call __x86.get_pc_thunk.bx在 EBX 中返回其返回地址,即0x1065使用您从中获得的占位符地址objdump -d。然后add $0x3efb,%ebx将该位置的偏移量添加到 GOT。

然后静态数据相对于 GOT 基础进行寻址(在本例中为 EBX)。痛苦地跟随它与绝对地址。0x1000在内核的程序加载器将代码映射到某个虚拟地址(除了)之后,您可以在正在运行的进程中单步执行调试器。

或者手动操作:0x1065 + 0x3efb= GOT base (EBX) of 0x4f60.
0x4f60-0x2600是查找表数组的开始:(0x2960如果您也objdump -D用于转储数据部分)。 您可能可以使用 GDB 中的该地址(之前 startrun)与x命令一起以方便的格式转储表,而不是将数据假反汇编为来自 objdump 的代码。

正在运行的进程中的实际地址将是该地址加上 4096 (0x1000) 的某个倍数。

于 2020-10-29T21:11:41.643 回答