bomblab-再相遇

​ 废话不多说,开始。

phase_1

1
2
3
4
5
6
7
8
9
10
11
(gdb) disassemble phase_1
Dump of assembler code for function phase_1:
0x0000000000400f2d <+0>: sub $0x8,%rsp
0x0000000000400f31 <+4>: mov $0x4026f0,%esi
0x0000000000400f36 <+9>: callq 0x401472 <strings_not_equal>
0x0000000000400f3b <+14>: test %eax,%eax
0x0000000000400f3d <+16>: je 0x400f44 <phase_1+23>
0x0000000000400f3f <+18>: callq 0x401741 <explode_bomb>
0x0000000000400f44 <+23>: add $0x8,%rsp
0x0000000000400f48 <+27>: retq
End of assembler dump.

直接看一下0x4026f0字符串就可以:

(gdb) x/s 0x4026f0
0x4026f0: "I am just a renegade hockey mom."

phase_2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(gdb) disassemble phase_2
Dump of assembler code for function phase_2:
0x0000000000400f49 <+0>: push %rbp
0x0000000000400f4a <+1>: push %rbx
0x0000000000400f4b <+2>: sub $0x28,%rsp
0x0000000000400f4f <+6>: mov %fs:0x28,%rax
0x0000000000400f58 <+15>: mov %rax,0x18(%rsp)
0x0000000000400f5d <+20>: xor %eax,%eax
0x0000000000400f5f <+22>: mov %rsp,%rsi
0x0000000000400f62 <+25>: callq 0x401777 <read_six_numbers>
0x0000000000400f67 <+30>: cmpl $0x0,(%rsp)
0x0000000000400f6b <+34>: jns 0x400f72 <phase_2+41>
0x0000000000400f6d <+36>: callq 0x401741 <explode_bomb>
0x0000000000400f72 <+41>: mov %rsp,%rbp
0x0000000000400f75 <+44>: mov $0x1,%ebx
0x0000000000400f7a <+49>: mov %ebx,%eax
0x0000000000400f7c <+51>: add 0x0(%rbp),%eax
0x0000000000400f7f <+54>: cmp %eax,0x4(%rbp)
0x0000000000400f82 <+57>: je 0x400f89 <phase_2+64>
0x0000000000400f84 <+59>: callq 0x401741 <explode_bomb>
0x0000000000400f89 <+64>: add $0x1,%ebx
0x0000000000400f8c <+67>: add $0x4,%rbp
0x0000000000400f90 <+71>: cmp $0x6,%ebx
0x0000000000400f93 <+74>: jne 0x400f7a <phase_2+49>
---Type <return> to continue, or q <return> to quit---
0x0000000000400f95 <+76>: mov 0x18(%rsp),%rax
0x0000000000400f9a <+81>: xor %fs:0x28,%rax
0x0000000000400fa3 <+90>: je 0x400faa <phase_2+97>
0x0000000000400fa5 <+92>: callq 0x400b90 <[email protected]>
0x0000000000400faa <+97>: add $0x28,%rsp
0x0000000000400fae <+101>: pop %rbx
0x0000000000400faf <+102>: pop %rbp
0x0000000000400fb0 <+103>: retq
End of assembler dump.

输入是6个数,从0x400f93 <+74>: jne 0x400f7a <phase_2+49> 知道主逻辑是个循环,第一个数是必须是0,第二个数必须是1,开始以为是等差数列,然后发现中间还有个+1的过程,所以这个数列的公差是等差数列,那么正确答案是:0 1 3 6 10 15.

