第三关
还是先附上代码
0000000000400ef9<phase_3>:
400ef9: 4883 ec 18 sub $0x18, %rsp
400efd: 488d 4c 24 08 lea 0x8(%rsp), %rcx
400f02: 488d 54 24 0c lea 0xc(%rsp), %rdx
400f07: bebe 1e 40 00 mov $0x401ebe, %esi
400f0c: b800 00 00 00 mov $0x0, %eax
400f11: e8 9a fb ff ff callq 400ab0 <__isoc99_sscanf@plt>
400f16: 83f8 01 cmp $0x1, %eax
400f19: 7f05 jg 400f20<phase_3+0x27>
400f1b: e81d 07 00 00 callq 40163d<explode_bomb>
400f20: 837c 24 0c 07 cmpl $0x7, 0xc(%rsp)
400f25: 773c ja 400f63<phase_3+0x6a>
400f27: 8b44 24 0c mov 0xc(%rsp), %eax
400f2b: ff 24 c5 60 1b 40 00 jmpq *0x401b60(, %rax, 8)
400f32: b817 02 00 00 mov $0x217, %eax
400f37: eb3b jmp 400f74<phase_3+0x7b>
400f39: b8d6 00 00 00 mov $0xd6, %eax
400f3e: eb34 jmp 400f74<phase_3+0x7b>
400f40: b853 01 00 00 mov $0x153, %eax
400f45: eb2d jmp 400f74<phase_3+0x7b>
400f47: b877 00 00 00 mov $0x77, %eax
400f4c: eb26 jmp 400f74<phase_3+0x7b>
400f4e: b860 01 00 00 mov $0x160, %eax
400f53: eb1f jmp 400f74<phase_3+0x7b>
400f55: b897 03 00 00 mov $0x397, %eax
400f5a: eb18 jmp 400f74<phase_3+0x7b>
400f5c: b89c 01 00 00 mov $0x19c, %eax
400f61: eb11 jmp 400f74<phase_3+0x7b>
400f63: e8d5 06 00 00 callq 40163d<explode_bomb>
400f68: b800 00 00 00 mov $0x0, %eax
400f6d: eb05 jmp 400f74<phase_3+0x7b>
400f6f: b89e 03 00 00 mov $0x39e, %eax
400f74: 3b44 24 08 cmp 0x8(%rsp), %eax
400f78: 7405 je 400f7f<phase_3+0x86>
400f7a: e8be 06 00 00 callq 40163d<explode_bomb>
400f7f: 4883 c4 18 add $0x18, %rsp
400f83: c3 retq
400ab0<__isoc99_sscanf@plt> 指明了 sscanf 是标准库函数,经查文档,得到该函数的signature为
intsscanf(const char *buffer,const char *format,[argument ]...);
与gets函数一样都要有buffer,结合前面将0x8(%rsp),0xc(%rsp) 的地址压入寄存器,以及后面会取出0x8(%rsp),0xc(%rsp)进行其他操作,所以猜测应该是输入的内容放入栈中这两个位置(作为buffer)。而且该函数的返回值(返回值为参数数目)要求大于1才不会爆炸,所以结合buffer的大小为2输入的应该是两个字符。%esi 对应的是参数 const char *forma。
现在打印mov $0x401ebe, %esi看看:
确定输入的是两个字符,而且是两个数字。读代码可以知道,要求输入的第一个数字小于等于7,且跳转到 *(0x401b60 + 8 * args[1] ) 处。
jmpq *0x401b60(, %rax, 8)
这是一个switch结构,分别对eax赋值,然后与我们输入的第二个数字比较,相等才过关。所以相应的这里的答案也有8组。
这里我用的答案是0 535