Assembly 二元炸弹-第4阶段
我有一个非常困难的时间来追踪以下二进制炸弹的汇编代码一个来自学校的作业,炸弹必须被拆除,这个炸弹包含6个阶段,所有阶段都有1个正确的输入,以进入下一阶段。我目前在第四阶段,它有一个名为func4的递归函数。我已经确定输入是%d%d,它是两个整数。然而,我不能完全弄清楚func4在做什么,即使在每一步都获得所有寄存器的信息之后 第四阶段:Assembly 二元炸弹-第4阶段,assembly,x86,gdb,reverse-engineering,Assembly,X86,Gdb,Reverse Engineering,我有一个非常困难的时间来追踪以下二进制炸弹的汇编代码一个来自学校的作业,炸弹必须被拆除,这个炸弹包含6个阶段,所有阶段都有1个正确的输入,以进入下一阶段。我目前在第四阶段,它有一个名为func4的递归函数。我已经确定输入是%d%d,它是两个整数。然而,我不能完全弄清楚func4在做什么,即使在每一步都获得所有寄存器的信息之后 第四阶段: (gdb) disas Dump of assembler code for function phase_4: => 0x08048e24 &l
(gdb) disas
Dump of assembler code for function phase_4:
=> 0x08048e24 <+0>: sub $0x2c,%esp
0x08048e27 <+3>: lea 0x1c(%esp),%eax
0x08048e2b <+7>: mov %eax,0xc(%esp)
0x08048e2f <+11>: lea 0x18(%esp),%eax
0x08048e33 <+15>: mov %eax,0x8(%esp)
0x08048e37 <+19>: movl $0x804a7f1,0x4(%esp)
0x08048e3f <+27>: mov 0x30(%esp),%eax
0x08048e43 <+31>: mov %eax,(%esp)
0x08048e46 <+34>: call 0x80488d0 <__isoc99_sscanf@plt>
0x08048e4b <+39>: cmp $0x2,%eax
0x08048e4e <+42>: jne 0x8048e5d <phase_4+57>
0x08048e50 <+44>: mov 0x18(%esp),%eax
0x08048e54 <+48>: test %eax,%eax
0x08048e56 <+50>: js 0x8048e5d <phase_4+57>
0x08048e58 <+52>: cmp $0xe,%eax
0x08048e5b <+55>: jle 0x8048e62 <phase_4+62>
0x08048e5d <+57>: call 0x8049470 <explode_bomb>
0x08048e62 <+62>: movl $0xe,0x8(%esp)
0x08048e6a <+70>: movl $0x0,0x4(%esp)
0x08048e72 <+78>: mov 0x18(%esp),%eax
0x08048e76 <+82>: mov %eax,(%esp)
0x08048e79 <+85>: call 0x8048dbb <func4>
0x08048e7e <+90>: cmp $0x25,%eax
0x08048e81 <+93>: jne 0x8048e8a <phase_4+102>
0x08048e83 <+95>: cmpl $0x25,0x1c(%esp)
0x08048e88 <+100>: je 0x8048e8f <phase_4+107>
0x08048e8a <+102>: call 0x8049470 <explode_bomb>
0x08048e8f <+107>: add $0x2c,%esp
0x08048e92 <+110>: ret
End of assembler dump.
职能4:
Breakpoint 2, 0x08048dbb in func4 ()
(gdb) disas
Dump of assembler code for function func4:
=> 0x08048dbb <+0>: sub $0x1c,%esp
0x08048dbe <+3>: mov %ebx,0x14(%esp)
0x08048dc2 <+7>: mov %esi,0x18(%esp)
0x08048dc6 <+11>: mov 0x20(%esp),%eax
0x08048dca <+15>: mov 0x24(%esp),%edx
0x08048dce <+19>: mov 0x28(%esp),%esi
0x08048dd2 <+23>: mov %esi,%ecx
0x08048dd4 <+25>: sub %edx,%ecx
0x08048dd6 <+27>: mov %ecx,%ebx
0x08048dd8 <+29>: shr $0x1f,%ebx
0x08048ddb <+32>: add %ebx,%ecx
0x08048ddd <+34>: sar %ecx
0x08048ddf <+36>: lea (%ecx,%edx,1),%ebx
0x08048de2 <+39>: cmp %eax,%ebx
0x08048de4 <+41>: jle 0x8048dfd <func4+66>
0x08048de6 <+43>: lea -0x1(%ebx),%ecx
0x08048de9 <+46>: mov %ecx,0x8(%esp)
0x08048ded <+50>: mov %edx,0x4(%esp)
0x08048df1 <+54>: mov %eax,(%esp)
0x08048df4 <+57>: call 0x8048dbb <func4>
0x08048df9 <+62>: add %eax,%ebx
0x08048dfb <+64>: jmp 0x8048e16 <func4+91>
0x08048dfd <+66>: cmp %eax,%ebx
0x08048dff <+68>: jge 0x8048e16 <func4+91>
0x08048e01 <+70>: mov %esi,0x8(%esp)
0x08048e05 <+74>: lea 0x1(%ebx),%edx
0x08048e08 <+77>: mov %edx,0x4(%esp)
0x08048e0c <+81>: mov %eax,(%esp)
0x08048e0f <+84>: call 0x8048dbb <func4>
0x08048e14 <+89>: add %eax,%ebx
0x08048e16 <+91>: mov %ebx,%eax
0x08048e18 <+93>: mov 0x14(%esp),%ebx
0x08048e1c <+97>: mov 0x18(%esp),%esi
0x08048e20 <+101>: add $0x1c,%esp
0x08048e23 <+104>: ret
End of assembler dump.
我希望很明显,phase4正在检查第一个数字是否在0..14范围内(包括0..14),请参见第+44..+57行
然后用三个参数调用func4:输入的第一个数字、0和14行+62..+85。接下来,它检查第+90行的返回值是否为0x25 37 decimal,并且输入的第二个数字是否也是第37行+95
让我们继续讨论函数4。我将这三个参数分别称为x,low和high。一开始你当然不知道它们是什么。行+23..+34计算高-低/2。令人难堪的混乱是因为编译器生成代码来处理截断为零的负数。不过,我们不会看到任何负数。第+36行只是一个奇特的加法,所以在ebx中我们现在有low+high-low/2,也就是两个数字的平均值。然后,代码将此平均值与作为第一个参数提供的数字x进行比较。如果xTL;DR:正确的输入应该是10和37,我也能确定int必须大于0,但除此之外我丢失了。这有帮助吗。在这里搜索二进制炸弹,或者只看右边的相关问题。------>如果我能在搜索中找到它,我不会问这个问题。哇,太棒了。你的解释把一切都说得很清楚。我看到了0-14的范围,但我不知道func4本身在做什么。我自己也看到了37,但我没有意识到这将是第二次输入。非常感谢好先生@佩特罗夫,你能解释一下你是怎么得到0-14分的吗?我很困惑。第52行,%eax