• Phase 1:


Dump of assembler code for function phase_1:
0x08048d1c <+0>: push %ebp
0x08048d1d <+1>: mov %esp,%ebp
0x08048d1f <+3>: sub $0x8,%esp
=> 0x08048d22 <+6>: movl $0x8049804,0x4(%esp)
0x08048d2a <+14>: mov 0x8(%ebp),%eax
0x08048d2d <+17>: mov %eax,(%esp)
0x08048d30 <+20>: call 0x8048f00 <strings_not_equal>
0x08048d35 <+25>: test %eax,%eax
0x08048d37 <+27>: je 0x8048d3e <phase_1+34>
0x08048d39 <+29>: call 0x8048ff8 <explode_bomb>
0x08048d3e <+34>: leave
0x08048d3f <+35>: nop
0x08048d40 <+36>: ret
End of assembler dump.
(gdb) x /s 0x8049804
0x8049804: "When I get angry, Mr. Bigglesworth gets upset."
0x08048d22 <+6>: movl $0x8049804,0x4(%esp)
0x8049804 作为第二个参数
0x08048d2a <+14>: mov 0x8(%ebp),%eax
phase_1(input): input -> %eax
0x08048d2d <+17>: mov %eax,(%esp)
%eax 作为第一个参数
0x08048d30 <+20>: call 0x8048f00 <strings_not_equal>
调用strings_not_equal,顾名思义,就是判断字符串相等与否了。原型strings_not_equal(char *lh, char *rh)
rh = 0x8049804, lh = input
查看0x8049804所指的字符串,为"When I get angry, Mr. Bigglesworth gets upset."
因此,input = "When I get angry, Mr. Bigglesworth gets upset."
• Phase 2:


Dump of assembler code for function phase_2:
=> 0x08048e29 <+0>: push %ebp
0x08048e2a <+1>: mov %esp,%ebp
0x08048e2c <+3>: push %esi
0x08048e2d <+4>: push %ebx
0x08048e2e <+5>: sub $0x30,%esp
0x08048e31 <+8>: lea -0x20(%ebp),%eax
0x08048e34 <+11>: mov %eax,0x4(%esp)
0x08048e38 <+15>: mov 0x8(%ebp),%eax
0x08048e3b <+18>: mov %eax,(%esp)
0x08048e3e <+21>: call 0x8049022 <read_six_numbers>
0x08048e43 <+26>: cmpl $0x1,-0x20(%ebp)
0x08048e47 <+30>: je 0x8048e72 <phase_2+73>
0x08048e49 <+32>: call 0x8048ff8 <explode_bomb>
0x08048e4e <+37>: xchg %ax,%ax
0x08048e50 <+39>: jmp 0x8048e72 <phase_2+73>
0x08048e52 <+41>: mov %ebx,%eax
0x08048e54 <+43>: imul -0x8(%esi,%ebx,4),%eax
0x08048e59 <+48>: cmp %eax,-0x4(%esi,%ebx,4)
0x08048e5d <+52>: je 0x8048e64 <phase_2+59>
0x08048e5f <+54>: call 0x8048ff8 <explode_bomb>
0x08048e64 <+59>: add $0x1,%ebx
0x08048e67 <+62>: cmp $0x7,%ebx
0x08048e6a <+65>: je 0x8048e7c <phase_2+83>
0x08048e6c <+67>: lea 0x0(%esi,%eiz,1),%esi
0x08048e70 <+71>: jmp 0x8048e52 <phase_2+41>
0x08048e72 <+73>: mov $0x2,%ebx
0x08048e77 <+78>: lea -0x20(%ebp),%esi
0x08048e7a <+81>: jmp 0x8048e52 <phase_2+41>
0x08048e7c <+83>: add $0x30,%esp
0x08048e7f <+86>: pop %ebx
0x08048e80 <+87>: pop %esi
0x08048e81 <+88>: pop %ebp
0x08048e82 <+89>: ret
End of assembler dump.
phase_2函数还调用了 read_six_numbers,read_six_numbers有两个参数
参数1:0x8(%ebp) , 即phase_2(input)的input
参数2:%ebp - 0x20,该函数帧中的一个地址,作用得看read_six_numbers
read_six_numbers的原型应该是read_six_numbers(char *arg1, void *arg2)
arg2是指针,类型不明
进入 read_six_numbers


