首先对bomb可执行文件进行反汇编。
Phase_1
0000000000400ee0 <phase_1>:
400ee0: 48 83 ec 08 sub $0x8,%rsp 为函数开辟一个新栈,分配0x1c即28个字节的空间
400ee4: be 00 24 40 00 mov $0x402400,%esi 将$0x402400处值存入esi地址处
400ee9: e8 4a 04 00 00 callq 401338 <strings_not_equal> 调401338方法 判断是否相等
400eee: 85 c0 test %eax,%eax 判断eax值是否为0
400ef0: 74 05 je 400ef7 <phase_1+0x17> 若eax为0则跳转到400ef7处,进入下一关
400ef2: e8 43 05 00 00 callq 40143a <explode_bomb> 否则跳转到40143a处,调用引爆炸弹函数
400ef7: 48 83 c4 08 add $0x8,%rsp 平栈
400efb: c3 retq
通过gdb启动bomb可执行文件,然后对该方法打断点
run指令运行后,随便输入几个字符。
接着通过disas指令查看目前汇编停留的位置。
调用x/s命令查看esi寄存器中的内容,发现是一长串字符串。
在通过info register命令查看当前各寄存器状态。
经过我们的尝试得知
r8处存储的是我们输入的值。
esi是默认的值。
故我们可以得知,Border relations with Canada have never been better. 是第一个关卡的密码。
Phase_2
0000000000400efc <phase_2>:
400efc: 55 push %rbp 压栈保存
400efd: 53 push %rbx 压栈保存
400efe: 48 83 ec 28 sub $0x28,%rsp 为函数开辟一个新栈,分配0x28即40个字节的空间
400f02: 48 89 e6 mov %rsp,%rsi 将rsp寄存器内值存入rsi地址处
400f05: e8 52 05 00 00 callq 40145c <read_six_numbers> 调用读取6个输入数字的函数,即字符串为6个数字组合
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp) 判断立即数1和rsp内所存值是否相等
400f0e: 74 20 je 400f30 <phase_2+0x34> 若相等则跳转到400f30处
400f10: e8 25 05 00 00 callq 40143a <explode_bomb> 否则跳转到40143a处,调用引爆炸弹函数
400f15: eb 19 jmp 400f30 <phase_2+0x34> 直接跳转400f30
400f17: 8b 43 fc mov -0x4(%rbx),%eax 将rbx-4地址处值存入eax寄存器中
400f1a: 01 c0 add %eax,%eax eax = eax * 2
400f1c: 39 03 cmp %eax,(%rbx) rbx和eax进行比较
400f1e: 74 05 je 400f25 <phase_2+0x29> 相等则跳转至400f25
400f20: e8 15 05 00 00 callq 40143a <explode_bomb> 否则跳转到40143a处,调用引爆炸弹函数
400f25: 48 83 c3 04 add $0x4,%rbx 将rbx寄存器内值加4后放回
400f29: 48 39 eb cmp %rbp,%rbx rbx和rbp进行比较
400f2c: 75 e9 jne 400f17 <phase_2+0x1b> 不相等跳转400f17
400f2e: eb 0c jmp 400f3c <phase_2+0x40> 相等则直接跳转400f3c
400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx 将rsp+4得到的地址传送到rbx寄存器中
400f35: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp 将rsp+24得到的地址传送到rbp寄存器中
400f3a: eb db jmp 400f17 <phase_2+0x1b> 直接跳转400f17
400f3c: 48 83 c4 28 add $0x28,%rsp 更新栈
400f40: 5b pop %rbx 平栈
400f41: 5d pop %rbp 平栈
400f42: c3 retq
以上是phase_2的反汇编后的结果。
tips:为了避免每次都输入一遍上一关的密码,我们可以把每一关的正确答案保存在一个txt文档中,比如我的就是psol.txt,下次只需要run psol.txt即可跳过前面关卡。
Phase_3
0000000000400f43 <phase_3>:
400f43: 48 83 ec 18 sub $0x18,%rsp //开辟栈空间 分配0x18 即24Byte空间
400f47: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx 将rsp+12的地址送入rcx寄存器中
400f4c: 48 8d 54 24 08 lea 0x8(%rsp),%rdx 将rsp+8的地址送入rdx寄存器中
400f51: be cf 25 40 00 mov $0x4025cf,%esi
400f56: b8 00 00 00 00 mov $0x0,%eax 将立即数0传送到eax寄存器中
400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt> 过程调用,400bf0为被调用过程起始点指令地址
400f60: 83 f8 01 cmp $0x1,%eax //判断 eax>1 ?
400f63: 7f 05 jg 400f6a <phase_3+0x27> //大于1直接跳转400f6a
400f65: e8 d0 04 00 00 callq 40143a <explode_bomb> 过程调用,40143a为被调用过程起始点指令地址 bomb
400f6a: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp) //rsp+8的地址 > 7?
400f6f: 77 3c ja 400fad <phase_3+0x6a> 大于直接跳转400fad 然后bomb
400f71: 8b 44 24 08 mov 0x8(%rsp),%eax rsp+8的地址送入eax寄存器中
400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8) //跳转到 0x402470 + M*8 所存储的地址处
400f7c: b8 cf 00 00 00 mov $0xcf,%eax 立即数207送入eax
400f81: eb 3b jmp 400fbe <phase_3+0x7b> 跳转到 400fbe 地址处
400f83: b8 c3 02 00 00 mov $0x2c3,%eax 立即数707送入eax
400f88: eb 34 jmp 400fbe <phase_3+0x7b>
400f8a: b8 00 01 00 00 mov $0x100,%eax 立即数256送入eax
400f8f: eb 2d jmp 400fbe <phase_3+0x7b>
400f91: b8 85 01 00 00 mov $0x185,%eax 立即数389送入eax
400f96: eb 26 jmp 400fbe <phase_3+0x7b>
400f98: b8 ce 00 00 00 mov $0xce,%eax 立即数707送入eax
400f9d: eb 1f jmp 400fbe <phase_3+0x7b>
400f9f: b8 aa 02 00 00 mov $0x2aa,%eax 立即数206送入eax
400fa4: eb 18 jmp 400fbe <phase_3+0x7b>
400fa6: b8 47 01 00 00 mov $0x147,%eax 立即数327送入eax
400fab: eb 11 jmp 400fbe <phase_3+0x7b>
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>
400fb2: b8 00 00 00 00 mov $0x0,%eax 立即数0送入eax
400fb7: eb 05 jmp 400fbe <phase_3+0x7b>
400fb9: b8 37 01 00 00 mov $0x137,%eax 立即数311送入eax
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax 判断eax = rsp+12地址的值
400fc2: 74 05 je 400fc9 <phase_3+0x86> 等于进入 400fc9
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb> 不等于 bomb
400fc9: 48 83 c4 18 add $0x18,%rsp 更新栈
400fcd: c3 retq 函数返回
由上述反编译的汇编代码可以看出,这是常见的switch case格式的汇编代码,根据input的值jmp至对应的方法来获取正确的答案。