程序代码:
(gdb) disas phase_3
Dump of assembler code for function phase_3:
0x08048e01 <+0>:push %ebp
0x08048e02 <+1>:mov %esp,%ebp
0x08048e04 <+3>:sub $0x28,%esp
0x08048e07 <+6>:lea -0x8(%ebp),%eax
0x08048e0a <+9>:mov %eax,0xc(%esp)
0x08048e0e <+13>:lea -0x4(%ebp),%eax
0x08048e11 <+16>:mov %eax,0x8(%esp)
0x08048e15 <+20>:movl $0x8049ad6,0x4(%esp)
0x08048e1d <+28>:mov 0x8(%ebp),%eax
0x08048e20 <+31>:mov %eax,(%esp)
0x08048e23 <+34>:call 0x80488b4 <sscanf@plt>
0x08048e28 <+39>:cmp $0x1,%eax
0x08048e2b <+42>:jg 0x8048e32 <phase_3+49>
0x08048e2d <+44>:call 0x8049253 <explode_bomb>
0x08048e32 <+49>:cmpl $0x7,-0x4(%ebp)
0x08048e36 <+53>:ja 0x8048ea1 <phase_3+160>
0x08048e38 <+55>:mov -0x4(%ebp),%eax
0x08048e3b <+58>:jmp *0x8049900(,%eax,4)
0x08048e42 <+65>:mov $0x0,%eax
0x08048e47 <+70>:jmp 0x8048e9a <phase_3+153>
---Type <return> to continue, or q <return> to quit---
0x08048e49 <+72>:mov $0x0,%eax
0x08048e4e <+77>:xchg %ax,%ax
0x08048e50 <+79>:jmp 0x8048e95 <phase_3+148>
0x08048e52 <+81>:mov $0x0,%eax
0x08048e57 <+86>:jmp 0x8048e90 <phase_3+143>
0x08048e59 <+88>:mov $0x0,%eax
0x08048e5e <+93>:xchg %ax,%ax
0x08048e60 <+95>:jmp 0x8048e8b <phase_3+138>
0x08048e62 <+97>:mov $0x0,%eax
0x08048e67 <+102>:jmp 0x8048e86 <phase_3+133>
0x08048e69 <+104>:mov $0x0,%eax
0x08048e6e <+109>:xchg %ax,%ax
0x08048e70 <+111>:jmp 0x8048e81 <phase_3+128>
0x08048e72 <+113>:mov $0x396,%eax
0x08048e77 <+118>:jmp 0x8048e7e <phase_3+125>
0x08048e79 <+120>:mov $0x0,%eax
0x08048e7e <+125>:sub $0x53,%eax
0x08048e81 <+128>:add $0x139,%eax
0x08048e86 <+133>:sub $0x1e5,%eax
0x08048e8b <+138>:add $0x279,%eax
0x08048e90 <+143>:sub $0x3da,%eax
---Type <return> to continue, or q <return> to quit---
0x08048e95 <+148>:add $0x3da,%eax
0x08048e9a <+153>:sub $0x30e,%eax
0x08048e9f <+158>:jmp 0x8048eab <phase_3+170>
0x08048ea1 <+160>:call 0x8049253 <explode_bomb>
0x08048ea6 <+165>:mov $0x0,%eax
0x08048eab <+170>:cmpl $0x5,-0x4(%ebp)
0x08048eaf <+174>:jg 0x8048eb6 <phase_3+181>
0x08048eb1 <+176>:cmp -0x8(%ebp),%eax
0x08048eb4 <+179>:je 0x8048ebb <phase_3+186>
0x08048eb6 <+181>:call 0x8049253 <explode_bomb>
0x08048ebb <+186>:leave
0x08048ebc <+187>:lea 0x0(%esi,%eiz,1),%esi
0x08048ec0 <+191>:ret
End of assembler dump.
前面没什么好说的
只是这次的断点设置是关键
程序代码:
(gdb) break *phase_3
Breakpoint 1 at 0x8048e01
(gdb) run
Starting program: /home/wog/bomb
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
I am not part of the problem. I am a Republican.
Phase 1 defused. How about the next one?
1 2 6 24 120 720
That's number 2. Keep going!
1 2
Breakpoint 1, 0x08048e01 in phase_3 ()
运行到这里
我们查看一下寄存器
程序代码:
(gdb) info reg
eax 0x804a8c0134523072
ecx 0x77
edx 0x33
ebx 0xbffff414-1073744876
esp 0xbffff33c0xbffff33c
ebp 0xbffff3580xbffff358
esi 0x00
edi 0x00
eip 0x8048e010x8048e01 <phase_3>
有了第二颗炸弹的经验,我们知道eax里是刚才输入的字符串的地址
eip指向0x8048e01,ebp已经进栈,所以4(%esp)里是字符串地址
0x08048e07 <+6>:lea -0x8(%ebp),%eax
0x08048e0a <+9>:mov %eax,0xc(%esp)
0x08048e0e <+13>:lea -0x4(%ebp),%eax
0x08048e11 <+16>:mov %eax,0x8(%esp)
这个和前一次差不多,预留空位
0x08048dc3 <+13>:movl $0x8049ad6,0x4(%esp)
0x08048dcb <+21>:mov 0x8(%ebp),%eax
这个$0x8049ad6就有点奇怪了
所以,现在关键是搞清楚这个是什么
多试几次,最后用
(gdb) x/sb 0x8049ad6
0x8049ad6: "%d %d"
额……学过c语言就毫无压力了
(密码是两个数字?)
然后再运行一个GDB,设置另一个断点
(gdb) break sscanf
Breakpoint 2 at 0x17d1e4
单步走到这里
程序代码:
(gdb) s
Single stepping until exit from function sscanf,
which has no line number information.
0x08048e28 in phase_3 ()
(gdb) info reg
eax 0x22
ecx 0x3220313285041
edx 0x00
ebx 0xbffff414-1073744876
esp 0xbffff3100xbffff310
ebp 0xbffff3380xbffff338
esi 0x00
edi 0x00
eip 0x8048e280x8048e28 <phase_3+39>
因为下面就已经开始判断了
所以先查看查看内存(再也不纯手工算了)
程序代码:
(gdb) x/20xw 0xbffff310
0xbffff310:0x0804a8c0 0x08049ad6 0xbffff334 0xbffff330
0xbffff320:0x0000001d 0xbffff414 0xbffff338 0x0804936f
0xbffff330:0x00000002 0x00000001 0xbffff358 0x08048ab6
0xbffff340:0x0804a8c0 0x00287ff4 0x08049680 0xbffff368
0xbffff350:0xbffff370 0x00287ff4 0xbffff3e8 0x00145ce7
看到%d%d已经与数字对齐
(这里是怎么对的,中间又为什么多了个0xbffff358,求高手指教……)
再往下看
0x08048e32 <+49>:cmpl $0x7,-0x4(%ebp)
0x08048e36 <+53>:ja 0x8048ea1 <phase_3+160>
第一个数字大于7就gameover了
0x08048e38 <+55>:mov -0x4(%ebp),%eax
0x08048e3b <+58>:jmp *0x8049900(,%eax,4)
还好这个以前在书上见过,先弄清这个*0x8049900是什么
(gdb) x/xw 0x8049900
0x8049900 <__dso_handle+440>:0x08048e72
所以就是0x08048e72(,%eax,4)
这个就相当与c语言中的switch语句了
eax的值不同jmp的位置不同
从0到7一个一个试,(在试过程中就发现其实只用试到5,而且最后的结果就是第二个数)
程序代码:
case ‘0’:
eax=0x398-0x53+0x139-0x1e5+0x279-0x3da+0x3da-0x30e=514
case ‘1’:
eax=0-0x53+0x139-0x1e5+0x279-0x3da+0x3da-0x30e=-404
……
最后发现只有case‘0’最后是正数
所以密码是0 514
程序代码:
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
I am not part of the problem. I am a Republican.
Phase 1 defused. How about the next one?
1 2 6 24 120 720
That's number 2. Keep going!
0 514
Halfway there!
[code]
[
本帖最后由 wog 于 2011-4-13 18:36 编辑 ]