Dump of assembler code for function read_six_numbers:
0x08049022 <+0>: push %ebp
=> 0x08049023 <+1>: mov %esp,%ebp
0x08049025 <+3>: sub $0x28,%esp
0x08049028 <+6>: mov 0xc(%ebp),%edx
0x0804902b <+9>: lea 0x14(%edx),%eax
0x0804902e <+12>: mov %eax,0x1c(%esp)
0x08049032 <+16>: lea 0x10(%edx),%eax
0x08049035 <+19>: mov %eax,0x18(%esp)
0x08049039 <+23>: lea 0xc(%edx),%eax
0x0804903c <+26>: mov %eax,0x14(%esp)
0x08049040 <+30>: lea 0x8(%edx),%eax
0x08049043 <+33>: mov %eax,0x10(%esp)
0x08049047 <+37>: lea 0x4(%edx),%eax
0x0804904a <+40>: mov %eax,0xc(%esp)
0x0804904e <+44>: mov %edx,0x8(%esp)
0x08049052 <+48>: movl $0x804989f,0x4(%esp)
0x0804905a <+56>: mov 0x8(%ebp),%eax
0x0804905d <+59>: mov %eax,(%esp)
0x08049060 <+62>: call 0x8048960 <sscanf@plt>
0x08049065 <+67>: cmp $0x5,%eax
0x08049068 <+70>: jg 0x804906f <read_six_numbers+77>
0x0804906a <+72>: call 0x8048ff8 <explode_bomb>
0x0804906f <+77>: leave
0x08049070 <+78>: ret
End of assembler dump.
(gdb) x /s 0x804989f
0x804989f: "%d %d %d %d %d %d"
arg2 -> %edx
%edx + 0x14 -> %eax -> 0x1c(%esp) 参数8
%edx + 0x10 -> %eax -> 0x18(%esp) 参数7
%edx + 0xc -> %eax -> 0x14(%esp) 参数6
%edx + 0x8 -> %eax -> 0x10(%esp) 参数5
%edx + 0x4 -> %eax -> 0xc(%esp) 参数4
%edx -> 0x8(%esp) 参数3
0x804989f -> 0x4(%esp) 参数2
0x8(%ebp) -> (%esp) 参数1
int sscanf(const char *str, const char *format, ...);
因此, str=input, format="%d %d %d %d %d %d"
写入到数组int a[6]中,a=%edx
0x08049065 <+67>: cmp $0x5,%eax
判断是否读入大于5个数
回到phase_2中:
int a[6], a=%ebp-0x20
0x08048e43 <+26>: cmpl $0x1,-0x20(%ebp)
a[0] == 1
0x08048e54 <+43>: imul -0x8(%esi,%ebx,4),%eax
a[i] = (i+1)*a[i-1],依次类推
a[] = {1, 2, 6, 24, 120, 720}
因此input="1 2 6 24 120 720"
• Phase 3


