所以我正在做一个二元炸弹作业,但陷入了困境。尝试查看其他问题和指南,但我的问题和指南似乎与我在网上找到的其他问题和指南中描述的完全不同。
该阶段仅需要 2 个无符号整数作为输入。这里它在以 11 2 作为输入运行后在 gdb 中被反汇编。
Dump of assembler code for function phase_5:
0x08048ccc <+0>: push %ebp
0x08048ccd <+1>: mov %esp,%ebp
0x08048ccf <+3>: push %esi
0x08048cd0 <+4>: push %ebx
=> 0x08048cd1 <+5>: sub $0x20,%esp
0x08048cd4 <+8>: lea -0x10(%ebp),%eax
0x08048cd7 <+11>: mov %eax,0xc(%esp)
0x08048cdb <+15>: lea -0xc(%ebp),%eax
0x08048cde <+18>: mov %eax,0x8(%esp)
0x08048ce2 <+22>: movl $0x8049b0a,0x4(%esp)
0x08048cea <+30>: mov 0x8(%ebp),%eax
0x08048ced <+33>: mov %eax,(%esp)
0x08048cf0 <+36>: call 0x8048788 <__isoc99_sscanf@plt>
0x08048cf5 <+41>: cmp $0x1,%eax
0x08048cf8 <+44>: jg 0x8048cff <phase_5+51>
0x08048cfa <+46>: call 0x80492b6 <explode_bomb>
0x08048cff <+51>: mov -0xc(%ebp),%eax
0x08048d02 <+54>: and $0xf,%eax
0x08048d05 <+57>: mov %eax,-0xc(%ebp)
0x08048d08 <+60>: cmp $0xf,%eax
0x08048d0b <+63>: je 0x8048d36 <phase_5+106>
0x08048d0d <+65>: mov $0x0,%ecx
0x08048d12 <+70>: mov $0x0,%edx
0x08048d17 <+75>: mov $0x8049960,%ebx
0x08048d1c <+80>: add $0x1,%edx
0x08048d1f <+83>: mov (%ebx,%eax,4),%eax
0x08048d22 <+86>: add %eax,%ecx
0x08048d24 <+88>: cmp $0xf,%eax
0x08048d27 <+91>: jne 0x8048d1c <phase_5+80>
0x08048d29 <+93>: mov %eax,-0xc(%ebp)
0x08048d2c <+96>: cmp $0xb,%edx
0x08048d2f <+99>: jne 0x8048d36 <phase_5+106>
0x08048d31 <+101>: cmp -0x10(%ebp),%ecx
0x08048d34 <+104>: je 0x8048d3b <phase_5+111>
0x08048d36 <+106>: call 0x80492b6 <explode_bomb>
0x08048d3b <+111>: add $0x20,%esp
0x08048d3e <+114>: pop %ebx
0x08048d3f <+115>: pop %esi
0x08048d40 <+116>: pop %ebp
0x08048d41 <+117>: ret
Run Code Online (Sandbox Code Playgroud)
对于 0x08048d17 <+75> 行:mov $0x8049960,%ebx
我用了
x/16b 0x8049960
gdb 它告诉我
0x8049960 数组.2954: 10 0 0 0 2 0 0 0
0x8049968数组.2954+8: 14 0 0 0 7 0 00
当我使用直到直到我完成该程序时
0x08048d31 <+101>: cmp -0x10(%ebp),%ecx
%edx = 11、%ecx = 82 和 %ebp-0x10 = 2(使用 print 获取前两个值,使用 x/d $ebp-0x10 获取最后一个值)
因为 82 != 2 它只是去调用explode_bomb。
据我了解,它正在读取我的 2 个数字,确保我在 <+41> 处输入了 2。然后它从数组中获取第一个数字(在本例中为 10)并将其放入 $eax 的 +=<+51> 处。然后它将 eax 放入 <+57> 处的 -0xc($ebp) 中。
然后它检查以确保 <+60> 处的 $eax 不是 15,然后将 $ecx 和 $edx 设置为 0。然后它将指向数组的指针传递给 <+75> 处的 $ebx。
然后它进入从 <+80> 到 <+91> 的循环,但我不确定它到底在做什么。我知道它会将 $edx 加 1,并且当 $eax 为 15 时退出循环,但我无法弄清楚其余的内容是如何工作的。
我对循环部分的理解正确吗?而且,如果有人不介意解释 <+80> 和 <+91> 之间发生的事情,我将非常感激。
ps 抱歉,如果我的格式错误。
然后它从数组中获取第一个数字(在本例中为 10)并将其放入 $eax 的 +=<+51> 处。
错误的。<+51>读取您输入的第一个数字,而不是数组中的第一个数字。然后通过丢弃最高位将其掩码到 0..15 范围内,并写回其来源的局部变量。eax当然,它也继续存在。
该数组包含 4 个字节整数,共有 15 个。因此,您可以使用 打印它x/15wd。
现在进入循环。edx显然只是跟踪迭代计数,这并不奇怪。<+83>有趣的部分是:它替换eax为当前索引所在的数组项的值eax。那是eax = array[eax]。ecx当然只是总结您访问过的数组元素,这又很简单。退出条件是当您点击值为 15 的数组项时。
归根结底,这个数组实际上是一个链表。列表的末尾标记为 15。您输入的第一个数字将用作列表遍历的起点。应该选择这样直到列表末尾为止有 11 个元素(请参阅<+96>)。第二个输入数字应等于访问的数组项的总和。