x /&b/ 8048bad: lea -0xc(%ebp),%eax 8048bb0: push %eax /&a/ 8048bb1: push $0x80497de /format/ 8048bb6: push %edx /input/ 8048bb7: call 8048860
同样用gdb可以知道format的值是”%d %c %d”,因此调用了sscanf(input,”%d %c %d”,&a,&b,&c),之后同样比较其返回值,如果小于3就引爆,接着:
08048b98
: 8048bc9: cmpl $0x7,-0xc(%ebp) 8048bcd: ja 8048c88
8048bd3: mov -0xc(%ebp),%eax /c/ 8048bd6: jmp *0x80497e8(,%eax,4) /case 0,1,2,3,4,5,6,7/ ...
8048c88: mov $0x78,%bl
8048c8a: call 80494fc
/default/
这里可以看到这是一个switch语句,用gdb查看跳转表:
(gdb) x/8x 0x80497e8
0x80497e8: 0x08048be0 0x08048c00 0x08048c16 0x08048c28
0x80497f8: 0x08048c40 0x08048c52 0x08048c64 0x08048c76
其中,从上到下,从左到右依次为a=0,1,..7时跳转地址,以a=0时为例:
08048b98
: 8048be0: mov $0x71,%bl /bl=”q”/ 8048be2: cmpl $0x309,-0x4(%ebp) /比较777和c/ 8048be9: je 8048c8f
/c==777/ 8048bef: call 80494fc
/c!=777/ ... 8048c8f: cmp -0x5(%ebp),%bl /比较b和”q”/ 8048c92: je 8048c99
/b==”q”/ 8048c94: call 80494fc
/b!=”q”/ 8048c99: mov -0x18(%ebp),%ebx /return/ 8048c9c: mov %ebp,%esp 8048c9e: pop %ebp 8048c9f: ret
由此可知,当a=0时,b=”q”且c=777才不会引爆,其余情况类似。
C语言等价代码为:
void phase_3(char *input)
{
int a,c;
char b;
int eax=sscanf(input,"%d %c %d",&a,&b,&c);
if (eax<=2)
explode_bomb();
switch (a){
case 0:
if (c!=777||b!="q")
explode_bomb();
case 1:
if (c!=214||b!="b")
explode_bomb();
case 2:
if (c!=755||b!="b")
explode_bomb();
case 3:
if (c!=251||b!="k")
explode_bomb();
case 4:
if (c!=160||b!="o")
explode_bomb();
case 5:
if (c!=458||b!="t")
explode_bomb();
case 6:
if (c!=780||b!="v")
explode_bomb();
case 7:
if (c!=524||b!="b")
explode_bomb();
default:explode_bomb();
}
}
由此可知,阶段三字符串必须是以0q777,1b214,2b755,3k251,4o111,5t458,6v780,7b524中的一个为开头且后续字符串不能以数字为开头的字符串。
阶段四
08048ce0
: 8048ce3: sub $0x18,%esp 8048ce6: mov 0x8(%ebp),%edx /input/ 8048ce9: add $0xfffffffc,%esp 8048cec: lea -0x4(%ebp),%eax /&x/ 8048cef: push %eax /&x/ 8048cf0: push $0x8049808 /format/ 8048cf5: push %edx /input/ 8048cf6: call 8048860
... 8048cfe: cmp $0x1,%eax 8048d01: jne 8048d09
... 8048d09: call 80494fc
同前分析可知,这里调用了sscanf(input,”%d”,&x),并且读到的数据个数不为1时,引爆,如果读入了一个数据:
08048ce0
: ... 8048d03: cmpl $0x0,-0x4(%ebp) /比较x和0/ 8048d07: jg 8048d0e
/x>0/ 8048d09: call 80494fc
/x<=0/ 8048d0e: add $0xfffffff4,%esp 8048d11: mov -0x4(%ebp),%eax /x/ 8048d14: push %eax/x/ 8048d15: call 8048ca0
8048d1a: add $0x10,%esp 8048d1d: cmp $0x37,%eax /比较func4(x)和55/ 8048d20: je 8048d27
/func4(x)==55,return/ 8048d22: call 80494fc
可以看出,如果读入值x<=0,引爆,如果读入值>0,比较func4(x)和55的大小,如果不相等,引爆,接下来分析func4:
08048ca0
: ... 8048cab: cmp $0x1,%ebx /比较x和1/ 8048cae: jle 8048cd0
/x<=1,return 1/ 8048cb0: add $0xfffffff4,%esp 8048cb3: lea -0x1(%ebx),%eax 8048cb6: push %eax /push x-1/ 8048cb7: call 8048ca0
/func4(x-1)/ 8048cbc: mov %eax,%esi /esi=func4(x-1)/ 8048cbe: add $0xfffffff4,%esp 8048cc1: lea -0x2(%ebx),%eax 8048cc4: push %eax /push x-2/ 8048cc5: call 8048ca0
/func4(x-2)/ 8048cca: add %esi,%eax /return func4(x-1)+func4(x-2)/ 8048ccc: jmp 8048cd5
8048cce: mov %esi,%esi 8048cd0: mov $0x1,%eax ...
可以发现func4首先比较x和1,如果x<=1返回1,否则返回func4(x-1)+func4(x-2;
C语言等价代码为:
int func4(int x)
{
if (x<=1)
return 1;
else
return func4(x-1)+func4(x-2);
}
void phase_4(char *input)
{
int x;
int eax=sscanf(input,"%d",&x);
if (eax!=1)
explode_bomb();
if (x<=0)
explode_bomb();
if (func4(x)!=55)
explode_bomb();
}
可知这是一个斐波拉契数列:
x 0 1 2 3 4 5 6 7 8 9
func4 1 1 2 3 5 8 13 21 34 55
由此可知,阶段4的正确输入是以9为开头,后续字符串以非数字开头的字符串,关于隐藏关是什么,我们留到最后分析。
阶段五
08048d2c
: ... 8048d3a: push %ebx /input/ 8048d3b: call 8049018
8048d40: add $0x10,%esp 8048d43: cmp $0x6,%eax 8048d46: je 8048d4d
8048d48: call 80494fc
...
可以知道这里比较input的长度,如果不是6,引爆,接着:
08048d2c
: 8048d4d: xor %edx,%edx /edx=0/ 8048d4f: lea -0x8(%ebp),%ecx /ecx=&s[0]/ 8048d52: mov $0x804b220,%esi /esi=&p[0]/ .loop 8048d57: mov (%edx,%ebx,1),%al /al=input[edx]/ 8048d5a: and $0xf,%al /al&=0xf/ 8048d5c: movsbl %al,%eax /eax=(int)al/ 8048d5f: mov (%eax,%esi,1),%al /al=p[eax]/ 8048d62: mov %al,(%edx,%ecx,1) /s[edx]=al/ 8048d65: inc %edx 8048d66: cmp $0x5,%edx 8048d69: jle 8048d57
goto .loop
同样用gdb可以知道p的值是”isrveawhobpnutfg”,上述循环的功能是令
s[edx]=p[(int)(input[edx]&0xf)],接着:
08048d2c
: ... 8048d6b: movb $0x0,-0x2(%ebp) /s[7]=0/ ... 8048d72: push $0x804980b /pattern/ 8048d77