所以我正在做一个二进制炸弹任务,被卡住了。尝试查看其他问题和指南,但是我的似乎与我在网络上发现的其他问题和指南中所描述的完全不同。
该阶段仅需输入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
对于行0x08048d17 <+75>:mov $ 0x8049960,%ebx
我用了
x / 16b 0x8049960
gdb,它告诉我
0x8049960 array.2954:10 0 0 0 2 0 0 0
0x8049968 array.2954 + 8:14 0 0 0 7 0 00
当我浏览程序时,使用直到直到
0x08048d31 <+101>:cmp -0x10(%ebp),%ecx
%edx = 11,%ecx = 82和%ebp-0x10 = 2(用于打印以获取前两个值,x / d $ ebp-0x10用于后一个值)
因为82!= 2,所以只需调用explode_bomb。
据我了解,它正在读取我的2个数字,请确保我在<+41>输入2。然后,它从数组中获取第一个数字(在本例中为10),并将其放入+ = <+ 51>的$ eax中。然后将eax放入<+57>的-0xc($ ebp)中。
然后检查以确保$ eax在<+60>处不是15,然后将$ ecx和$ edx设置为0。然后将指向数组的指针传递给<+75>处的$ ebx。
然后它进入从<+80>到<+91>的循环,但是我不确定它的实际作用。我知道它会使$ edx增加1,并且当$ eax为15时退出循环,但是我无法弄清楚其余的工作原理。
在循环部分之前,我是否正确理解它?而且,如果有人不介意解释<+80>和<+91>之间发生的事情,我将不胜感激。
ps对不起,如果我的格式错误。
然后,它从数组中获取第一个数字(在本例中为10),并将其放入+ = <+ 51>的$ eax中。
错误的。<+51>
读取你输入的第一个数字,而不是数组中的第一个数字。然后通过丢弃高位将其屏蔽到0..15范围,并将其写回到它来自的本地变量。eax
当然,它也存在于中。
该数组包含4个字节的整数,其中有15个整数。因此,你可以使用进行打印x/15wd
。
现在到循环。edx
显然只是跟踪迭代次数,这并不奇怪。<+83>
有趣的部分是:它替换eax
为eax
当前持有索引的数组项的值。那是eax = array[eax]
。ecx
当然只是总结你访问过的数组元素,这再简单不过了。退出条件是当你命中具有值15的数组项时。
归结为这个数组实际上是一个链表。列表的末尾用15标记。输入的第一个数字用作列表遍历的起点。应该选择它,直到列表末尾有11个元素(请参阅参考资料<+96>
)。第二个输入数字应等于访问的数组项的总和。
感谢您的解释,在阅读您的更正后设法使它起作用。
打扰一下!我发现这个答案很有帮助。但是,我仍然有一些疑问。首先,通过掩码,您的意思是程序将对我们的第一个输入应用掩码,对吗?如果是这样,以便能够遍历11个元素,那么当我们输入第一个输入器时,还应该首先使用mask进行计算,对吗?其次,例如,如果数组为[10、2、14、7、8、12、15、11、0、4、1、13、3、9、6、5],则使其遍历11元素并结束于15,我们必须从值为3的元素开始?如果我的问题不清楚,请让我知道。非常感谢!
我数的方法是12步,而不是11步,但我可能只差一个:)