Defuse the bomb(1)

拆解二进制炸弹
本文详细解析了一个名为“二进制炸弹”的C程序,它包含六个阶段的挑战,涉及从字符串比较到链表操作的不同任务。每个阶段都需要学生正确输入特定字符串来解除炸弹,否则炸弹将触发并爆炸。
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 1:

ExpandedBlockStart.gifphase_1
(gdb) disass
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
0
x8049804:       "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:

ExpandedBlockStart.gifphase_2
(gdb) disass
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 

ExpandedBlockStart.gifread_six_numbers
(gdb) disass
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
0
x804989f:       "%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

 

ExpandedBlockStart.gifphase_3
   0x08048d91 <+0>:     push   %ebp
=> 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
0
x80498ab:       "%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! 

转载于:https://www.cnblogs.com/qzchenwl/archive/2010/03/27/1698170.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值