拆掉邪恶博士的炸弹
原文链接:BombLab实验
这是一个课程实验,感觉有点意思,就记录一下吧。
分析可能不准确,仅供参考。
邪恶博士的幽默感
/***************************************************************************
* Dr. Evil's Insidious Bomb, Version 1.1
* Copyright 2011, Dr. Evil Incorporated. All rights reserved.
*
* LICENSE:
*
* Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the
* VICTIM) explicit permission to use this bomb (the BOMB). This is a
* time limited license, which expires on the death of the VICTIM.
* The PERPETRATOR takes no responsibility for damage, frustration,
* insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other
* harm to the VICTIM. Unless the PERPETRATOR wants to take credit,
* that is. The VICTIM may not distribute this bomb source code to
* any enemies of the PERPETRATOR. No VICTIM may debug,
* reverse-engineer, run "strings" on, decompile, decrypt, or use any
* other technique to gain knowledge of and defuse the BOMB. BOMB
* proof clothing may not be worn when handling this program. The
* PERPETRATOR will not apologize for the PERPETRATOR's poor sense of
* humor. This license is null and void where the BOMB is prohibited
* by law.
***************************************************************************/
满满的中二之感,连我都看不惯了,解之。
由于我们并没有完整的源代码,只能通过汇编代码来尝试推出这个邪恶的刀客塔到底在炸弹里做了些什么手脚了。
第一关
/* Hmm... Six phases must be more secure than one phase! */
邪恶博士的第一个关卡如下
08048b50 <phase_1>:
8048b50: 83 ec 1c sub $0x1c,%esp
8048b53: c7 44 24 04 64 a1 04 movl $0x804a164,0x4(%esp)
8048b5a: 08
8048b5b: 8b 44 24 20 mov 0x20(%esp),%eax
8048b5f: 89 04 24 mov %eax,(%esp)
8048b62: e8 2d 04 00 00 call 8048f94 <strings_not_equal>
8048b67: 85 c0 test %eax,%eax
8048b69: 74 05 je 8048b70 <phase_1+0x20>
8048b6b: e8 36 05 00 00 call 80490a6 <explode_bomb>
8048b70: 83 c4 1c add $0x1c,%esp
8048b73: c3 ret
看起来很短,大概是这样的:
把输入的内容传给了phase_1
,根据phase_1
调用了<strings_not_equal>
猜想这里应该是把输入的字符串和某个字符串作比较,下面test %eax,%eax
,当%eax
为0时跳过<explode_bomb>
,即<strings_not_equal>
的返回值为0,两个字符串相等时跳过。
在<strings_not_equal>
之前可以看到movl $0x804a164,0x4(%esp)
,将这个立即数作为地址。使用gdb调试bomb程序,输入x/s 0x804a164
,终端显示了0x804a164: "Crikey! I have lost my mojo!"
。
再往下是mov 0x20(%esp),%eax
,把手动输入的字符串的地址放进%eax
,再放到(%esp)
,传给了<strings_not_equal>
。猜测需要输入的正确答案就是0x804a164
处的字符串Crikey! I have lost my mojo!
。
在<explode_bomb>
前设置断点,break explode_bomb
,输入run运行程序。输入字符串Crikey! I have lost my mojo!
,终端显示Phase 1 defused. How about the next one?
,第一关通过。
第二关
/* The second phase is harder. No one will ever figure out
* how to defuse this... */
08048b74 <phase_2>:
8048b74: 56 push %esi
8048b75: 53 push %ebx
8048b76: 83 ec 34 sub $0x34,%esp
8048b79: 8d 44 24 18 lea 0x18(%esp),%eax
8048b7d: 89 44 24 04 mov %eax,0x4(%esp)
8048b81: 8b 44 24 40 mov 0x40(%esp),%eax
8048b85: 89 04 24 mov %eax,(%esp)
8048b88: e8 4e 06 00 00 call 80491db <read_six_numbers>
8048b8d: 83 7c 24 18 00 cmpl $0x0,0x18(%esp)
8048b92: 75 07 jne 8048b9b <phase_2+0x27>
8048b94: 83 7c 24 1c 01 cmpl $0x1,0x1c(%esp)
8048b99: 74 05 je 8048ba0 <phase_2+0x2c>
8048b9b: e8 06 05 00 00 call 80490a6 <explode_bomb>
由<read_six_numbers>
可以猜想第二关要输入六个数。紧接着是cmpl $0x0,0x18(%esp)
和jne 8048b9b <phase_2+0x27>
,而8048b9b
处就是调用<explode_bomb>
,也就是说如果第一个数不等于0就爆炸,所以第一个数是0。
再往下是cmpl $0x1,0x1c(%esp)
和je 8048ba0 <phase_2+0x2c>
,第二个数等于1就跳过爆炸。
8048ba0: 8d 5c 24 20 lea 0x20(%esp),%ebx
8048ba4: 8d 74 24 30 lea 0x30(%esp),%esi
8048ba8: 8b 43 f8 mov -0x8(%ebx),%eax
8048bab: 03 43 fc add -0x4(%ebx),%eax
8048bae: 39 03 cmp %eax,(%ebx)
8048bb0: 74 05 je 8048bb7 <phase_2+0x43>
8048bb2: e8 ef 04 00 00 call 80490a6 <explode_bomb>
8048bb7: 83 c3 04 add $0x4,%ebx
8048bba: 39 f3 cmp %esi,%ebx
8048bbc: 75 ea jne 8048ba8 <phase_2+0x34>
8048bbe: 83 c4 34 add $0x34,%esp
8048bc1: 5b pop %ebx
8048bc2: 5e pop %esi
8048bc3: c3 ret
接着是循环遍历剩下的数,由mov -0x8(%ebx),%eax
、add -0x4(%ebx),%eax
、cmp %eax,(%ebx)
可以发现是用当前数与它前面两个数之和比较,相等就不爆炸,也就是说输入的数应该组成斐波那契数列,已经有了0和1,剩下的应该是1、2、3、5。
在终端输入0 1 1 2 3 5
,终端输出了That's number 2. Keep going!
,第二关通过。
第三关
/* I guess this is too easy so far. Some more complex code will
* confuse people. */
08048bc4 <phase_3>:
8048bc4: 83 ec 2c sub $0x2c,%esp
8048bc7: 8d 44 24 1c lea 0x1c(%esp),%eax
8048bcb: 89 44 24 0c mov %eax,0xc(%esp)
8048bcf: 8d 44 24 18 lea 0x18(%esp),%eax
8048bd3: 89 44 24 08 mov %eax,0x8(%esp)
8048bd7: c7 44 24 04 8b a3 04 movl $0x804a38b,0x4(%esp)
8048bde: 08
8048bdf: 8b 44 24 30 mov 0x30(%esp),%eax
8048be3: 89 04 24 mov %eax,(%esp)
8048be6: e8 85 fc ff ff call 8048870 <__isoc99_sscanf@plt>
8048beb: 83 f8 01 cmp $0x1,%eax
8048bee: 7f 05