这只是文件的一个剪辑。这是炸弹中的关卡之一。每个级别都由用户的输入化解。我们应该解释反汇编的代码,以确定输入应该是什么。在此特定级别中,用户必须输入 5 个数字。提供 5 个数字后,将在此反汇编代码中检查它们。如果它们不起作用,那么炸弹就会爆炸。我已经完成了它,并提出了一些数字规则,但有些部分我很难解释。主要是在循环方面。
以下是反汇编的代码以供参考:
8048eae: 55 push %ebp
8048eaf: 89 e5 mov %esp,%ebp
8048eb1: 83 ec 28 sub $0x28,%esp
8048eb4: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp)
8048ebb: 8d 45 e4 lea 0xffffffe4(%ebp),%eax
8048ebe: 89 44 24 04 mov %eax,0x4(%esp)
8048ec2: 8b 45 08 mov 0x8(%ebp),%eax
8048ec5: 89 04 24 mov %eax,(%esp)
8048ec8: e8 69 06 00 00 call 8049536 <read_five_numbers>
8048ecd: 8b 45 e4 mov 0xffffffe4(%ebp),%eax
8048ed0: 83 f8 1a cmp $0x1a,%eax
8048ed3: 74 05 je 8048eda <level_3+0x2c>
8048ed5: e8 a6 10 00 00 call 8049f80 <explode_bomb>
8048eda: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
8048ee1: eb 2c jmp 8048f0f <level_3+0x61>
8048ee3: 8b 45 fc mov 0xfffffffc(%ebp),%eax
8048ee6: 8b 54 85 e4 mov 0xffffffe4(%ebp,%eax,4),%edx
8048eea: 8b 45 fc mov 0xfffffffc(%ebp),%eax
8048eed: 83 c0 01 add $0x1,%eax
8048ef0: 8b 44 85 e4 mov 0xffffffe4(%ebp,%eax,4),%eax
8048ef4: 39 c2 cmp %eax,%edx
8048ef6: 7f 05 jg 8048efd <level_3+0x4f>
8048ef8: e8 83 10 00 00 call 8049f80 <explode_bomb>
8048efd: 8b 45 fc mov 0xfffffffc(%ebp),%eax
8048f00: 8b 44 85 e4 mov 0xffffffe4(%ebp,%eax,4),%eax
8048f04: 0f af 45 fc imul 0xfffffffc(%ebp),%eax
8048f08: 01 45 f8 add %eax,0xfffffff8(%ebp)
8048f0b: 83 45 fc 01 addl $0x1,0xfffffffc(%ebp)
8048f0f: 83 7d fc 03 cmpl $0x3,0xfffffffc(%ebp)
8048f13: 7e ce jle 8048ee3 <level_3+0x35>
8048f15: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
8048f18: f7 d8 neg %eax
8048f1a: 3b 45 f8 cmp 0xfffffff8(%ebp),%eax
8048f1d: 74 05 je 8048f24 <level_3+0x76>
8048f1f: e8 5c 10 00 00 call 8049f80 <explode_bomb>
8048f24: c9 leave
8048f25: c3 ret
到目前为止,我有以下规则来查找数字:
第一个数字应该是 26,因为与 0x1a 相比。
有一个 for 循环迭代 4 次,并确保每个数字小于当前索引处的数字以下是我不确定的规则
- 前四个数字的总和应小于某物。
- 最后一个数字应该是第一个数字的负数
根据函数的开头,可以按如下方式查看堆栈布局:
int v[5], c0, c1;
ebp+e4 | v1
ebp+e8 | v2
ebp+ec | v3
ebp+f0 | v4
ebp+f4 | v5
ebp+f8 | c0
ebp+fc | c1
我已经将代码转录为伪代码,这应该可以回答您的问题。当然,一旦您了解了正在发生的事情,就可以将 goto 转换为 do/while
循环以提高可读性。
8048eae push %ebp
8048eaf mov %esp,%ebp
8048eb1 sub $0x28,%esp
8048eb4 movl $0x0,0xfffffff8(%ebp) c0 = 0;
8048ebb lea 0xffffffe4(%ebp),%eax
8048ebe mov %eax,0x4(%esp)
8048ec2 mov 0x8(%ebp),%eax
8048ec5 mov %eax,(%esp)
8048ec8 call 8049536 <read_five_numbers> read_five_numbers(v);
8048ecd mov 0xffffffe4(%ebp),%eax eax = v[0];
8048ed0 cmp $0x1a,%eax
8048ed3 je 8048eda <level_3+0x2c> unless(eax == 0x1A)
{
8048ed5 call 8049f80 <explode_bomb> explode_bomb();
}
8048eda movl $0x0,0xfffffffc(%ebp) c1 = 0;
8048ee1 jmp 8048f0f <level_3+0x61> goto loop_condition;
loop_body:
8048ee3 mov 0xfffffffc(%ebp),%eax eax = c1;
8048ee6 mov 0xffffffe4(%ebp,%eax,4),%edx edx = v[eax];
8048eea mov 0xfffffffc(%ebp),%eax eax = c1;
8048eed add $0x1,%eax ++eax;
8048ef0 mov 0xffffffe4(%ebp,%eax,4),%eax eax = v[eax];
8048ef4 cmp %eax,%edx
8048ef6 jg 8048efd <level_3+0x4f> unless(edx > eax)
{
8048ef8 call 8049f80 <explode_bomb> explode_bomb();
}
8048efd mov 0xfffffffc(%ebp),%eax eax = c1;
8048f00 mov 0xffffffe4(%ebp,%eax,4),%eax eax = v[eax];
8048f04 imul 0xfffffffc(%ebp),%eax eax *= c1;
8048f08 add %eax,0xfffffff8(%ebp) c0 += eax;
8048f0b addl $0x1,0xfffffffc(%ebp) ++c1;
loop_condition:
8048f0f cmpl $0x3,0xfffffffc(%ebp) if(c1 <= 3) {
8048f13 jle 8048ee3 <level_3+0x35> goto loop_body;
}
8048f15 mov 0xfffffff4(%ebp),%eax eax = v[4];
8048f18 neg %eax eax = -eax;
8048f1a cmp 0xfffffff8(%ebp),%eax
8048f1d je 8048f24 <level_3+0x76> unless(c0 == eax)
{
8048f1f call 8049f80 <explode_bomb> explode_bomb();
}
8048f24 leave
8048f25 ret
因此,如果我没看错,您的数字需要:
- 第一个必须等于0x1A。
- 第二个必须小于第一个。
- 第三个必须小于第二个。
- 第四个必须小于第三个。
-
(1 * second + 2 * third + 3 * fourth)
必须等于第五个数字的负数。