实验步骤
准备工作
使用tar -vxf
将炸弹压缩包解压,cd 进入,可以从 bomb.c 中看出实验的用意以及程序的大致
逻辑,bomb 为可执行程序,使用 gdb 调试该程序.
1
2
3
4
|
(gdb) b read_line
Breakpoint 1 at 0x40155c
(gdb) b explode_bomb
Breakpoint 2 at 0x4014e4
|
给 read_line 函数打上断点,以便每次输入运行一关.给 explode_bomb 打上断点,以便在炸弹爆炸
前可以处理.
phase_1
获得 phase_1 汇编代码
1
2
3
4
5
6
7
8
9
10
11
|
(gdb) disas phase_1
Dump of assembler code for function phase_1:
0x0000000000400e80 <+0>: sub $0x8,%rsp
0x0000000000400e84 <+4>: mov $0x4024a0,%esi
0x0000000000400e89 <+9>: callq 0x40127e <strings_not_equal>
0x0000000000400e8e <+14>: test %eax,%eax
0x0000000000400e90 <+16>: je 0x400e97 <phase_1+23>
0x0000000000400e92 <+18>: callq 0x4014e4 <explode_bomb>
0x0000000000400e97 <+23>: add $0x8,%rsp
0x0000000000400e9b <+27>: retq
End of assembler dump.
|
可见,此题是将我们输入的字符串与地址 0x4024a0 处字符串比较,不等则爆炸.查看该字符串.
1
2
|
(gdb) x/s 0x4024a0
0x4024a0 <__dso_handle+344>: "We have to stand with our North Korean allies."
|
那么答案是 We have to stand with our North Korean allies.
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
|
(gdb) disas phase_2
Dump of assembler code for function phase_2:
0x0000000000400e9c <+0>: push %rbp
0x0000000000400e9d <+1>: push %rbx
0x0000000000400e9e <+2>: sub $0x28,%rsp
0x0000000000400ea2 <+6>: mov %rsp,%rsi
0x0000000000400ea5 <+9>: callq 0x40151a <read_six_numbers>
0x0000000000400eaa <+14>: cmpl $0x1,(%rsp)
0x0000000000400eae <+18>: je 0x400ed0 <phase_2+52>
0x0000000000400eb0 <+20>: callq 0x4014e4 <explode_bomb>
0x0000000000400eb5 <+25>: jmp 0x400ed0 <phase_2+52>
0x0000000000400eb7 <+27>: mov -0x4(%rbx),%eax
0x0000000000400eba <+30>: add %eax,%eax
0x0000000000400ebc <+32>: cmp %eax,(%rbx)
0x0000000000400ebe <+34>: je 0x400ec5 <phase_2+41>
0x0000000000400ec0 <+36>: callq 0x4014e4 <explode_bomb>
0x0000000000400ec5 <+41>: add $0x4,%rbx
0x0000000000400ec9 <+45>: cmp %rbp,%rbx
0x0000000000400ecc <+48>: jne 0x400eb7 <phase_2+27>
0x0000000000400ece <+50>: jmp 0x400edc <phase_2+64>
0x0000000000400ed0 <+52>: lea 0x4(%rsp),%rbx
0x0000000000400ed5 <+57>: lea 0x18(%rsp),%rbp
0x0000000000400eda <+62>: jmp 0x400eb7 <phase_2+27>
0x0000000000400edc <+64>: add $0x28,%rsp
---Type <return> to continue, or q <return> to quit---
0x0000000000400ee0 <+68>: pop %rbx
0x0000000000400ee1 <+69>: pop %rbp
0x0000000000400ee2 <+70>: retq
End of assembler dump.
|
+3 处发现在栈中开辟了 0x28 的内存区域.然后将%rsp 的值传给%rsi 作为
参数传给函数 read_six_numbers,可以看出应该使用开辟的空闲内存做
数组,记数组为 r,读取六个数字.将(%rsp)和 0x1 比较,如果不等,就会爆
炸,(%rsp)为数组首元,故 r[0]=1;跳转到+52,将 r[1]地址赋给%rbx,
将 r6
地址赋给%rbp,跳到+27,将%eax 设为%rbx 指向的前一个
数,此时为 r[0],比较 r[1]和 2*r[0]是否相等,不等则爆炸.跳转到+41,%
rbx+4,比较%rbx 和%rbp,不等跳转到+27,重复,等则跳转到+64 结束,成功
.可以看出,这是一个循环比较.等价于下面的 c 语 a 言
1
2
3
4
|
for(int *b = &r[1]; b != &r[6]; b++)
{
if(*b != 2 * (*(b - 1)))
call explode_bomb;
|
故答案应该为 1 2 4 8 16 32.
phase_3
1
2
3
4
|
0x0000000000400ef1 <+14>: mov $0x4027cd,%esi
0x0000000000400ef6 <+19>: mov $0x0,%eax
0x0000000000400efb <+24>: callq 0x400ba0 <__isoc99_sscanf@plt>
0x0000000000400f00 <+29>: cmp $0x1,%eax
|
查看 0x4027cd,
1
2
|
(gdb) x/s 0x4027cd
0x4027cd: "%d %d"
|
可知,应该是读入了两个整数.
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
|
0x0000000000400f15 <+50>: jmpq *0x402500(,%rax,8)
0x0000000000400f1c <+57>: mov $0x0,%eax
0x0000000000400f21 <+62>: jmp 0x400f28 <phase_3+69>
0x0000000000400f23 <+64>: mov $0x19c,%eax
0x0000000000400f28 <+69>: sub $0xcd,%eax
0x0000000000400f2d <+74>: jmp 0x400f34 <phase_3+81>
0x0000000000400f2f <+76>: mov $0x0,%eax
0x0000000000400f34 <+81>: add $0x29b,%eax
0x0000000000400f39 <+86>: jmp 0x400f40 <phase_3+93>
0x0000000000400f3b <+88>: mov $0x0,%eax
---Type <return> to continue, or q <return> to quit---
0x0000000000400f40 <+93>: sub $0x36f,%eax
0x0000000000400f45 <+98>: jmp 0x400f4c <phase_3+105>
0x0000000000400f47 <+100>: mov $0x0,%eax
0x0000000000400f4c <+105>: add $0x36f,%eax
0x0000000000400f51 <+110>: jmp 0x400f58 <phase_3+117>
0x0000000000400f53 <+112>: mov $0x0,%eax
0x0000000000400f58 <+117>: sub $0x36f,%eax
0x0000000000400f5d <+122>: jmp 0x400f64 <phase_3+129>
0x0000000000400f5f <+124>: mov $0x0,%eax
0x0000000000400f64 <+129>: add $0x36f,%eax
0x0000000000400f69 <+134>: jmp 0x400f70 <phase_3+141>
0x0000000000400f6b <+136>: mov $0x0,%eax
0x0000000000400f70 <+141>: sub $0x36f,%eax
0x0000000000400f75 <+146>: jmp 0x400f81 <phase_3+158>
0x0000000000400f77 <+148>: callq 0x4014e4 <explode_bomb>
0x0000000000400f7c <+153>: mov $0x0,%eax
0x0000000000400f81 <+158>: cmpl $0x5,0xc(%rsp)
0x0000000000400f86 <+163>: jg 0x400f8e <phase_3+171>
0x0000000000400f88 <+165>: cmp 0x8(%rsp),%eax
0x0000000000400f8c <+169>: je 0x400f93 <phase_3+176>
0x0000000000400f8e <+171>: callq 0x4014e4 <explode_bomb>
|
由这段汇编代码可知,这是一段 switch 语句,使用输入的第一个值作为 key,
经过对应跳转位置的操作后应与第二个数相等.
1
2
|
(gdb) p/x *(0x402500 + 32)
$1 = 0x400f47
|
那么第一个数为 0 时,跳转到 0x400f23 处,那么第二个数应该为此处的 0x0,
故一组答案为 4 0;
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
|
(gdb) disas phase_4
Dump of assembler code for function phase_4:
0x0000000000400fd0 <+0>: sub $0x18,%rsp
0x0000000000400fd4 <+4>: lea 0xc(%rsp),%rcx
0x0000000000400fd9 <+9>: lea 0x8(%rsp),%rdx
0x0000000000400fde <+14>: mov $0x4027cd,%esi
0x0000000000400fe3 <+19>: mov $0x0,%eax
0x0000000000400fe8 <+24>: callq 0x400ba0 <__isoc99_sscanf@plt>
0x0000000000400fed <+29>: cmp $0x2,%eax
0x0000000000400ff0 <+32>: jne 0x400ffe <phase_4+46>
0x0000000000400ff2 <+34>: mov 0xc(%rsp),%eax
0x0000000000400ff6 <+38>: sub $0x2,%eax
0x0000000000400ff9 <+41>: cmp $0x2,%eax
0x0000000000400ffc <+44>: jbe 0x401003 <phase_4+51>
0x0000000000400ffe <+46>: callq 0x4014e4 <explode_bomb>
0x0000000000401003 <+51>: mov 0xc(%rsp),%esi
0x0000000000401007 <+55>: mov $0x9,%edi
0x000000000040100c <+60>: callq 0x400f98 <func4>
0x0000000000401011 <+65>: cmp 0x8(%rsp),%eax
0x0000000000401015 <+69>: je 0x40101c <phase_4+76>
0x0000000000401017 <+71>: callq 0x4014e4 <explode_bomb>
0x000000000040101c <+76>: add $0x18,%rsp
0x0000000000401020 <+80>: retq
End of assembler dump.
|
由代码易知,phase_4 读入了两个数,第二个数在 2-4 之间,然后将第二个数作为
func4 的第二个参数,func4 第一个参数为 9,输入的第一个数必须和 func4 返回值相等.
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
|
(gdb) disas func4
Dump of assembler code for function func4:
0x0000000000400f98 <+0>: push %r12
0x0000000000400f9a <+2>: push %rbp
0x0000000000400f9b <+3>: push %rbx
0x0000000000400f9c <+4>: mov %edi,%ebx
0x0000000000400f9e <+6>: test %edi,%edi
0x0000000000400fa0 <+8>: jle 0x400fc6 <func4+46>
0x0000000000400fa2 <+10>: mov %esi,%ebp
0x0000000000400fa4 <+12>: mov %esi,%eax
0x0000000000400fa6 <+14>: cmp $0x1,%edi
0x0000000000400fa9 <+17>: je 0x400fcb <func4+51>
0x0000000000400fab <+19>: lea -0x1(%rdi),%edi
0x0000000000400fae <+22>: callq 0x400f98 <func4>
0x0000000000400fb3 <+27>: lea (%rax,%rbp,1),%r12d
0x0000000000400fb7 <+31>: lea -0x2(%rbx),%edi
0x0000000000400fba <+34>: mov %ebp,%esi
0x0000000000400fbc <+36>: callq 0x400f98 <func4>
0x0000000000400fc1 <+41>: add %r12d,%eax
0x0000000000400fc4 <+44>: jmp 0x400fcb <func4+51>
0x0000000000400fc6 <+46>: mov $0x0,%eax
0x0000000000400fcb <+51>: pop %rbx
0x0000000000400fcc <+52>: pop %rbp
0x0000000000400fcd <+53>: pop %r12
0x0000000000400fcf <+55>: retq
End of assembler dump.
|
此函数等价于下面的 c 代码
1
2
3
4
5
6
7
8
9
|
int func4(int a, int b)
{
if(a <= 0)
return 0;
if(a == 1)
return b;
return b + func4(a - 1, b) + func4(n - 2, b);
}
|
穷举 2-4 的值即可得到答案,取答案为 176 2
phase_5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
(gdb) disas phase_5
Dump of assembler code for function phase_5:
0x0000000000401021 <+0>: push %rbx
0x0000000000401022 <+1>: mov %rdi,%rbx
0x0000000000401025 <+4>: callq 0x401261 <string_length>
0x000000000040102a <+9>: cmp $0x6,%eax
0x000000000040102d <+12>: je 0x401034 <phase_5+19>
0x000000000040102f <+14>: callq 0x4014e4 <explode_bomb>
0x0000000000401034 <+19>: mov $0x0,%eax
0x0000000000401039 <+24>: mov $0x0,%edx
0x000000000040103e <+29>: movzbl (%rbx,%rax,1),%ecx
0x0000000000401042 <+33>: and $0xf,%ecx
0x0000000000401045 <+36>: add 0x402540(,%rcx,4),%edx
0x000000000040104c <+43>: add $0x1,%rax
0x0000000000401050 <+47>: cmp $0x6,%rax
0x0000000000401054 <+51>: jne 0x40103e <phase_5+29>
0x0000000000401056 <+53>: cmp $0x27,%edx
0x0000000000401059 <+56>: je 0x401060 <phase_5+63>
0x000000000040105b <+58>: callq 0x4014e4 <explode_bomb>
0x0000000000401060 <+63>: pop %rbx
0x0000000000401061 <+64>: retq
End of assembler dump.
|
由汇编代码可知,需要输入一个长度为 6 的字符串.令该字符串为 input,+36 处出现的
数组为 array,则该汇编等价于下面代码.
1
2
|
for(int i = 0; i < 6; i++)
sum += array[ input[i] & 0xf ];
|
意为遍历输入字符串,取该字符串低 4 位作为 array 下标,取出 array 值相加.
查看 array 的值
1
2
3
|
(gdb) p/x *0x402540@16
$2 = {0x2, 0xa, 0x6, 0x1, 0xc, 0x10, 0x9, 0x3, 0x4, 0x7, 0xe, 0x5, 0xb, 0x8,
0xf, 0xd}
|
题目要求 sum = 0x27,故从 array 中选出 6 个和为 0x27 的数,通过这 6 个数的下标找出对应字符.
答案应为 01347L;
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
|
(gdb) disas phase_6
Dump of assembler code for function phase_6:
0x0000000000401062 <+0>: push %r13
0x0000000000401064 <+2>: push %r12
0x0000000000401066 <+4>: push %rbp
0x0000000000401067 <+5>: push %rbx
0x0000000000401068 <+6>: sub $0x58,%rsp
0x000000000040106c <+10>: lea 0x30(%rsp),%rsi
0x0000000000401071 <+15>: callq 0x40151a <read_six_numbers>
0x0000000000401076 <+20>: lea 0x30(%rsp),%r13
0x000000000040107b <+25>: mov $0x0,%r12d
0x0000000000401081 <+31>: mov %r13,%rbp
0x0000000000401084 <+34>: mov 0x0(%r13),%eax
0x0000000000401088 <+38>: sub $0x1,%eax
0x000000000040108b <+41>: cmp $0x5,%eax
0x000000000040108e <+44>: jbe 0x401095 <phase_6+51>
0x0000000000401090 <+46>: callq 0x4014e4 <explode_bomb>
0x0000000000401095 <+51>: add $0x1,%r12d
0x0000000000401099 <+55>: cmp $0x6,%r12d
0x000000000040109d <+59>: jne 0x4010a6 <phase_6+68>
0x000000000040109f <+61>: mov $0x0,%esi
0x00000000004010a4 <+66>: jmp 0x4010e8 <phase_6+134>
0x00000000004010a6 <+68>: mov %r12d,%ebx
0x00000000004010a9 <+71>: movslq %ebx,%rax
---Type <return> to continue, or q <return> to quit---
0x00000000004010ac <+74>: mov 0x30(%rsp,%rax,4),%eax
0x00000000004010b0 <+78>: cmp %eax,0x0(%rbp)
0x00000000004010b3 <+81>: jne 0x4010ba <phase_6+88>
0x00000000004010b5 <+83>: callq 0x4014e4 <explode_bomb>
0x00000000004010ba <+88>: add $0x1,%ebx
0x00000000004010bd <+91>: cmp $0x5,%ebx
0x00000000004010c0 <+94>: jle 0x4010a9 <phase_6+71>
0x00000000004010c2 <+96>: add $0x4,%r13
0x00000000004010c6 <+100>: jmp 0x401081 <phase_6+31>
0x00000000004010c8 <+102>: mov 0x8(%rdx),%rdx
0x00000000004010cc <+106>: add $0x1,%eax
0x00000000004010cf <+109>: cmp %ecx,%eax
0x00000000004010d1 <+111>: jne 0x4010c8 <phase_6+102>
0x00000000004010d3 <+113>: jmp 0x4010da <phase_6+120>
0x00000000004010d5 <+115>: mov $0x603410,%edx
0x00000000004010da <+120>: mov %rdx,(%rsp,%rsi,2)
0x00000000004010de <+124>: add $0x4,%rsi
0x00000000004010e2 <+128>: cmp $0x18,%rsi
0x00000000004010e6 <+132>: je 0x4010fd <phase_6+155>
0x00000000004010e8 <+134>: mov 0x30(%rsp,%rsi,1),%ecx
0x00000000004010ec <+138>: cmp $0x1,%ecx
0x00000000004010ef <+141>: jle 0x4010d5 <phase_6+115>
0x00000000004010f1 <+143>: mov $0x1,%eax
---Type <return> to continue, or q <return> to quit---
0x00000000004010f6 <+148>: mov $0x603410,%edx
0x00000000004010fb <+153>: jmp 0x4010c8 <phase_6+102>
0x00000000004010fd <+155>: mov (%rsp),%rbx
0x0000000000401101 <+159>: lea 0x8(%rsp),%rax
0x0000000000401106 <+164>: lea 0x30(%rsp),%rsi
0x000000000040110b <+169>: mov %rbx,%rcx
0x000000000040110e <+172>: mov (%rax),%rdx
0x0000000000401111 <+175>: mov %rdx,0x8(%rcx)
0x0000000000401115 <+179>: add $0x8,%rax
0x0000000000401119 <+183>: cmp %rsi,%rax
0x000000000040111c <+186>: je 0x401123 <phase_6+193>
0x000000000040111e <+188>: mov %rdx,%rcx
0x0000000000401121 <+191>: jmp 0x40110e <phase_6+172>
0x0000000000401123 <+193>: movq $0x0,0x8(%rdx)
0x000000000040112b <+201>: mov $0x5,%ebp
0x0000000000401130 <+206>: mov 0x8(%rbx),%rax
0x0000000000401134 <+210>: mov (%rax),%eax
0x0000000000401136 <+212>: cmp %eax,(%rbx)
0x0000000000401138 <+214>: jge 0x40113f <phase_6+221>
0x000000000040113a <+216>: callq 0x4014e4 <explode_bomb>
0x000000000040113f <+221>: mov 0x8(%rbx),%rbx
0x0000000000401143 <+225>: sub $0x1,%ebp
0x0000000000401146 <+228>: jne 0x401130 <phase_6+206>
---Type <return> to continue, or q <return> to quit---
0x0000000000401148 <+230>: add $0x58,%rsp
0x000000000040114c <+234>: pop %rbx
0x000000000040114d <+235>: pop %rbp
0x000000000040114e <+236>: pop %r12
0x0000000000401150 <+238>: pop %r13
0x0000000000401152 <+240>: retq
End of assembler dump.
|
汇编代码很长.其意为输入 6 个互不相等的数,介于 1-6.按这 6 个数的值从位于地址 0x603410 的链表中选出对应位置的
节点指针,组成一个数组.按选出的顺序将这六个节点组成新的链表,然后检查这个链表是否为降序.
查看链表的值.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
(gdb) p/x *(0x603410)
$3 = 0x1cf
(gdb) p/x *(0x603410 + 8)
$4 = 0x603420
(gdb) p/x *(0x603420)
$5 = 0x188
(gdb) p/x *(0x603420 + 8)
$6 = 0x603430
(gdb) p/x *(0x603430)
$7 = 0x1d1
(gdb) p/x *(0x603430 + 8)
$8 = 0x603440
(gdb) p/x *(0x603440)
$9 = 0x174
(gdb) p/x *(0x603440 + 8)
$10 = 0x603450
(gdb) p/x *(0x603450)
$11 = 0x220
(gdb) p/x *(0x603450 + 8)
$12 = 0x603460
(gdb) p/x *(0x603460 + 8)
$13 = 0x0
|
故答案应为 6 5 3 1 2 4;
secret_phase
正常通过前 6 关是无法触发 secret_phase 的,查看汇编发现,在 phase_4 答案之后输入 DrEvil 即可进入 secret_phase.
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
|
(gdb) disas secret_phase
Dump of assembler code for function secret_phase:
0x0000000000401191 <+0>: push %rbx
0x0000000000401192 <+1>: callq 0x40155c <read_line>
0x0000000000401197 <+6>: mov $0xa,%edx
0x000000000040119c <+11>: mov $0x0,%esi
0x00000000004011a1 <+16>: mov %rax,%rdi
0x00000000004011a4 <+19>: callq 0x400b80 <strtol@plt>
0x00000000004011a9 <+24>: mov %rax,%rbx
0x00000000004011ac <+27>: lea -0x1(%rax),%eax
0x00000000004011af <+30>: cmp $0x3e8,%eax
0x00000000004011b4 <+35>: jbe 0x4011bb <secret_phase+42>
0x00000000004011b6 <+37>: callq 0x4014e4 <explode_bomb>
0x00000000004011bb <+42>: mov %ebx,%esi
0x00000000004011bd <+44>: mov $0x603230,%edi
0x00000000004011c2 <+49>: callq 0x401153 <fun7>
0x00000000004011c7 <+54>: cmp $0x4,%eax
0x00000000004011ca <+57>: je 0x4011d1 <secret_phase+64>
0x00000000004011cc <+59>: callq 0x4014e4 <explode_bomb>
0x00000000004011d1 <+64>: mov $0x4024d0,%edi
0x00000000004011d6 <+69>: callq 0x400ac0 <puts@plt>
0x00000000004011db <+74>: callq 0x401682 <phase_defused>
0x00000000004011e0 <+79>: pop %rbx
0x00000000004011e1 <+80>: retq
---Type <return> to continue, or q <return> to quit---
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
|
(gdb) disas fun7
Dump of assembler code for function fun7:
0x0000000000401153 <+0>: sub $0x8,%rsp
0x0000000000401157 <+4>: test %rdi,%rdi
0x000000000040115a <+7>: je 0x401187 <fun7+52>
0x000000000040115c <+9>: mov (%rdi),%edx
0x000000000040115e <+11>: cmp %esi,%edx
0x0000000000401160 <+13>: jle 0x40116f <fun7+28>
0x0000000000401162 <+15>: mov 0x8(%rdi),%rdi
0x0000000000401166 <+19>: callq 0x401153 <fun7>
0x000000000040116b <+24>: add %eax,%eax
0x000000000040116d <+26>: jmp 0x40118c <fun7+57>
0x000000000040116f <+28>: mov $0x0,%eax
0x0000000000401174 <+33>: cmp %esi,%edx
0x0000000000401176 <+35>: je 0x40118c <fun7+57>
0x0000000000401178 <+37>: mov 0x10(%rdi),%rdi
0x000000000040117c <+41>: callq 0x401153 <fun7>
0x0000000000401181 <+46>: lea 0x1(%rax,%rax,1),%eax
0x0000000000401185 <+50>: jmp 0x40118c <fun7+57>
0x0000000000401187 <+52>: mov $0xffffffff,%eax
0x000000000040118c <+57>: add $0x8,%rsp
0x0000000000401190 <+61>: retq
End of assembler dump.
|
此题题意为在一个题目中构建好的平衡二叉树中从根节点开始查找一个输入的数.
由节点向左为 0,由节点向右为 1,查找路径序的 0-1 列从右向左构成一个二进制数,该
二进制数的十进制值必须等于题目中提供的数,其为 4,那么所需查找路径序列为 100,
根据二叉树结构,应该查找 7,故答案为 7.
运行截图