=> 0x08048d92 <+1>: mov %esp,%ebp
0x08048d94 <+3>: sub $0x28,%esp
0x08048d97 <+6>: lea -0x8(%ebp),%eax
0x08048d9a <+9>: mov %eax,0xc(%esp)
0x08048d9e <+13>: lea -0x4(%ebp),%eax
0x08048da1 <+16>: mov %eax,0x8(%esp)
0x08048da5 <+20>: movl $0x80498ab,0x4(%esp)
0x08048dad <+28>: mov 0x8(%ebp),%eax
0x08048db0 <+31>: mov %eax,(%esp)
0x08048db3 <+34>: call 0x8048960 <sscanf@plt>
0x08048db8 <+39>: cmp $0x1,%eax
0x08048dbb <+42>: jg 0x8048dc2 <phase_3+49>
0x08048dbd <+44>: call 0x8048ff8 <explode_bomb>
0x08048dc2 <+49>: cmpl $0x7,-0x4(%ebp)
0x08048dc6 <+53>: ja 0x8048e12 <phase_3+129>
0x08048dc8 <+55>: mov -0x4(%ebp),%eax
0x08048dcb <+58>: jmp *0x804983c(,%eax,4)
0x08048dd2 <+65>: mov $0x28e,%eax
0x08048dd7 <+70>: jmp 0x8048e1c <phase_3+139>
0x08048dd9 <+72>: mov $0x20a,%eax
0x08048dde <+77>: xchg %ax,%ax
0x08048de0 <+79>: jmp 0x8048e1c <phase_3+139>
0x08048de2 <+81>: mov $0x359,%eax
0x08048de7 <+86>: jmp 0x8048e1c <phase_3+139>
0x08048de9 <+88>: mov $0x330,%eax
0x08048dee <+93>: xchg %ax,%ax
0x08048df0 <+95>: jmp 0x8048e1c <phase_3+139>
0x08048df2 <+97>: mov $0x2a4,%eax
0x08048df7 <+102>: jmp 0x8048e1c <phase_3+139>
0x08048df9 <+104>: mov $0xf3,%eax
0x08048dfe <+109>: xchg %ax,%ax
0x08048e00 <+111>: jmp 0x8048e1c <phase_3+139>
0x08048e02 <+113>: mov $0xd6,%eax
0x08048e07 <+118>: jmp 0x8048e1c <phase_3+139>
0x08048e09 <+120>: mov $0x34,%eax
0x08048e0e <+125>: xchg %ax,%ax
0x08048e10 <+127>: jmp 0x8048e1c <phase_3+139>
---Type <return> to continue, or q <return> to quit---
0x08048e12 <+129>: call 0x8048ff8 <explode_bomb>
0x08048e17 <+134>: mov $0x0,%eax
0x08048e1c <+139>: cmp -0x8(%ebp),%eax
0x08048e1f <+142>: nop
0x08048e20 <+143>: je 0x8048e27 <phase_3+150>
0x08048e22 <+145>: call 0x8048ff8 <explode_bomb>
0x08048e27 <+150>: leave
0x08048e28 <+151>: ret
End of assembler dump.
(gdb) x /s 0x80498ab
0x80498ab: "%d %d"
看来输入是两个数值了,并以一个空格分开
sscanf(input, "%d %d", %ebp-0x4, %ebp-0x8)
0x08048dc2 <+49>: cmpl $0x7,-0x4(%ebp)0x08048dc6 <+53>: ja 0x8048e12 <phase_3+129>
看来第一个数不能大于0x7,只能是0,1,2,3,4,5,6,7
0x08048e10 <+127>: jmp 0x8048e1c <phase_3+139>
jmp之后与-0x8(%ebp)比较,即和参数2判等,共8处,jmp之前给%eax赋值。
参数1影响jmp的位置。
0x08048dc8 <+55>: mov -0x4(%ebp),%eax
0x08048dcb <+58>: jmp *0x804983c(,%eax,4)
这句完全不懂,逐个尝试后
-4(%ebp) pc %eax (hex) (dec)
0 0x08048de2 0x359 857
1 0x08048de9 0x330 816
2 0x08048df2 0x2a4 676
3 0x08048df9 0xf3 243
4 0x08048e02 0xd6 214
5 0x08048e09 0x34 52
6 0x08048dd2 0x28e 654
7 0x08048dd9 0x20a 522
因此,可能的输入有
0 857
1 816
2 676
3 243
4 214
5 52
6 654
7 522
懂了,0x804983c(,%eax,4)处是跳转表项
jmp * 简介跳转指令
Half way!