phase_3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(gdb) disassemble phase_3
Dump of assembler code for function phase_3:
0x0000000000400fb1 <+0>: sub $0x28,%rsp
0x0000000000400fb5 <+4>: mov %fs:0x28,%rax
0x0000000000400fbe <+13>: mov %rax,0x18(%rsp)
0x0000000000400fc3 <+18>: xor %eax,%eax
0x0000000000400fc5 <+20>: lea 0x14(%rsp),%r8
0x0000000000400fca <+25>: lea 0xf(%rsp),%rcx
0x0000000000400fcf <+30>: lea 0x10(%rsp),%rdx
0x0000000000400fd4 <+35>: mov $0x40273e,%esi
0x0000000000400fd9 <+40>: callq 0x400c40 <[email protected]>
0x0000000000400fde <+45>: cmp $0x2,%eax
0x0000000000400fe1 <+48>: jg 0x400fe8 <phase_3+55>
0x0000000000400fe3 <+50>: callq 0x401741 <explode_bomb>
0x0000000000400fe8 <+55>: cmpl $0x7,0x10(%rsp,
0x0000000000400fed <+60>: ja 0x4010ef <phase_3+318>
0x0000000000400ff3 <+66>: mov 0x10(%rsp),%eax
0x0000000000400ff7 <+70>: jmpq *0x402750(,%rax,8)
0x0000000000400ffe <+77>: mov $0x66,%eax
0x0000000000401003 <+82>: cmpl $0xde,0x14(%rsp)
0x000000000040100b <+90>: je 0x4010f9 <phase_3+328>
0x0000000000401011 <+96>: callq 0x401741 <explode_bomb>
0x0000000000401016 <+101>: mov $0x66,%eax
0x000000000040101b <+106>: jmpq 0x4010f9 <phase_3+328>
---Type <return> to continue, or q <return> to quit---
0x0000000000401020 <+111>: mov $0x74,%eax
0x0000000000401025 <+116>: cmpl $0x288,0x14(%rsp)
0x000000000040102d <+124>: je 0x4010f9 <phase_3+328>
0x0000000000401033 <+130>: callq 0x401741 <explode_bomb>
0x0000000000401038 <+135>: mov $0x74,%eax
0x000000000040103d <+140>: jmpq 0x4010f9 <phase_3+328>
0x0000000000401042 <+145>: mov $0x76,%eax
0x0000000000401047 <+150>: cmpl $0x149,0x14(%rsp)
0x000000000040104f <+158>: je 0x4010f9 <phase_3+328>
0x0000000000401055 <+164>: callq 0x401741 <explode_bomb>
0x000000000040105a <+169>: mov $0x76,%eax
0x000000000040105f <+174>: jmpq 0x4010f9 <phase_3+328>
0x0000000000401064 <+179>: mov $0x62,%eax
0x0000000000401069 <+184>: cmpl $0x2a7,0x14(%rsp)
0x0000000000401071 <+192>: je 0x4010f9 <phase_3+328>
0x0000000000401077 <+198>: callq 0x401741 <explode_bomb>
0x000000000040107c <+203>: mov $0x62,%eax
0x0000000000401081 <+208>: jmp 0x4010f9 <phase_3+328>
0x0000000000401083 <+210>: mov $0x73,%eax
0x0000000000401088 <+215>: cmpl $0xc6,0x14(%rsp)
0x0000000000401090 <+223>: je 0x4010f9 <phase_3+328>
0x0000000000401092 <+225>: callq 0x401741 <explode_bomb>
0x0000000000401097 <+230>: mov $0x73,%eax
---Type <return> to continue, or q <return> to quit---
0x000000000040109c <+235>: jmp 0x4010f9 <phase_3+328>
0x000000000040109e <+237>: mov $0x63,%eax
0x00000000004010a3 <+242>: cmpl $0x398,0x14(%rsp)
0x00000000004010ab <+250>: je 0x4010f9 <phase_3+328>
0x00000000004010ad <+252>: callq 0x401741 <explode_bomb>
0x00000000004010b2 <+257>: mov $0x63,%eax
0x00000000004010b7 <+262>: jmp 0x4010f9 <phase_3+328>
0x00000000004010b9 <+264>: mov $0x67,%eax
0x00000000004010be <+269>: cmpl $0x1a5,0x14(%rsp)
0x00000000004010c6 <+277>: je 0x4010f9 <phase_3+328>
0x00000000004010c8 <+279>: callq 0x401741 <explode_bomb>
0x00000000004010cd <+284>: mov $0x67,%eax
0x00000000004010d2 <+289>: jmp 0x4010f9 <phase_3+328>
0x00000000004010d4 <+291>: mov $0x67,%eax
0x00000000004010d9 <+296>: cmpl $0x109,0x14(%rsp)
0x00000000004010e1 <+304>: je 0x4010f9 <phase_3+328>
0x00000000004010e3 <+306>: callq 0x401741 <explode_bomb>
0x00000000004010e8 <+311>: mov $0x67,%eax
0x00000000004010ed <+316>: jmp 0x4010f9 <phase_3+328>
0x00000000004010ef <+318>: callq 0x401741 <explode_bomb>
0x00000000004010f4 <+323>: mov $0x71,%eax
0x00000000004010f9 <+328>: cmp 0xf(%rsp),%al
0x00000000004010fd <+332>: je 0x401104 <phase_3+339>
---Type <return> to continue, or q <return> to quit---
0x00000000004010ff <+334>: callq 0x401741 <explode_bomb>
0x0000000000401104 <+339>: mov 0x18(%rsp),%rax
0x0000000000401109 <+344>: xor %fs:0x28,%rax
0x0000000000401112 <+353>: je 0x401119 <phase_3+360>
0x0000000000401114 <+355>: callq 0x400b90 <[email protected]>
0x0000000000401119 <+360>: add $0x28,%rsp
0x000000000040111d <+364>: retq
End of assembler dump.

首先看一下输入格式:

(gdb) x/s 0x40273e
0x40273e: "%d %c %d"

这里疯狂跳转,而且到处写着explode_bomb,仔细看一下其实就是个case语句,比方说如果输入的第一个数是0,那么就把第三个数和0xde比较,即222,不想等就爆炸,即第三个数为222,再把第二个和0x66,比较,第二个是字符型,转成字符就是f,一个答案:0 f 222.

phase_4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(gdb) disassemble phase_4
Dump of assembler code for function phase_4:
0x0000000000401151 <+0>: sub $0x18,%rsp
0x0000000000401155 <+4>: mov %fs:0x28,%rax
0x000000000040115e <+13>: mov %rax,0x8(%rsp)
0x0000000000401163 <+18>: xor %eax,%eax
0x0000000000401165 <+20>: lea 0x4(%rsp),%rcx
0x000000000040116a <+25>: mov %rsp,%rdx
0x000000000040116d <+28>: mov $0x4029ed,%esi
0x0000000000401172 <+33>: callq 0x400c40 <[email protected]>
0x0000000000401177 <+38>: cmp $0x2,%eax
0x000000000040117a <+41>: jne 0x401182 <phase_4+49>
0x000000000040117c <+43>: cmpl $0xe,(%rsp)
0x0000000000401180 <+47>: jbe 0x401187 <phase_4+54>
0x0000000000401182 <+49>: callq 0x401741 <explode_bomb>
0x0000000000401187 <+54>: mov $0xe,%edx
0x000000000040118c <+59>: mov $0x0,%esi
0x0000000000401191 <+64>: mov (%rsp),%edi
0x0000000000401194 <+67>: callq 0x40111e <func4>
0x0000000000401199 <+72>: cmp $0x1b,%eax
0x000000000040119c <+75>: jne 0x4011a5 <phase_4+84>
0x000000000040119e <+77>: cmpl $0x1b,0x4(%rsp)
0x00000000004011a3 <+82>: je 0x4011aa <phase_4+89>
0x00000000004011a5 <+84>: callq 0x401741 <explode_bomb>
---Type <return> to continue, or q <return> to quit---
0x00000000004011aa <+89>: mov 0x8(%rsp),%rax
0x00000000004011af <+94>: xor %fs:0x28,%rax
0x00000000004011b8 <+103>: je 0x4011bf <phase_4+110>
0x00000000004011ba <+105>: callq 0x400b90 <[email protected]>
0x00000000004011bf <+110>: add $0x18,%rsp
0x00000000004011c3 <+114>: retq
End of assembler dump.

输入格式是两个整数,然后第一个必须小于等于14,第二个必须是27。再把第一个参数传到fun4里面,如果返回值与27相等,就通过,否则爆炸。那么fun4是啥呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Dump of assembler code for function func4:
0x000000000040111e <+0>: push %rbx
0x000000000040111f <+1>: mov %edx,%eax
0x0000000000401121 <+3>: sub %esi,%eax
0x0000000000401123 <+5>: mov %eax,%ebx
0x0000000000401125 <+7>: shr $0x1f,%ebx
0x0000000000401128 <+10>: add %ebx,%eax
0x000000000040112a <+12>: sar %eax
0x000000000040112c <+14>: lea (%rax,%rsi,1),%ebx
0x000000000040112f <+17>: cmp %edi,%ebx
0x0000000000401131 <+19>: jle 0x40113f <func4+33>
0x0000000000401133 <+21>: lea -0x1(%rbx),%edx
0x0000000000401136 <+24>: callq 0x40111e <func4>
0x000000000040113b <+29>: add %ebx,%eax
0x000000000040113d <+31>: jmp 0x40114f <func4+49>
0x000000000040113f <+33>: mov %ebx,%eax
0x0000000000401141 <+35>: cmp %edi,%ebx
0x0000000000401143 <+37>: jge 0x40114f <func4+49>
0x0000000000401145 <+39>: lea 0x1(%rbx),%esi
0x0000000000401148 <+42>: callq 0x40111e <func4>
0x000000000040114d <+47>: add %ebx,%eax
0x000000000040114f <+49>: pop %rbx
0x0000000000401150 <+50>: retq

显然是个递归函数,可以把它转成c语言函数然后遍历一下,经队友提示可以把断点打在第二个explode_bomb函数之前,直接输入a 27,这样就能跳过第一个explode_bomb,单步执行到fun4调用完毕,看一下返回值就行了,得到的结果是9,所以答案是9 27

phase_5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
(gdb) disassemble phase_5
Dump of assembler code for function phase_5:
0x00000000004011c4 <+0>: push %rbx
0x00000000004011c5 <+1>: sub $0x10,%rsp
0x00000000004011c9 <+5>: mov %rdi,%rbx
0x00000000004011cc <+8>: mov %fs:0x28,%rax
0x00000000004011d5 <+17>: mov %rax,0x8(%rsp)
0x00000000004011da <+22>: xor %eax,%eax
0x00000000004011dc <+24>: callq 0x401454 <string_length>
0x00000000004011e1 <+29>: cmp $0x6,%eax
0x00000000004011e4 <+32>: je 0x4011eb <phase_5+39>
0x00000000004011e6 <+34>: callq 0x401741 <explode_bomb>
0x00000000004011eb <+39>: mov $0x0,%eax
0x00000000004011f0 <+44>: movzbl (%rbx,%rax,1),%edx
0x00000000004011f4 <+48>: and $0xf,%edx
0x00000000004011f7 <+51>: movzbl 0x402790(%rdx),%edx
0x00000000004011fe <+58>: mov %dl,(%rsp,%rax,1)
0x0000000000401201 <+61>: add $0x1,%rax
0x0000000000401205 <+65>: cmp $0x6,%rax
0x0000000000401209 <+69>: jne 0x4011f0 <phase_5+44>
0x000000000040120b <+71>: movb $0x0,0x6(%rsp)
0x0000000000401210 <+76>: mov $0x402747,%esi
0x0000000000401215 <+81>: mov %rsp,%rdi
0x0000000000401218 <+84>: callq 0x401472 <strings_not_equal>
---Type <return> to continue, or q <return> to quit---
0x000000000040121d <+89>: test %eax,%eax
0x000000000040121f <+91>: je 0x401226 <phase_5+98>
0x0000000000401221 <+93>: callq 0x401741 <explode_bomb>
0x0000000000401226 <+98>: mov 0x8(%rsp),%rax
0x000000000040122b <+103>: xor %fs:0x28,%rax
0x0000000000401234 <+112>: je 0x40123b <phase_5+119>
0x0000000000401236 <+114>: callq 0x400b90 <[email protected]>
0x000000000040123b <+119>: add $0x10,%rsp
0x000000000040123f <+123>: pop %rbx
0x0000000000401240 <+124>: retq
End of assembler dump.

看到两个奇怪的地址0x402790,打印一下看看

x/s 0x402790

0x402790 <array.3601>: "maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?"

x/s 0x402747

0x402747: "devils"

输入格式为1个字符串,长度为6,然后去那句话里面找到这6个字母的偏移,从输入的字符里面依次取低4位与之比较,比如这里的偏移为:2 5 12 4 15 7 ,我对照ascii码表找了一个合格的答案0010-b 0101-e 1100-l 0100-t 1111-o 0111-w ,即beltow,试一下,通过了。

phase_6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(gdb) disassemble phase_6
Dump of assembler code for function phase_6:
0x0000000000401241 <+0>: push %r13
0x0000000000401243 <+2>: push %r12
0x0000000000401245 <+4>: push %rbp
0x0000000000401246 <+5>: push %rbx
0x0000000000401247 <+6>: sub $0x68,%rsp
0x000000000040124b <+10>: mov %fs:0x28,%rax
0x0000000000401254 <+19>: mov %rax,0x58(%rsp)
0x0000000000401259 <+24>: xor %eax,%eax
0x000000000040125b <+26>: mov %rsp,%rsi
0x000000000040125e <+29>: callq 0x401777 <read_six_numbers>
0x0000000000401263 <+34>: mov %rsp,%r12
0x0000000000401266 <+37>: mov $0x0,%r13d
0x000000000040126c <+43>: mov %r12,%rbp
0x000000000040126f <+46>: mov (%r12),%eax
0x0000000000401273 <+50>: sub $0x1,%eax
0x0000000000401276 <+53>: cmp $0x5,%eax
0x0000000000401279 <+56>: jbe 0x401280 <phase_6+63>
0x000000000040127b <+58>: callq 0x401741 <explode_bomb>
0x0000000000401280 <+63>: add $0x1,%r13d
0x0000000000401284 <+67>: cmp $0x6,%r13d
0x0000000000401288 <+71>: je 0x4012c7 <phase_6+134>
0x000000000040128a <+73>: mov %r13d,%ebx
0x000000000040128d <+76>: movslq %ebx,%rax
0x0000000000401290 <+79>: mov (%rsp,%rax,4),%eax
0x0000000000401293 <+82>: cmp %eax,0x0(%rbp)
0x0000000000401296 <+85>: jne 0x40129d <phase_6+92>
0x0000000000401298 <+87>: callq 0x401741 <explode_bomb>
0x000000000040129d <+92>: add $0x1,%ebx
0x00000000004012a0 <+95>: cmp $0x5,%ebx
0x00000000004012a3 <+98>: jle 0x40128d <phase_6+76>
0x00000000004012a5 <+100>: add $0x4,%r12
0x00000000004012a9 <+104>: jmp 0x40126c <phase_6+43>
0x00000000004012ab <+106>: mov 0x8(%rdx),%rdx
0x00000000004012af <+110>: add $0x1,%eax
0x00000000004012b2 <+113>: cmp %ecx,%eax
0x00000000004012b4 <+115>: jne 0x4012ab <phase_6+106>
0x00000000004012b6 <+117>: mov %rdx,0x20(%rsp,%rsi,2)
0x00000000004012bb <+122>: add $0x4,%rsi
0x00000000004012bf <+126>: cmp $0x18,%rsi
0x00000000004012c3 <+130>: jne 0x4012cc <phase_6+139>
0x00000000004012c5 <+132>: jmp 0x4012e0 <phase_6+159>
0x00000000004012c7 <+134>: mov $0x0,%esi
0x00000000004012cc <+139>: mov (%rsp,%rsi,1),%ecx
0x00000000004012cf <+142>: mov $0x1,%eax
0x00000000004012d4 <+147>: mov $0x604300,%edx
---Type <return> to continue, or q <return> to quit---
0x00000000004012d9 <+152>: cmp $0x1,%ecx
0x00000000004012dc <+155>: jg 0x4012ab <phase_6+106>
0x00000000004012de <+157>: jmp 0x4012b6 <phase_6+117>
0x00000000004012e0 <+159>: mov 0x20(%rsp),%rbx
0x00000000004012e5 <+164>: lea 0x20(%rsp),%rax
0x00000000004012ea <+169>: lea 0x48(%rsp),%rsi
0x00000000004012ef <+174>: mov %rbx,%rcx
0x00000000004012f2 <+177>: mov 0x8(%rax),%rdx
0x00000000004012f6 <+181>: mov %rdx,0x8(%rcx)
0x00000000004012fa <+185>: add $0x8,%rax
0x00000000004012fe <+189>: mov %rdx,%rcx
0x0000000000401301 <+192>: cmp %rsi,%rax
0x0000000000401304 <+195>: jne 0x4012f2 <phase_6+177>
0x0000000000401306 <+197>: movq $0x0,0x8(%rdx)
0x000000000040130e <+205>: mov $0x5,%ebp
0x0000000000401313 <+210>: mov 0x8(%rbx),%rax
0x0000000000401317 <+214>: mov (%rax),%eax
0x0000000000401319 <+216>: cmp %eax,(%rbx)
0x000000000040131b <+218>: jge 0x401322 <phase_6+225>
0x000000000040131d <+220>: callq 0x401741 <explode_bomb>
0x0000000000401322 <+225>: mov 0x8(%rbx),%rbx
0x0000000000401326 <+229>: sub $0x1,%ebp
0x0000000000401329 <+232>: jne 0x401313 <phase_6+210>
0x000000000040132b <+234>: mov 0x58(%rsp),%rax
0x0000000000401330 <+239>: xor %fs:0x28,%rax
0x0000000000401339 <+248>: je 0x401340 <phase_6+255>
0x000000000040133b <+250>: callq 0x400b90 <[email protected]>
0x0000000000401340 <+255>: add $0x68,%rsp
0x0000000000401344 <+259>: pop %rbx
0x0000000000401345 <+260>: pop %rbp
0x0000000000401346 <+261>: pop %r12
0x0000000000401348 <+263>: pop %r13
0x000000000040134a <+265>: retq
End of assembler dump.

代码贼长,看的心累,慢慢看下去会发现是个链表,而且有编号,而且要对其进行升序排列,而输入的格式又恰好是6个整数,显然就是要输入6个结点的序号了。重点是这个地址:0x604300,很突兀,看一下里面是啥(这个结果要输入一个顺序后才能看到

啊哦,这不就全出来了吗,按照升序排列的话,就是:3 1 6 2 5 4

secret_phase

直接搜源码,把里面可疑的地址都打印看一下会发现有一个输入格式是“%d %d %s”,而且找到那个字符串为DrEvil,回忆一下前面那几关,只有第四关的输入格式是%d %d,跟要求的格式的前两个一样,退出重新输入答案,在9 27后面加DrEvil,过了第6关后就进了隐藏关了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(gdb) disassemble secret_phase
Dump of assembler code for function secret_phase:
0x0000000000401389 <+0>: push %rbx
0x000000000040138a <+1>: callq 0x4017b6 <read_line>
0x000000000040138f <+6>: mov $0xa,%edx
0x0000000000401394 <+11>: mov $0x0,%esi
0x0000000000401399 <+16>: mov %rax,%rdi
0x000000000040139c <+19>: callq 0x400c20 <[email protected]>
0x00000000004013a1 <+24>: mov %rax,%rbx
0x00000000004013a4 <+27>: lea -0x1(%rax),%eax
0x00000000004013a7 <+30>: cmp $0x3e8,%eax
0x00000000004013ac <+35>: jbe 0x4013b3 <secret_phase+42>
0x00000000004013ae <+37>: callq 0x401741 <explode_bomb>
0x00000000004013b3 <+42>: mov %ebx,%esi
0x00000000004013b5 <+44>: mov $0x604120,%edi
0x00000000004013ba <+49>: callq 0x40134b <fun7>
0x00000000004013bf <+54>: test %eax,%eax
0x00000000004013c1 <+56>: je 0x4013c8 <secret_phase+63>
0x00000000004013c3 <+58>: callq 0x401741 <explode_bomb>
0x00000000004013c8 <+63>: mov $0x402718,%edi
0x00000000004013cd <+68>: callq 0x400b70 <[email protected]>
0x00000000004013d2 <+73>: callq 0x4018dc <phase_defused>
0x00000000004013d7 <+78>: pop %rbx
0x00000000004013d8 <+79>: retq

逻辑似乎很简单,它把你的输入转成10进制数,先与1000(0x3e8)比较,如果大于1000直接炸掉,如果不相等,那么把它作为第二个参数传到fun7,如果返回值大于0,爆炸。看一下fun7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Dump of assembler code for function fun7:
0x000000000040134b <+0>: sub $0x8,%rsp
0x000000000040134f <+4>: test %rdi,%rdi
0x0000000000401352 <+7>: je 0x40137f <fun7+52>
0x0000000000401354 <+9>: mov (%rdi),%edx
0x0000000000401356 <+11>: cmp %esi,%edx
0x0000000000401358 <+13>: jle 0x401367 <fun7+28>
0x000000000040135a <+15>: mov 0x8(%rdi),%rdi
0x000000000040135e <+19>: callq 0x40134b <fun7>
0x0000000000401363 <+24>: add %eax,%eax
0x0000000000401365 <+26>: jmp 0x401384 <fun7+57>
0x0000000000401367 <+28>: mov $0x0,%eax
0x000000000040136c <+33>: cmp %esi,%edx
0x000000000040136e <+35>: je 0x401384 <fun7+57>
0x0000000000401370 <+37>: mov 0x10(%rdi),%rdi
0x0000000000401374 <+41>: callq 0x40134b <fun7>
0x0000000000401379 <+46>: lea 0x1(%rax,%rax,1),%eax
0x000000000040137d <+50>: jmp 0x401384 <fun7+57>
0x000000000040137f <+52>: mov $0xffffffff,%eax
0x0000000000401384 <+57>: add $0x8,%rsp
0x0000000000401388 <+61>: retq
End of assembler dump.

显然是个递归函数,第一个参数显然很可疑,看一下是啥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(gdb) x/120 0x604120
0x604120 <n1>: 36 0 6308160 0
0x604130 <n1+16>: 6308192 0 0 0
0x604140 <n21>: 8 0 6308288 0
0x604150 <n21+16>: 6308224 0 0 0
0x604160 <n22>: 50 0 6308256 0
0x604170 <n22+16>: 6308320 0 0 0
0x604180 <n32>: 22 0 6308512 0
0x604190 <n32+16>: 6308448 0 0 0
0x6041a0 <n33>: 45 0 6308352 0
0x6041b0 <n33+16>: 6308544 0 0 0
0x6041c0 <n31>: 6 0 6308384 0
0x6041d0 <n31+16>: 6308480 0 0 0
0x6041e0 <n34>: 107 0 6308416 0
0x6041f0 <n34+16>: 6308576 0 0 0
0x604200 <n45>: 40 0 0 0
0x604210 <n45+16>: 0 0 0 0
0x604220 <n41>: 1 0 0 0
0x604230 <n41+16>: 0 0 0 0
0x604240 <n47>: 99 0 0 0
0x604250 <n47+16>: 0 0 0 0
0x604260 <n44>: 35 0 0 0
0x604270 <n44+16>: 0 0 0 0
0x604280 <n42>: 7 0 0 0
0x604290 <n42+16>: 0 0 0 0
0x6042a0 <n43>: 20 0 0 0
0x6042b0 <n43+16>: 0 0 0 0
0x6042c0 <n46>: 47 0 0 0
0x6042d0 <n46+16>: 0 0 0 0
0x6042e0 <n48>: 1001 0 0 0
0x6042f0 <n48+16>: 0 0 0 0

二叉树。。。。。它结点的命名很有规律,直接画出来都行。

然后fun7的逻辑可疑整理一下,写成c语言大概是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int fun7(BiTree T,int v){//v是传入的那个整数
int result;
if(T){
if(T->data <= v){
result = 0;
if(T->data != v){
result = 2 * fun7(T->right,v) + 1;
}
}
else{
result = 2 * fun7(T->left,v);
}
}
else{
result = -1;
}
return result;
}

把那颗二叉树直接保存下来然后爆破一下即可,因为上周刚好写完了树的基本操作,所以自己电脑上有环境直接跑

1
2
3
4
5
6
for(int i = 0;i < 1000;i++){
if(!fun7(T,i)){
printf("answer: %d ",i);
// break;
}
}

结果竟然只有4个???咦,厉害了

通关截图:

tips

总结了一点技巧(骚姿势):b explode_bomb(这个应该都会);如果绕不过检测函数,可以选择让它炸一次,然后看返回值;直接把包拖到本地,把检测host和记录答题状态的函数全部nop掉,这样在本地想怎么玩就怎么玩;IDA!!!!!!!(我就借助了IDA,捂脸φ(>ω<) φ(>ω<)