Defuse the bomb(2)
Your job is to defuse the bomb. A ”binary bomb” is an executable C program that consists of six phases. Each phase expects the student to enter a particular string on stdin. If the student enters the expected string, then that phase is ”defused”. Otherwise the bomb explodes by printing ”BOOM!!!”. In either case, the bomb sends email to an email account specially created by the instructor. (Messages associated with defusions contain the string that defused the stage.) The goal for the students is to defuse as many phases as possible. Each bomb phase tests a different aspect of machine language programs:
• Phase 1: comparison;
• Phase 2: loops
• Phase 3: conditionals/switches
• Phase 4: recursive calls and the stack discipline
• Phase 5: pointers
• Phase 6: linked lists/pointers/structs
• Phase 4: phase_4 Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
Dump of assembler code for function phase_4:
=> 0x08048d41 <+0>: push %ebp
0x08048d42 <+1>: mov %esp,%ebp
0x08048d44 <+3>: sub $0x28,%esp
0x08048d47 <+6>: lea -0x4(%ebp),%eax
0x08048d4a <+9>: mov %eax,0x8(%esp)
0x08048d4e <+13>: movl $0x80498ae,0x4(%esp)
0x08048d56 <+21>: mov 0x8(%ebp),%eax
0x08048d59 <+24>: mov %eax,(%esp)
0x08048d5c <+27>: call 0x8048960 <sscanf@plt>
0x08048d61 <+32>: cmp $0x1,%eax
0x08048d64 <+35>: jne 0x8048d6c <phase_4+43>
0x08048d66 <+37>: cmpl $0x0,-0x4(%ebp)
0x08048d6a <+41>: jg 0x8048d75 <phase_4+52>
0x08048d6c <+43>: lea 0x0(%esi,%eiz,1),%esi
0x08048d70 <+47>: call 0x8048ff8 <explode_bomb>
0x08048d75 <+52>: mov -0x4(%ebp),%eax
0x08048d78 <+55>: mov %eax,(%esp)
0x08048d7b <+58>: call 0x8048b80 <func4>
0x08048d80 <+63>: cmp $0x58980,%eax
0x08048d85 <+68>: je 0x8048d8c <phase_4+75>
0x08048d87 <+70>: call 0x8048ff8 <explode_bomb>
0x08048d8c <+75>: leave
0x08048d8d <+76>: lea 0x0(%esi),%esi
0x08048d90 <+79>: ret
End of assembler dump.
(gdb) x /s 0x80498ae 0x80498ae: "%d"
phase_4输入只有一个数 -4(%ebp)保存数值,并作为func4的参数 func4
Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->
(gdb) disass
Dump of assembler code for function func4:
=> 0x08048b80 <+0>: push %ebp
0x08048b81 <+1>: mov %esp,%ebp
0x08048b83 <+3>: push %ebx
0x08048b84 <+4>: sub $0x4,%esp
0x08048b87 <+7>: mov 0x8(%ebp),%ebx
0x08048b8a <+10>: mov $0x1,%eax
0x08048b8f <+15>: cmp $0x1,%ebx
0x08048b92 <+18>: jle 0x8048ba2 <func4+34>
0x08048b94 <+20>: lea -0x1(%ebx),%eax
0x08048b97 <+23>: mov %eax,(%esp)
0x08048b9a <+26>: call 0x8048b80 <func4>
0x08048b9f <+31>: imul %ebx,%eax
0x08048ba2 <+34>: add $0x4,%esp
0x08048ba5 <+37>: pop %ebx
0x08048ba6 <+38>: pop %ebp
0x08048ba7 <+39>: ret
End of assembler dump.
这是一个递归函数,imul %ebx,%eax,可以看出 %eax = func4(%ebx-1)*%ebx ,
%ebx为func4的参数 func4(n) = n*func4(n-1), func4(0)=func4(1)=1,所以func4(n)计算n!。
回到phase_4,
0x08048d80 <+63>: cmp $0x58980,%eax
0x58980 == n! 等于则可以拆雷,因此n = 9
• Phase 5:
代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->
Dump of assembler code for function phase_5:
0x08048cb8 <+0>: push %ebp
=> 0x08048cb9 <+1>: mov %esp,%ebp
0x08048cbb <+3>: push %esi
0x08048cbc <+4>: push %ebx
0x08048cbd <+5>: sub $0x20,%esp
0x08048cc0 <+8>: mov 0x8(%ebp),%esi
0x08048cc3 <+11>: mov %esi,(%esp)
0x08048cc6 <+14>: call 0x8048ee0 <string_length>
0x08048ccb <+19>: cmp $0x6,%eax
0x08048cce <+22>: je 0x8048cd5 <phase_5+29>
0x08048cd0 <+24>: call 0x8048ff8 <explode_bomb>
0x08048cd5 <+29>: mov $0x1,%edx
0x08048cda <+34>: lea -0xf(%ebp),%ecx
0x08048cdd <+37>: movsbl -0x1(%edx,%esi,1),%eax
0x08048ce2 <+42>: and $0xf,%eax
0x08048ce5 <+45>: movzbl 0x804985c(%eax),%eax
0x08048cec <+52>: mov %al,-0x1(%edx,%ecx,1)
0x08048cf0 <+56>: add $0x1,%edx
0x08048cf3 <+59>: cmp $0x7,%edx
0x08048cf6 <+62>: jne 0x8048cdd <phase_5+37>
0x08048cf8 <+64>: movb $0x0,-0x9(%ebp)
0x08048cfc <+68>: movl $0x8049833,0x4(%esp)
0x08048d04 <+76>: mov %ecx,(%esp)
0x08048d07 <+79>: call 0x8048f00 <strings_not_equal>
0x08048d0c <+84>: test %eax,%eax
0x08048d0e <+86>: je 0x8048d15 <phase_5+93>
0x08048d10 <+88>: call 0x8048ff8 <explode_bomb>
0x08048d15 <+93>: add $0x20,%esp
0x08048d18 <+96>: pop %ebx
0x08048d19 <+97>: pop %esi
0x08048d1a <+98>: pop %ebp
0x08048d1b <+99>: ret
End of assembler dump.
(gdb) x /s 0x804985c
0x804985c <array.3018>: "isrveawhobpnutfg%d %s"
(gdb) x /s 0x8049833
0x8049833: "titans"
又是比较字符串,目标字符串是"titans",我们需要构造一个相同的字符串,地址由%ecx指向。
字符串中的字符源自 "isrveawhobpnutfg%d %s"
构造字符串
0x08048cdd <+37>: movsbl -0x1(%edx,%esi,1),%eax
0x08048ce2 <+42>: and $0xf,%eax
0x08048ce5 <+45>: movzbl 0x804985c(%eax),%eax
0x08048cec <+52>: mov %al,-0x1(%edx,%ecx,1)
0x08048cf0 <+56>: add $0x1,%edx
0x08048cf3 <+59>: cmp $0x7,%edx
0x08048cf6 <+62>: jne 0x8048cdd <phase_5+37>
其中%esi保存input, %ecx构造字符串起始位置, input[i]的低4位构成 "isrveawhobpnutfg%d %s"下标。
"isrveawhobpnutfg%d %s"
0123456789abcdef
从"isrveawhobpnutfg%d %s"取出6个到%ecx指向的内存中。't' 'i' 't' 'a' 'n' 's',
下标分别为0xd,0x0,0xd,0x5,0xb,0x1
input位16进制尾数位以上下标的字符串,如"mpmeka"
• Phase 6:
2: *(int *)($eax) = 367
(gdb) disass
Dump of assembler code for function phase_6:
0x08048e83 <+0>: push %ebp
0x08048e84 <+1>: mov %esp,%ebp
0x08048e86 <+3>: push %ebx
0x08048e87 <+4>: sub $0x14,%esp
0x08048e8a <+7>: movl $0xa,0x8(%esp)
0x08048e92 <+15>: movl $0x0,0x4(%esp)
0x08048e9a <+23>: mov 0x8(%ebp),%eax
0x08048e9d <+26>: mov %eax,(%esp)
0x08048ea0 <+29>: call 0x8048840 <strtol@plt>
0x08048ea5 <+34>: mov %eax,%ebx
0x08048ea7 <+36>: movl $0x804a600,(%esp)
0x08048eae <+43>: call 0x8048ba8 <fun6>
0x08048eb3 <+48>: mov 0x8(%eax),%eax
0x08048eb6 <+51>: mov 0x8(%eax),%eax
0x08048eb9 <+54>: mov 0x8(%eax),%eax
0x08048ebc <+57>: mov 0x8(%eax),%eax
0x08048ebf <+60>: mov 0x8(%eax),%eax
=> 0x08048ec2 <+63>: cmp (%eax),%ebx
0x08048ec4 <+65>: je 0x8048ecb <phase_6+72>
0x08048ec6 <+67>: call 0x8048ff8 <explode_bomb>
0x08048ecb <+72>: add $0x14,%esp
0x08048ece <+75>: pop %ebx
0x08048ecf <+76>: pop %ebp
0x08048ed0 <+77>: ret
End of assembler dump.
(gdb) display *(int *)$eax
3: *(int *)$eax = 367
(gdb)
这个比较明显,input->strtol == 367
input="367"