0000000000400f43 <phase_3>: 00f43: 48 83 ec 18 sub $0x18,%rsp 400f47: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx 400f4c: 48 8d 54 24 08 lea 0x8(%rsp),%rdx 400f51: be cf 25 40 00 mov $0x4025cf,%esi ;用x/s 0x4025cf查看内存得到"%d %d" 400f56: b8 00 00 00 00 mov $0x0,%eax ;说明下一行中sscanf函数读取 2 个int值。 400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt>;sscanf正常返回值为读取的数据个数!正常运行则返回值为2。 400f60: 83 f8 01 cmp $0x1,%eax ;单步调试得%eax=2,2>1,下一行跳转。否则bomb. 400f63: 7f 05 jg 400f6a <phase_3+0x27> 400f65: e8 d0 04 00 00 callq 40143a <explode_bomb> 400f6a: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp) ;内存位置(%rsp+8)存储的是读取的第一个数据的值。 400f6f: 77 3c ja 400fad <phase_3+0x6a>;如果输入的第一个数大于7,则跳转bomb。言外之意第一个数必须小于等于7! 400f71: 8b 44 24 08 mov 0x8(%rsp),%eax ;%eax=第一个数; 400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8) ;按照第一个数的值进行跳转,可查看内存0x402470之后的值。分析则这是个switch(x)结构!0<=x<=7 400f7c: b8 cf 00 00 00 mov $0xcf,%eax ;答案“0 207”,0xcf=0d207; 400f81: eb 3b jmp 400fbe <phase_3+0x7b> 400f83: b8 c3 02 00 00 mov $0x2c3,%eax ;答案“2 707”,0x2c3=0d707; 400f88: eb 34 jmp 400fbe <phase_3+0x7b> 400f8a: b8 00 01 00 00 mov $0x100,%eax ;答案“3 256”,0x100=0d256; 400f8f: eb 2d jmp 400fbe <phase_3+0x7b> 400f91: b8 85 01 00 00 mov $0x185,%eax ;答案“4 389”,0x185=0d389; 400f96: eb 26 jmp 400fbe <phase_3+0x7b> 400f98: b8 ce 00 00 00 mov $0xce,%eax ;答案“5 206”,0xce=0d206; 400f9d: eb 1f jmp 400fbe <phase_3+0x7b> 400f9f: b8 aa 02 00 00 mov $0x2aa,%eax ;答案“6 682”; 400fa4: eb 18 jmp 400fbe <phase_3+0x7b> 400fa6: b8 47 01 00 00 mov $0x147,%eax ;答案“7 327”; 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 400fb7: eb 05 jmp 400fbe <phase_3+0x7b> 400fb9: b8 37 01 00 00 mov $0x137,%eax ;答案“1 311”; 400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax 400fc2: 74 05 je 400fc9 <phase_3+0x86> 400fc4: e8 71 04 00 00 callq 40143a <explode_bomb> 400fc9: 48 83 c4 18 add $0x18,%rsp 400fcd: c3 retq
需要注意的一点是,在这个switch结构与内存地址0x402470的关系中,并不是简单的线性关系(按照0 1 2 3 4 5 6 7的顺序对应于0x400f7c这边的地址),而是有变化的(0 2 3 4 5 6 7 1),主要需要查看地址内容才可以看的出来,如下:
需要对应着看,才可以分析出所有答案。
然后