总共7个phase,非常好玩…
进入每一个phase时,我们应该弄清楚的是:
1、输入格式:需要我们输入什么,是字符串,还是整数,还是字符,输入个数是多少?
2、爆炸点:哪些语句可能引起爆炸,通常为一个比较语句cmp,这是解题的关键,告诉应该输入的值是多少。因此,找到这些爆炸点即可能跳到<explode_bomb>爆炸函数的语句,在这些地方打上断点哦。
3、循环、递归:当发现jump会往之前的语句跳时,可能是循环或者递归,建议在这段代码做个标记,弄清楚每一段在做什么操作。
4、每个寄存器是用来干什么的:
最常使用的gdb语句:
1、b+空格+地址/函数名打断点
2、x /s+地址/寄存器
打印该地址处的字符串,s可以换成其他字母,d打印十进制整数,c打印字符,x打印十六进制整数。
3、i r
查看寄存器的值(同info r
)。
4、stepi
单步进入,不跳过子函数;nexti
跳过子函数,逐步执行主函数。
5、continue
跳到下一个断点。
6、run
开始运行。
另外!!可以画图帮助理解!!
命令行中进入实验,然后打开gdb开始调试:
gdb ./bomb
然后在每个炸弹处打断点:phase_1 到 phase_6
(gdb) b phase_1
phase_1
000000000400ead <phase_1>:
400ead: 48 83 ec 08 sub $0x8,%rsp
400eb1: be 8c 24 40 00 mov $0x40248c,%esi
400eb6: e8 4b 05 00 00 callq 401406 <strings_not_equal>
400ebb: 85 c0 test %eax,%eax
400ebd: 74 05 je 400ec4 <phase_1+0x17>
400ebf: e8 41 06 00 00 callq 401505 <explode_bomb>
400ec4: 48 83 c4 08 add $0x8,%rsp
400ec8: c3 retq
进入phase_1后,第二行看到比较输入参数和存储在地址 0x40248c 处的值,gdb调试中输入并得到:
(gdb) x /s 0x40248c
0x40248c: "Public speaking is very easy."
答案 :Public speaking is very easy.
phase_2
小 tips:先把炸弹找出来,然后在可能跳到炸弹的地方打断点。
000000000400ec9 <phase_2>:
400ec9: 55 push %rbp
400eca: 53 push %rbx
400ecb: 48 83 ec 28 sub $0x28,%rsp
400ecf: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
400ed6: 00 00
400ed8: 48 89 44 24 18 mov %rax,0x18(%rsp)
400edd: 31 c0 xor %eax,%eax
400edf: 48 89 e6 mov %rsp,%rsi
400ee2: e8 40 06 00 00 callq 401527 <read_six_numbers>
400ee7: 83 3c 24 00 cmpl $0x0,(%rsp) //x1=0
400eeb: 75 07 jne 400ef4 <phase_2+0x2b>
400eed: 83 7c 24 04 01 cmpl $0x1,0x4(%rsp) //x2=1
400ef2: 74 05 je 400ef9 <phase_2+0x30>
400ef4: e8 0c 06 00 00 callq 401505 <explode_bomb>
400ef9: 48 89 e3 mov %rsp,%rbx
400efc: 48 8d 6c 24 10 lea 0x10(%rsp),%rbp//x5
//循环
400f01: 8b 43 04 mov 0x4(%rbx),%eax//x2 x3..x5
400f04: 03 03 add (%rbx),%eax //x1+x2 x2+x3.. x4+x5
400f06: 39 43 08 cmp %eax,0x8(%rbx)
//x3=x1+x2=1 x4=x2+x3=2 x5=x3+x4 x6=x4+x5=5
400f09: 74 05 je 400f10 <phase_2+0x47>
400f0b: e8 f5 05 00 00 callq 401505 <explode_bomb>
400f10: 48 83 c3 04 add $0x4,%rbx//x2->x5
400f14: 48 39 eb cmp %rbp,%rbx//比较x2和x5 x3和x5..
400f17: 75 e8 jne 400f01 <phase_2+0x38>
//循环结束
400f19: 48 8b 44 24 18 mov 0x18(%rsp),%rax
400f1e: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
400f25: 00 00
400f27: 74 05 je 400f2e <phase_2+0x65>
400f29: e8 f2 fb ff ff callq 400b20 <__stack_chk_fail@plt>
400f2e: 48 83 c4 28 add $0x28,%rsp
400f32: 5b pop %rbx
400f33: 5d pop %rbp
400f34: c3 retq
前5行和后7行可以跳过,callq 401527 <read_six_numbers>
告诉我们读取6个数,猜测输入为6个整数。
往下看,有给在栈中,栈顶保存的值应为x1=0,向上x2=1,否则会jump到
401505 <explode_bomb>
炸弹爆炸。
然后在%rbp中保留了x5,即lea 0x10(%rsp),%rbp
0x10是16,栈顶为x1,每4位一个整数,那么0x10(%rsp)
就是x5,然后进入循环,循环过程打在代码数字里面了,最后发现是斐波那契数列的前六个数。
答案 : 0 1 1 2 3 5
phase_3
粗略地总体看一下,中间有很多400f8e: 00
类似的语句,然后它们之间的代码好像做的都是差不多是操作。
000000000400f35 <phase_3>:
400f35: 48 83 ec 28 sub $0x28,%rsp
400f39: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
400f40: 00 00
400f42: 48 89 44 24 18 mov %rax,0x18(%rsp)
400f47: 31 c0 xor %eax,%eax
400f49: 4c 8d 44 24 14 lea 0x14(%rsp),%r8
400f4e: 48 8d 4c 24 0f lea 0xf(%rsp),%rcx
400f53: 48 8d 54 24 10 lea 0x10(%rsp),%rdx
400f58: be aa 24 40 00 mov $0x4024aa,%esi // "%d %c %d"
400f5d: e8 7e fc ff ff callq 400be0 <__isoc99_sscanf@plt>
400f62: 83 f8 02 cmp $0x2,%eax //输入的东西个数为3
400f65: 7f 05 jg 400f6c <phase_3+0x37>
400f67: e8 99 05 00 00 callq 401505 <explode_bomb>
400f6c: 83 7c 24 10 07 cmpl $0x7,0x10(%rsp)
400f71: 0f 87 fc 00 00 00 ja 401073 <phase_3+0x13e> //不可以跳<=7
400f77: 8b 44 24 10 mov 0x10(%rsp),%eax
400f7b: ff 24 c5 c0 24 40 00 jmpq *0x4024c0(,%rax,8)
400f82: b8 77 00 00 00 mov $0x77,%eax
400f87: 81 7c 24 14 91 03 00 cmpl $0x391,0x14(%rsp) //相等
400f8e: 00
400f8f: 0f 84 e8 00 00 00 je 40107d <phase_3+0x148>
400f95: e8 6b 05 00 00 callq 401505 <explode_bomb>
400f9a: b8 77 00 00 00 mov $0x77,%eax
400f9f: e9 d9 00 00 00 jmpq 40107d <phase_3+0x148>
400fa4: b8 6a 00 00 00 mov $0x6a,%eax
400fa9: 81 7c 24 14 f6 02 00 cmpl $0x2f6,0x14(%rsp)
400fb0: 00
400fb1: 0f 84 c6 00 00 00 je 40107d <phase_3+0x148>
400fb7: e8 49 05 00 00 callq 401505 <explode_bomb>
400fbc: b8 6a 00 00 00 mov $0x6a,%eax
400fc1: e9 b7 00 00 00 jmpq 40107d <phase_3+0x148>
400fc6: b8 61 00 00 00 mov $0x61,%eax
400fcb: 81 7c 24 1