phase_1
采用disas phase_1生成对应汇编代码:
1 2 3 4 5 6 7 8
| 0x0000000000400ee0 <+0>: sub $0x8,%rsp 0x0000000000400ee4 <+4>: mov $0x402400,%esi 0x0000000000400ee9 <+9>: call 0x401338 <strings_not_equal> 0x0000000000400eee <+14>: test %eax,%eax 0x0000000000400ef0 <+16>: je 0x400ef7 <phase_1+23> 0x0000000000400ef2 <+18>: call 0x40143a <explode_bomb> 0x0000000000400ef7 <+23>: add $0x8,%rsp 0x0000000000400efb <+27>: ret
|
<phase_1+9>处可以看出该句执行的是字符串比较,如果输入字符与0x402400处的不一致就发生爆炸。
使用print (char*)0x402400打印目标字符串,结果为Border relations with Canada have never been better.。
故phase_1的答案为:
1
| Border relations with Canada have never been better.
|
phase_2
采用disas 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
| 0x0000000000400efc <+0>: push %rbp 0x0000000000400efd <+1>: push %rbx 0x0000000000400efe <+2>: sub $0x28,%rsp 0x0000000000400f02 <+6>: mov %rsp,%rsi 0x0000000000400f05 <+9>: call 0x40145c <read_six_numbers> 0x0000000000400f0a <+14>: cmpl $0x1,(%rsp) 0x0000000000400f0e <+18>: je 0x400f30 <phase_2+52> 0x0000000000400f10 <+20>: call 0x40143a <explode_bomb> 0x0000000000400f15 <+25>: jmp 0x400f30 <phase_2+52> 0x0000000000400f17 <+27>: mov -0x4(%rbx),%eax 0x0000000000400f1a <+30>: add %eax,%eax 0x0000000000400f1c <+32>: cmp %eax,(%rbx) 0x0000000000400f1e <+34>: je 0x400f25 <phase_2+41> 0x0000000000400f20 <+36>: call 0x40143a <explode_bomb> 0x0000000000400f25 <+41>: add $0x4,%rbx 0x0000000000400f29 <+45>: cmp %rbp,%rbx 0x0000000000400f2c <+48>: jne 0x400f17 <phase_2+27> 0x0000000000400f2e <+50>: jmp 0x400f3c <phase_2+64> 0x0000000000400f30 <+52>: lea 0x4(%rsp),%rbx 0x0000000000400f35 <+57>: lea 0x18(%rsp),%rbp 0x0000000000400f3a <+62>: jmp 0x400f17 <phase_2+27> 0x0000000000400f3c <+64>: add $0x28,%rsp 0x0000000000400f40 <+68>: pop %rbx 0x0000000000400f41 <+69>: pop %rbp 0x0000000000400f42 <+70>: ret
|
<phase_2+9>处表明,该函数需要输入的是6个数值,<phase_2+48>处表明,该函数存在一个循环,循环节如下:
1 2 3 4 5 6 7 8
| 0x0000000000400f17 <+27>: mov -0x4(%rbx),%eax 0x0000000000400f1a <+30>: add %eax,%eax 0x0000000000400f1c <+32>: cmp %eax,(%rbx) 0x0000000000400f1e <+34>: je 0x400f25 <phase_2+41> 0x0000000000400f20 <+36>: call 0x40143a <explode_bomb> 0x0000000000400f25 <+41>: add $0x4,%rbx 0x0000000000400f29 <+45>: cmp %rbp,%rbx 0x0000000000400f2c <+48>: jne 0x400f17 <phase_2+27>
|
显然为一个数组结构,当a[i] + a[i] != a[i + 1]时被引爆。
同时,由<phase_2+14>处可以推出,a[0] = 1。
故phase_2的答案为:
phase_3
采用disas 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
| 0x0000000000400f43 <+0>: sub $0x18,%rsp 0x0000000000400f47 <+4>: lea 0xc(%rsp),%rcx 0x0000000000400f4c <+9>: lea 0x8(%rsp),%rdx 0x0000000000400f51 <+14>: mov $0x4025cf,%esi 0x0000000000400f56 <+19>: mov $0x0,%eax 0x0000000000400f5b <+24>: call 0x400bf0 <__isoc99_sscanf@plt> 0x0000000000400f60 <+29>: cmp $0x1,%eax 0x0000000000400f63 <+32>: jg 0x400f6a <phase_3+39> 0x0000000000400f65 <+34>: call 0x40143a <explode_bomb> 0x0000000000400f6a <+39>: cmpl $0x7,0x8(%rsp) 0x0000000000400f6f <+44>: ja 0x400fad <phase_3+106> 0x0000000000400f71 <+46>: mov 0x8(%rsp),%eax 0x0000000000400f75 <+50>: jmp *0x402470(,%rax,8) 0x0000000000400f7c <+57>: mov $0xcf,%eax 0x0000000000400f81 <+62>: jmp 0x400fbe <phase_3+123> 0x0000000000400f83 <+64>: mov $0x2c3,%eax 0x0000000000400f88 <+69>: jmp 0x400fbe <phase_3+123> 0x0000000000400f8a <+71>: mov $0x100,%eax 0x0000000000400f8f <+76>: jmp 0x400fbe <phase_3+123> 0x0000000000400f91 <+78>: mov $0x185,%eax 0x0000000000400f96 <+83>: jmp 0x400fbe <phase_3+123> 0x0000000000400f98 <+85>: mov $0xce,%eax 0x0000000000400f9d <+90>: jmp 0x400fbe <phase_3+123> 0x0000000000400f9f <+92>: mov $0x2aa,%eax 0x0000000000400fa4 <+97>: jmp 0x400fbe <phase_3+123> 0x0000000000400fa6 <+99>: mov $0x147,%eax 0x0000000000400fab <+104>: jmp 0x400fbe <phase_3+123> 0x0000000000400fad <+106>: call 0x40143a <explode_bomb> 0x0000000000400fb2 <+111>: mov $0x0,%eax 0x0000000000400fb7 <+116>: jmp 0x400fbe <phase_3+123> 0x0000000000400fb9 <+118>: mov $0x137,%eax 0x0000000000400fbe <+123>: cmp 0xc(%rsp),%eax 0x0000000000400fc2 <+127>: je 0x400fc9 <phase_3+134> 0x0000000000400fc4 <+129>: call 0x40143a <explode_bomb> 0x0000000000400fc9 <+134>: add $0x18,%rsp 0x0000000000400fcd <+138>: ret
|
开始时解析输入字符串:
1 2 3 4 5
| 0x0000000000400f47 <+4>: lea 0xc(%rsp),%rcx 0x0000000000400f4c <+9>: lea 0x8(%rsp),%rdx 0x0000000000400f51 <+14>: mov $0x4025cf,%esi 0x0000000000400f56 <+19>: mov $0x0,%eax 0x0000000000400f5b <+24>: call 0x400bf0 <__isoc99_sscanf@plt>
|
print (char*)0x4025cf获得"%d %d",即输入两个整数。
由<phase_3+39>可知,输入的第一个数一定在被视为无符号整数时小于等于7。
在<phase_3+50>处可知,根据输入的第一个参数进行跳转表查询后进行跳转。使用x/8xg 0x402470获取跳转表:
1 2 3 4
| 0x402470: 0x0000000000400f7c 0x0000000000400fb9 0x402480: 0x0000000000400f83 0x0000000000400f8a 0x402490: 0x0000000000400f91 0x0000000000400f98 0x4024a0: 0x0000000000400f9f 0x0000000000400fa6
|
跳转表中全部值均对应下述分支。
在<phase_3+127>处可知,第二个参数应该和第一个数跳转后的赋值相同。
故答案有多个,依次为(一行一个答案):
1 2 3 4 5 6 7 8
| 0 207 1 311 2 707 3 256 4 389 5 206 6 682 7 327
|
phase_4
采用disas phase_4生成对应汇编代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 0x000000000040100c <+0>: sub $0x18,%rsp 0x0000000000401010 <+4>: lea 0xc(%rsp),%rcx 0x0000000000401015 <+9>: lea 0x8(%rsp),%rdx 0x000000000040101a <+14>: mov $0x4025cf,%esi 0x000000000040101f <+19>: mov $0x0,%eax 0x0000000000401024 <+24>: call 0x400bf0 <__isoc99_sscanf@plt> 0x0000000000401029 <+29>: cmp $0x2,%eax 0x000000000040102c <+32>: jne 0x401035 <phase_4+41> 0x000000000040102e <+34>: cmpl $0xe,0x8(%rsp) 0x0000000000401033 <+39>: jbe 0x40103a <phase_4+46> 0x0000000000401035 <+41>: call 0x40143a <explode_bomb> 0x000000000040103a <+46>: mov $0xe,%edx 0x000000000040103f <+51>: mov $0x0,%esi 0x0000000000401044 <+56>: mov 0x8(%rsp),%edi 0x0000000000401048 <+60>: call 0x400fce <func4> 0x000000000040104d <+65>: test %eax,%eax 0x000000000040104f <+67>: jne 0x401058 <phase_4+76> 0x0000000000401051 <+69>: cmpl $0x0,0xc(%rsp) 0x0000000000401056 <+74>: je 0x40105d <phase_4+81> 0x0000000000401058 <+76>: call 0x40143a <explode_bomb> 0x000000000040105d <+81>: add $0x18,%rsp 0x0000000000401061 <+85>: ret
|
如上文,0x4025cf处为"%d %d",即解析两个整数。
<phase_4+34>处表明,第一个参数应当小于等于15。
<phase_4+60>调用了函数func4。其中func4第一个参数与phase_4第一个参数相同,第二、三个参数分别为0和14。
<phase_4+65>处表明,func4的返回值应当为0。
<phase_4+65>处表明,执行func4后第二个参数应当为0。
使用disas func4对func4反编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 0x0000000000400fce <+0>: sub $0x8,%rsp 0x0000000000400fd2 <+4>: mov %edx,%eax 0x0000000000400fd4 <+6>: sub %esi,%eax 0x0000000000400fd6 <+8>: mov %eax,%ecx 0x0000000000400fd8 <+10>: shr $0x1f,%ecx 0x0000000000400fdb <+13>: add %ecx,%eax 0x0000000000400fdd <+15>: sar %eax 0x0000000000400fdf <+17>: lea (%rax,%rsi,1),%ecx 0x0000000000400fe2 <+20>: cmp %edi,%ecx 0x0000000000400fe4 <+22>: jle 0x400ff2 <func4+36> 0x0000000000400fe6 <+24>: lea -0x1(%rcx),%edx 0x0000000000400fe9 <+27>: call 0x400fce <func4> 0x0000000000400fee <+32>: add %eax,%eax 0x0000000000400ff0 <+34>: jmp 0x401007 <func4+57> 0x0000000000400ff2 <+36>: mov $0x0,%eax 0x0000000000400ff7 <+41>: cmp %edi,%ecx 0x0000000000400ff9 <+43>: jge 0x401007 <func4+57> 0x0000000000400ffb <+45>: lea 0x1(%rcx),%esi 0x0000000000400ffe <+48>: call 0x400fce <func4> 0x0000000000401003 <+53>: lea 0x1(%rax,%rax,1),%eax 0x0000000000401007 <+57>: add $0x8,%rsp 0x000000000040100b <+61>: ret
|
可以看出func4是一个递归程序,翻译成C语言代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int func4(int edi, int esi, int edx) { int eax = edx - esi; eax = (eax + (eax < 0)) / 2; int ecx = eax + esi; if(ecx <= edi) { eax = 0; if(ecx >= edi) { return eax; } esi = ecx + 1; eax = func4(edi, esi, edx); return 2 * eax + 1; } else { edx = ecx - 1; eax = func4(edi, esi, edx); return 2 * eax; } }
|
于是问题变为使func4(x, 0, 14)为0的x值。
观察可得,只有当递归末端从1或3出口出,其他递归层均从3出口出时才为0。
同时,函数参数有如下变化:
1 2 3 4 5 6
| # 2出口进入时 edi = edi, esi = ecx + 1, edx = edx # 3出口进入时 edi = edi, esi = esi, edx = ecx - 1
ecx = esi + (edx > esi ? (edx - esi) / 2 : (edx - esi + 1) / 2)
|
因为输入的esi = 0,edx = 14,每次要求均从1或3出口出,所以有:
1
| 1: ecx = 7, 此时可以有edi = ecx <= 15,故可以直接另x = 15,直接返回。
|
故答案是:
phase_5
采用disas 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 37 38
| 0x0000000000401062 <+0>: push %rbx 0x0000000000401063 <+1>: sub $0x20,%rsp 0x0000000000401067 <+5>: mov %rdi,%rbx 0x000000000040106a <+8>: mov %fs:0x28,%rax 0x0000000000401073 <+17>: mov %rax,0x18(%rsp) 0x0000000000401078 <+22>: xor %eax,%eax 0x000000000040107a <+24>: call 0x40131b <string_length> 0x000000000040107f <+29>: cmp $0x6,%eax 0x0000000000401082 <+32>: je 0x4010d2 <phase_5+112> 0x0000000000401084 <+34>: call 0x40143a <explode_bomb> 0x0000000000401089 <+39>: jmp 0x4010d2 <phase_5+112> 0x000000000040108b <+41>: movzbl (%rbx,%rax,1),%ecx 0x000000000040108f <+45>: mov %cl,(%rsp) 0x0000000000401092 <+48>: mov (%rsp),%rdx 0x0000000000401096 <+52>: and $0xf,%edx 0x0000000000401099 <+55>: movzbl 0x4024b0(%rdx),%edx 0x00000000004010a0 <+62>: mov %dl,0x10(%rsp,%rax,1) 0x00000000004010a4 <+66>: add $0x1,%rax 0x00000000004010a8 <+70>: cmp $0x6,%rax 0x00000000004010ac <+74>: jne 0x40108b <phase_5+41> 0x00000000004010ae <+76>: movb $0x0,0x16(%rsp) 0x00000000004010b3 <+81>: mov $0x40245e,%esi 0x00000000004010b8 <+86>: lea 0x10(%rsp),%rdi 0x00000000004010bd <+91>: call 0x401338 <strings_not_equal> 0x00000000004010c2 <+96>: test %eax,%eax 0x00000000004010c4 <+98>: je 0x4010d9 <phase_5+119> 0x00000000004010c6 <+100>: call 0x40143a <explode_bomb> 0x00000000004010cb <+105>: nopl 0x0(%rax,%rax,1) 0x00000000004010d0 <+110>: jmp 0x4010d9 <phase_5+119> 0x00000000004010d2 <+112>: mov $0x0,%eax 0x00000000004010d7 <+117>: jmp 0x40108b <phase_5+41> 0x00000000004010d9 <+119>: mov 0x18(%rsp),%rax 0x00000000004010de <+124>: xor %fs:0x28,%rax 0x00000000004010e7 <+133>: je 0x4010ee <phase_5+140> 0x00000000004010e9 <+135>: call 0x400b30 <__stack_chk_fail@plt> 0x00000000004010ee <+140>: add $0x20,%rsp 0x00000000004010f2 <+144>: pop %rbx 0x00000000004010f3 <+145>: ret
|
由<phase_5+24>可知输入的是字符串,根据<phase_5+29>可知长度为6。
很显然,存在一个循环,循环节为:
1 2 3 4 5 6 7 8 9
| 0x000000000040108b <+41>: movzbl (%rbx,%rax,1),%ecx 0x000000000040108f <+45>: mov %cl,(%rsp) 0x0000000000401092 <+48>: mov (%rsp),%rdx 0x0000000000401096 <+52>: and $0xf,%edx 0x0000000000401099 <+55>: movzbl 0x4024b0(%rdx),%edx 0x00000000004010a0 <+62>: mov %dl,0x10(%rsp,%rax,1) 0x00000000004010a4 <+66>: add $0x1,%rax 0x00000000004010a8 <+70>: cmp $0x6,%rax 0x00000000004010ac <+74>: jne 0x40108b <phase_5+41>
|
该循环将位于0x4024b0的字符串按照一定规则搬运到0x10(%rsp)处,其中每一个规则为映射后的字符串是0x4024b0的字符串取对应下标的输入字符串对应的整数的后4位的结果。
<phase_5+91>表明获得的字符串应当与位于0x40245e的字符串相同。
使用p (char*)0x4024b0打印0x4024b0字符串,取前16位的结果如下:
1
| 0x4024b0 <array> "maduiersnfotvbyl"
|
使用p (char*)0x40245e打印0x40245e字符串,结果如下:
即输入的字符串对应的后4位的值应为:
为了便于输入,将其映射到a-o即可,故答案为:
phase_6
采用disas 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 83 84 85 86
| 0x00000000004010f4 <+0>: push %r14 0x00000000004010f6 <+2>: push %r13 0x00000000004010f8 <+4>: push %r12 0x00000000004010fa <+6>: push %rbp 0x00000000004010fb <+7>: push %rbx 0x00000000004010fc <+8>: sub $0x50,%rsp 0x0000000000401100 <+12>: mov %rsp,%r13 0x0000000000401103 <+15>: mov %rsp,%rsi 0x0000000000401106 <+18>: call 0x40145c <read_six_numbers> 0x000000000040110b <+23>: mov %rsp,%r14 0x000000000040110e <+26>: mov $0x0,%r12d 0x0000000000401114 <+32>: mov %r13,%rbp 0x0000000000401117 <+35>: mov 0x0(%r13),%eax 0x000000000040111b <+39>: sub $0x1,%eax 0x000000000040111e <+42>: cmp $0x5,%eax 0x0000000000401121 <+45>: jbe 0x401128 <phase_6+52> 0x0000000000401123 <+47>: call 0x40143a <explode_bomb> 0x0000000000401128 <+52>: add $0x1,%r12d 0x000000000040112c <+56>: cmp $0x6,%r12d 0x0000000000401130 <+60>: je 0x401153 <phase_6+95> 0x0000000000401132 <+62>: mov %r12d,%ebx 0x0000000000401135 <+65>: movslq %ebx,%rax 0x0000000000401138 <+68>: mov (%rsp,%rax,4),%eax 0x000000000040113b <+71>: cmp %eax,0x0(%rbp) 0x000000000040113e <+74>: jne 0x401145 <phase_6+81> 0x0000000000401140 <+76>: call 0x40143a <explode_bomb> 0x0000000000401145 <+81>: add $0x1,%ebx 0x0000000000401148 <+84>: cmp $0x5,%ebx 0x000000000040114b <+87>: jle 0x401135 <phase_6+65> 0x000000000040114d <+89>: add $0x4,%r13 0x0000000000401151 <+93>: jmp 0x401114 <phase_6+32> 0x0000000000401153 <+95>: lea 0x18(%rsp),%rsi 0x0000000000401158 <+100>: mov %r14,%rax 0x000000000040115b <+103>: mov $0x7,%ecx 0x0000000000401160 <+108>: mov %ecx,%edx 0x0000000000401162 <+110>: sub (%rax),%edx 0x0000000000401164 <+112>: mov %edx,(%rax) 0x0000000000401166 <+114>: add $0x4,%rax 0x000000000040116a <+118>: cmp %rsi,%rax 0x000000000040116d <+121>: jne 0x401160 <phase_6+108> 0x000000000040116f <+123>: mov $0x0,%esi 0x0000000000401174 <+128>: jmp 0x401197 <phase_6+163> 0x0000000000401176 <+130>: mov 0x8(%rdx),%rdx 0x000000000040117a <+134>: add $0x1,%eax 0x000000000040117d <+137>: cmp %ecx,%eax 0x000000000040117f <+139>: jne 0x401176 <phase_6+130> 0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148> 0x0000000000401183 <+143>: mov $0x6032d0,%edx 0x0000000000401188 <+148>: mov %rdx,0x20(%rsp,%rsi,2) 0x000000000040118d <+153>: add $0x4,%rsi 0x0000000000401191 <+157>: cmp $0x18,%rsi 0x0000000000401195 <+161>: je 0x4011ab <phase_6+183> 0x0000000000401197 <+163>: mov (%rsp,%rsi,1),%ecx 0x000000000040119a <+166>: cmp $0x1,%ecx 0x000000000040119d <+169>: jle 0x401183 <phase_6+143> 0x000000000040119f <+171>: mov $0x1,%eax 0x00000000004011a4 <+176>: mov $0x6032d0,%edx 0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130> 0x00000000004011ab <+183>: mov 0x20(%rsp),%rbx 0x00000000004011b0 <+188>: lea 0x28(%rsp),%rax 0x00000000004011b5 <+193>: lea 0x50(%rsp),%rsi 0x00000000004011ba <+198>: mov %rbx,%rcx 0x00000000004011bd <+201>: mov (%rax),%rdx 0x00000000004011c0 <+204>: mov %rdx,0x8(%rcx) 0x00000000004011c4 <+208>: add $0x8,%rax 0x00000000004011c8 <+212>: cmp %rsi,%rax 0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222> 0x00000000004011cd <+217>: mov %rdx,%rcx 0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201> 0x00000000004011d2 <+222>: movq $0x0,0x8(%rdx) 0x00000000004011da <+230>: mov $0x5,%ebp 0x00000000004011df <+235>: mov 0x8(%rbx),%rax 0x00000000004011e3 <+239>: mov (%rax),%eax 0x00000000004011e5 <+241>: cmp %eax,(%rbx) 0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250> 0x00000000004011e9 <+245>: call 0x40143a <explode_bomb> 0x00000000004011ee <+250>: mov 0x8(%rbx),%rbx 0x00000000004011f2 <+254>: sub $0x1,%ebp 0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235> 0x00000000004011f7 <+259>: add $0x50,%rsp 0x00000000004011fb <+263>: pop %rbx 0x00000000004011fc <+264>: pop %rbp 0x00000000004011fd <+265>: pop %r12 0x00000000004011ff <+267>: pop %r13 0x0000000000401201 <+269>: pop %r14 0x0000000000401203 <+271>: ret
|
<phase_6+18>表明,输入的是6个数值,解析后的数值放入栈中。
接下来进入一段循环中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 0x000000000040110b <+23>: mov %rsp,%r14 0x000000000040110e <+26>: mov $0x0,%r12d 0x0000000000401114 <+32>: mov %r13,%rbp 0x0000000000401117 <+35>: mov 0x0(%r13),%eax 0x000000000040111b <+39>: sub $0x1,%eax 0x000000000040111e <+42>: cmp $0x5,%eax 0x0000000000401121 <+45>: jbe 0x401128 <phase_6+52> 0x0000000000401123 <+47>: call 0x40143a <explode_bomb> 0x0000000000401128 <+52>: add $0x1,%r12d 0x000000000040112c <+56>: cmp $0x6,%r12d 0x0000000000401130 <+60>: je 0x401153 <phase_6+95> 0x0000000000401132 <+62>: mov %r12d,%ebx 0x0000000000401135 <+65>: movslq %ebx,%rax 0x0000000000401138 <+68>: mov (%rsp,%rax,4),%eax 0x000000000040113b <+71>: cmp %eax,0x0(%rbp) 0x000000000040113e <+74>: jne 0x401145 <phase_6+81> 0x0000000000401140 <+76>: call 0x40143a <explode_bomb> 0x0000000000401145 <+81>: add $0x1,%ebx 0x0000000000401148 <+84>: cmp $0x5,%ebx 0x000000000040114b <+87>: jle 0x401135 <phase_6+65> 0x000000000040114d <+89>: add $0x4,%r13 0x0000000000401151 <+93>: jmp 0x401114 <phase_6+32>
|
该循环依次遍历数组中的每个元素,并对其进行判断,要求每个元素两两均不相等且均在1-6之间。
接下来进入另一个循环:
1 2 3 4 5 6 7 8 9
| 0x0000000000401153 <+95>: lea 0x18(%rsp),%rsi 0x0000000000401158 <+100>: mov %r14,%rax 0x000000000040115b <+103>: mov $0x7,%ecx 0x0000000000401160 <+108>: mov %ecx,%edx 0x0000000000401162 <+110>: sub (%rax),%edx 0x0000000000401164 <+112>: mov %edx,(%rax) 0x0000000000401166 <+114>: add $0x4,%rax 0x000000000040116a <+118>: cmp %rsi,%rax 0x000000000040116d <+121>: jne 0x401160 <phase_6+108>
|
该循环依次遍历数组中的每个元素,并使用7减去其之后的值替代原值。
接下来又进入新循环:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 0x000000000040116f <+123>: mov $0x0,%esi 0x0000000000401174 <+128>: jmp 0x401197 <phase_6+163> 0x0000000000401176 <+130>: mov 0x8(%rdx),%rdx 0x000000000040117a <+134>: add $0x1,%eax 0x000000000040117d <+137>: cmp %ecx,%eax 0x000000000040117f <+139>: jne 0x401176 <phase_6+130> 0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148> 0x0000000000401183 <+143>: mov $0x6032d0,%edx 0x0000000000401188 <+148>: mov %rdx,0x20(%rsp,%rsi,2) 0x000000000040118d <+153>: add $0x4,%rsi 0x0000000000401191 <+157>: cmp $0x18,%rsi 0x0000000000401195 <+161>: je 0x4011ab <phase_6+183> 0x0000000000401197 <+163>: mov (%rsp,%rsi,1),%ecx 0x000000000040119a <+166>: cmp $0x1,%ecx 0x000000000040119d <+169>: jle 0x401183 <phase_6+143> 0x000000000040119f <+171>: mov $0x1,%eax 0x00000000004011a4 <+176>: mov $0x6032d0,%edx 0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130>
|
其中存在一组小循环:
1 2 3 4 5
| 0x0000000000401176 <+130>: mov 0x8(%rdx),%rdx 0x000000000040117a <+134>: add $0x1,%eax 0x000000000040117d <+137>: cmp %ecx,%eax 0x000000000040117f <+139>: jne 0x401176 <phase_6+130> 0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148>
|
该循环显然处理的是一个链表结构,其从rdx处返回ecx位置的链表节点。
接下来进入另一个小循环:
1 2 3 4 5 6 7 8 9 10 11
| 0x0000000000401183 <+143>: mov $0x6032d0,%edx 0x0000000000401188 <+148>: mov %rdx,0x20(%rsp,%rsi,2) 0x000000000040118d <+153>: add $0x4,%rsi 0x0000000000401191 <+157>: cmp $0x18,%rsi 0x0000000000401195 <+161>: je 0x4011ab <phase_6+183> 0x0000000000401197 <+163>: mov (%rsp,%rsi,1),%ecx 0x000000000040119a <+166>: cmp $0x1,%ecx 0x000000000040119d <+169>: jle 0x401183 <phase_6+143> 0x000000000040119f <+171>: mov $0x1,%eax 0x00000000004011a4 <+176>: mov $0x6032d0,%edx 0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130>
|
遍历7减操作后的数组,该循环用于根据处理后的取出对应链表节点指针并将其存放为数组,链表的头节点地址为0x6032d0。
故本段的作用是根据输入数组取出节点形成节点指针数组,指针节点数组的位置在0x20(%rsp)处。
接下来进行第三段大循环:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 0x00000000004011ab <+183>: mov 0x20(%rsp),%rbx 0x00000000004011b0 <+188>: lea 0x28(%rsp),%rax 0x00000000004011b5 <+193>: lea 0x50(%rsp),%rsi 0x00000000004011ba <+198>: mov %rbx,%rcx 0x00000000004011bd <+201>: mov (%rax),%rdx 0x00000000004011c0 <+204>: mov %rdx,0x8(%rcx) 0x00000000004011c4 <+208>: add $0x8,%rax 0x00000000004011c8 <+212>: cmp %rsi,%rax 0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222> 0x00000000004011cd <+217>: mov %rdx,%rcx 0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201> 0x00000000004011d2 <+222>: movq $0x0,0x8(%rdx) 0x00000000004011da <+230>: mov $0x5,%ebp 0x00000000004011df <+235>: mov 0x8(%rbx),%rax 0x00000000004011e3 <+239>: mov (%rax),%eax 0x00000000004011e5 <+241>: cmp %eax,(%rbx) 0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250> 0x00000000004011e9 <+245>: call 0x40143a <explode_bomb> 0x00000000004011ee <+250>: mov 0x8(%rbx),%rbx 0x00000000004011f2 <+254>: sub $0x1,%ebp 0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235>
|
一开始是一段小循环:
1 2 3 4 5 6 7
| 0x00000000004011bd <+201>: mov (%rax),%rdx 0x00000000004011c0 <+204>: mov %rdx,0x8(%rcx) 0x00000000004011c4 <+208>: add $0x8,%rax 0x00000000004011c8 <+212>: cmp %rsi,%rax 0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222> 0x00000000004011cd <+217>: mov %rdx,%rcx 0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201>
|
该段循环重建链表,使得其顺序与链表节点数组顺序相同。
1 2 3 4 5 6 7 8 9 10
| 0x00000000004011d2 <+222>: movq $0x0,0x8(%rdx) 0x00000000004011da <+230>: mov $0x5,%ebp 0x00000000004011df <+235>: mov 0x8(%rbx),%rax 0x00000000004011e3 <+239>: mov (%rax),%eax 0x00000000004011e5 <+241>: cmp %eax,(%rbx) 0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250> 0x00000000004011e9 <+245>: call 0x40143a <explode_bomb> 0x00000000004011ee <+250>: mov 0x8(%rbx),%rbx 0x00000000004011f2 <+254>: sub $0x1,%ebp 0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235>
|
该段对重排后的链表节点进行判定,要求链表单调递减。
现在开始反推:
要求最终节点单调递减。
进行了链表重构,重构顺序为7减数组指定链表节点顺序。
故输入应该为1-6的组合,并且其7减数组使得单调递减。
令7减数组转为原数组即可。
x/1xw 0x6032d0得:
1
| 0x6032d0 <node1>: 0x0000014c
|
x/2xg 0x6032d0得:
1
| 0x6032d0 <node1>: 0x000000010000014c 0x00000000006032e0
|
x/1xw 0x6032e0得:
1
| 0x6032e0 <node2>: 0x000000a8
|
x/2xg 0x6032e0得:
1
| 0x6032e0 <node2>: 0x00000002000000a8 0x00000000006032f0
|
x/1xw 0x6032f0得:
1
| 0x6032f0 <node3>: 0x0000039c
|
x/2xg 0x6032f0得:
1
| 0x6032f0 <node3>: 0x000000030000039c 0x0000000000603300
|
x/1xw 0x603300得:
1
| 0x603300 <node4>: 0x000002b3
|
x/2xg 0x603300得:
1
| 0x603300 <node4>: 0x00000004000002b3 0x0000000000603310
|
x/1xw 0x603310得:
1
| 0x603310 <node5>: 0x000001dd
|
x/2xg 0x603310得:
1
| 0x603310 <node5>: 0x00000005000001dd 0x0000000000603320
|
x/1xw 0x603320得:
1
| 0x603320 <node6>: 0x000001bb
|
x/2xg 0x603320得:
1
| 0x603320 <node6>: 0x00000006000001bb 0x0000000000000000
|
希望值为单调递减的索引应为3 4 5 6 1 2。
故7减数组应当为:3 4 5 6 1 2。
故答案应为:
secret_phase
实际上还存在一个secret_phase,其入口在phase_defused中。
使用disas phase_defused获取phase_defused源码:
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
| 0x00000000004015c4 <+0>: sub $0x78,%rsp 0x00000000004015c8 <+4>: mov %fs:0x28,%rax 0x00000000004015d1 <+13>: mov %rax,0x68(%rsp) 0x00000000004015d6 <+18>: xor %eax,%eax 0x00000000004015d8 <+20>: cmpl $0x6,0x202181(%rip) #0x603760 <num_input_strings> 0x00000000004015df <+27>: jne 0x40163f <phase_defused+123> 0x00000000004015e1 <+29>: lea 0x10(%rsp),%r8 0x00000000004015e6 <+34>: lea 0xc(%rsp),%rcx 0x00000000004015eb <+39>: lea 0x8(%rsp),%rdx 0x00000000004015f0 <+44>: mov $0x402619,%esi 0x00000000004015f5 <+49>: mov $0x603870,%edi 0x00000000004015fa <+54>: call 0x400bf0 <__isoc99_sscanf@plt> 0x00000000004015ff <+59>: cmp $0x3,%eax 0x0000000000401602 <+62>: jne 0x401635 <phase_defused+113> 0x0000000000401604 <+64>: mov $0x402622,%esi 0x0000000000401609 <+69>: lea 0x10(%rsp),%rdi 0x000000000040160e <+74>: call 0x401338 <strings_not_equal> 0x0000000000401613 <+79>: test %eax,%eax 0x0000000000401615 <+81>: jne 0x401635 <phase_defused+113> 0x0000000000401617 <+83>: mov $0x4024f8,%edi 0x000000000040161c <+88>: call 0x400b10 <puts@plt> 0x0000000000401621 <+93>: mov $0x402520,%edi 0x0000000000401626 <+98>: call 0x400b10 <puts@plt> 0x000000000040162b <+103>: mov $0x0,%eax 0x0000000000401630 <+108>: call 0x401242 <secret_phase> 0x0000000000401635 <+113>: mov $0x402558,%edi 0x000000000040163a <+118>: call 0x400b10 <puts@plt> 0x000000000040163f <+123>: mov 0x68(%rsp),%rax 0x0000000000401644 <+128>: xor %fs:0x28,%rax 0x000000000040164d <+137>: je 0x401654 <phase_defused+144> 0x000000000040164f <+139>: call 0x400b30 <__stack_chk_fail@plt> 0x0000000000401654 <+144>: add $0x78,%rsp 0x0000000000401658 <+148>: ret
|
在<phase_defused+20>中,要求将0x202181(%rip)等于6,否则不会进入。rip寄存器保存下一条指令地址,即最终目标为0x202181 + 0x4015df = 0x603760。x/1xw 0x603760得0,且其对应符号为num_input_strings。
在objdump -d bomb > bomb.s得到的bomb.s文件中查找num_input_strings,发现只在read_line中使用。
接下来,是对一段字符串的解析,0x603870为源字符串。p (char *)0x402619结果为%d %d %s。故应当解析出两个整数和一个字符串。
接下来进行字符串相等判断,p (char *)0x402622结果为"DrEvil"。因此第三个参数应该为DrEvil。
接下来打印两行字符串,p (char *)0x4024f8和p (char *)0x402520结果分别为"Curses, you've found the secret phase!"和"But finding it and solving it are quite different..."。
之后进入。结束后进行正常的资源释放。
使用disas read_line获取read_line源码:
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
| 0x000000000040149e <+0>: sub $0x8,%rsp 0x00000000004014a2 <+4>: mov $0x0,%eax 0x00000000004014a7 <+9>: call 0x4013f9 <skip> 0x00000000004014ac <+14>: test %rax,%rax 0x00000000004014af <+17>: jne 0x40151f <read_line+129> 0x00000000004014b1 <+19>: mov 0x202290(%rip),%rax # 0x603748 <stdin@@GLIBC_2.2.5> 0x00000000004014b8 <+26>: cmp %rax,0x2022a9(%rip) # 0x603768 <infile> 0x00000000004014bf <+33>: jne 0x4014d5 <read_line+55> 0x00000000004014c1 <+35>: mov $0x4025d5,%edi 0x00000000004014c6 <+40>: call 0x400b10 <puts@plt> 0x00000000004014cb <+45>: mov $0x8,%edi 0x00000000004014d0 <+50>: call 0x400c20 <exit@plt> 0x00000000004014d5 <+55>: mov $0x4025f3,%edi 0x00000000004014da <+60>: call 0x400ae0 <getenv@plt> 0x00000000004014df <+65>: test %rax,%rax 0x00000000004014e2 <+68>: je 0x4014ee <read_line+80> 0x00000000004014e4 <+70>: mov $0x0,%edi 0x00000000004014e9 <+75>: call 0x400c20 <exit@plt> 0x00000000004014ee <+80>: mov 0x202253(%rip),%rax # 0x603748 <stdin@@GLIBC_2.2.5> 0x00000000004014f5 <+87>: mov %rax,0x20226c(%rip) # 0x603768 <infile> 0x00000000004014fc <+94>: mov $0x0,%eax 0x0000000000401501 <+99>: call 0x4013f9 <skip> 0x0000000000401506 <+104>: test %rax,%rax 0x0000000000401509 <+107>: jne 0x40151f <read_line+129> 0x000000000040150b <+109>: mov $0x4025d5,%edi 0x0000000000401510 <+114>: call 0x400b10 <puts@plt> 0x0000000000401515 <+119>: mov $0x0,%edi 0x000000000040151a <+124>: call 0x400c20 <exit@plt> 0x000000000040151f <+129>: mov 0x20223b(%rip),%edx # 0x603760 <num_input_strings> 0x0000000000401525 <+135>: movslq %edx,%rax 0x0000000000401528 <+138>: lea (%rax,%rax,4),%rsi 0x000000000040152c <+142>: shl $0x4,%rsi 0x0000000000401530 <+146>: add $0x603780,%rsi 0x0000000000401537 <+153>: mov %rsi,%rdi 0x000000000040153a <+156>: mov $0x0,%eax 0x000000000040153f <+161>: mov $0xffffffffffffffff,%rcx 0x0000000000401546 <+168>: repnz scas %es:(%rdi),%al 0x0000000000401548 <+170>: not %rcx 0x000000000040154b <+173>: sub $0x1,%rcx 0x000000000040154f <+177>: cmp $0x4e,%ecx 0x0000000000401552 <+180>: jle 0x40159a <read_line+252> 0x0000000000401554 <+182>: mov $0x4025fe,%edi 0x0000000000401559 <+187>: call 0x400b10 <puts@plt> 0x000000000040155e <+192>: mov 0x2021fc(%rip),%eax # 0x603760 <num_input_strings> 0x0000000000401564 <+198>: lea 0x1(%rax),%edx 0x0000000000401567 <+201>: mov %edx,0x2021f3(%rip) # 0x603760 <num_input_strings> 0x000000000040156d <+207>: cltq 0x000000000040156f <+209>: imul $0x50,%rax,%rax 0x0000000000401573 <+213>: movabs $0x636e7572742a2a2a,%rdi 0x000000000040157d <+223>: mov %rdi,0x603780(%rax) 0x0000000000401584 <+230>: movabs $0x2a2a2a64657461,%rdi 0x000000000040158e <+240>: mov %rdi,0x603788(%rax) 0x0000000000401595 <+247>: call 0x40143a <explode_bomb> 0x000000000040159a <+252>: sub $0x1,%ecx 0x000000000040159d <+255>: movslq %ecx,%rcx 0x00000000004015a0 <+258>: movslq %edx,%rax 0x00000000004015a3 <+261>: lea (%rax,%rax,4),%rax 0x00000000004015a7 <+265>: shl $0x4,%rax 0x00000000004015ab <+269>: movb $0x0,0x603780(%rcx,%rax,1) 0x00000000004015b3 <+277>: add $0x1,%edx 0x00000000004015b6 <+280>: mov %edx,0x2021a4(%rip) # 0x603760 <num_input_strings> 0x00000000004015bc <+286>: mov %rsi,%rax 0x00000000004015bf <+289>: add $0x8,%rsp 0x00000000004015c3 <+293>: ret
|
在其中存在如下代码将num_input_strings的值增加1。
1 2 3
| 0x000000000040155e <+192>: mov 0x2021fc(%rip),%eax # 0x603760 <num_input_strings> 0x0000000000401564 <+198>: lea 0x1(%rax),%edx 0x0000000000401567 <+201>: mov %edx,0x2021f3(%rip) # 0x603760 <num_input_strings>
|
接下来关注跳转语句,发现除了以下代码后,其他的跳转语句不能避开该上述指令。
1 2 3 4 5 6 7
| 0x000000000040153a <+156>: mov $0x0,%eax 0x000000000040153f <+161>: mov $0xffffffffffffffff,%rcx 0x0000000000401546 <+168>: repnz scas %es:(%rdi),%al 0x0000000000401548 <+170>: not %rcx 0x000000000040154b <+173>: sub $0x1,%rcx 0x000000000040154f <+177>: cmp $0x4e,%ecx 0x0000000000401552 <+180>: jle 0x40159a <read_line+252>
|
该句计算输入语句的长度,若为0时跳过递增指令。
经过上述分析,可明白num_input_strings代表使用read_line读入过的的非0字符串数。
接下来需要追踪0x603870处字符串由谁修改。显然该字符串是输入字符串(内部缓存会被复用,信息会被清除)。故是read_line的返回值。接下来查看read_line的返回值信息:
1
| 0x00000000004015bc <+286>: mov %rsi,%rax
|
故查看rsi的最后修改处:
1 2 3 4 5
| 0x000000000040151f <+129>: mov 0x20223b(%rip),%edx # 0x603760 <num_input_strings> 0x0000000000401525 <+135>: movslq %edx,%rax 0x0000000000401528 <+138>: lea (%rax,%rax,4),%rsi 0x000000000040152c <+142>: shl $0x4,%rsi 0x0000000000401530 <+146>: add $0x603780,%rsi
|
故返回值地址为0x603780 + 16 * 5 * num_input_strings,当其为0x603870时,解得num_input_strings为3,故应当在phase_4的答案结尾加上DrEvil,修改后的phase_4答案为:
使用disas secret_phase获取secret_phase源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 0x0000000000401242 <+0>: push %rbx 0x0000000000401243 <+1>: call 0x40149e <read_line> 0x0000000000401248 <+6>: mov $0xa,%edx 0x000000000040124d <+11>: mov $0x0,%esi 0x0000000000401252 <+16>: mov %rax,%rdi 0x0000000000401255 <+19>: call 0x400bd0 <strtol@plt> 0x000000000040125a <+24>: mov %rax,%rbx 0x000000000040125d <+27>: lea -0x1(%rax),%eax 0x0000000000401260 <+30>: cmp $0x3e8,%eax 0x0000000000401265 <+35>: jbe 0x40126c <secret_phase+42> 0x0000000000401267 <+37>: call 0x40143a <explode_bomb> 0x000000000040126c <+42>: mov %ebx,%esi 0x000000000040126e <+44>: mov $0x6030f0,%edi 0x0000000000401273 <+49>: call 0x401204 <fun7> 0x0000000000401278 <+54>: cmp $0x2,%eax 0x000000000040127b <+57>: je 0x401282 <secret_phase+64> 0x000000000040127d <+59>: call 0x40143a <explode_bomb> 0x0000000000401282 <+64>: mov $0x402438,%edi 0x0000000000401287 <+69>: call 0x400b10 <puts@plt> 0x000000000040128c <+74>: call 0x4015c4 <phase_defused> 0x0000000000401291 <+79>: pop %rbx 0x0000000000401292 <+80>: ret
|
<secret_phase+19>处表明输入的是一个数字,<secret_phase+30>表明该数字为正数且小于等于0x3e9。
<secret_phase+49>调用函数fun7,之后对返回值进行判断,要求其返回值为2。
之后打印一些信息后便结束了。
使用disas fun7获取fun7源码,其第一个参数为0x6030f0,第二个参数为输入参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 0x0000000000401204 <+0>: sub $0x8,%rsp 0x0000000000401208 <+4>: test %rdi,%rdi 0x000000000040120b <+7>: je 0x401238 <fun7+52> 0x000000000040120d <+9>: mov (%rdi),%edx 0x000000000040120f <+11>: cmp %esi,%edx 0x0000000000401211 <+13>: jle 0x401220 <fun7+28> 0x0000000000401213 <+15>: mov 0x8(%rdi),%rdi 0x0000000000401217 <+19>: call 0x401204 <fun7> 0x000000000040121c <+24>: add %eax,%eax 0x000000000040121e <+26>: jmp 0x40123d <fun7+57> 0x0000000000401220 <+28>: mov $0x0,%eax 0x0000000000401225 <+33>: cmp %esi,%edx 0x0000000000401227 <+35>: je 0x40123d <fun7+57> 0x0000000000401229 <+37>: mov 0x10(%rdi),%rdi 0x000000000040122d <+41>: call 0x401204 <fun7> 0x0000000000401232 <+46>: lea 0x1(%rax,%rax,1),%eax 0x0000000000401236 <+50>: jmp 0x40123d <fun7+57> 0x0000000000401238 <+52>: mov $0xffffffff,%eax 0x000000000040123d <+57>: add $0x8,%rsp 0x0000000000401241 <+61>: ret
|
一个典型的二叉树递归,其对应的C代码应为:
1 2 3 4 5 6 7 8 9 10 11 12
| int fun7(TreeNode *root, long value) { if(NULL == root) { return -1; } if(root -> value < value) { return 2 * func7(root->more, value) + 1; } else if(root -> value > value) { return 2 * func7(root->less, value); } else { return 0; } }
|
接下来查看二叉树结点:
x/3xg 0x6030f0:
1 2
| 0x6030f0 <n1>: 0x0000000000000024 0x0000000000603110 0x603100 <n1+16>: 0x0000000000603130
|
x/3xg 0x603110:
1 2
| 0x603110 <n21>: 0x0000000000000008 0x0000000000603190 0x603120 <n21+16>: 0x0000000000603150
|
x/3xg 0x603130:
1 2
| 0x603130 <n22>: 0x0000000000000032 0x0000000000603170 0x603140 <n22+16>: 0x00000000006031b0
|
x/3xg 0x603190:
1 2
| 0x603190 <n31>: 0x0000000000000006 0x00000000006031f0 0x6031a0 <n31+16>: 0x0000000000603250
|
x/3xg 0x603150:
1 2
| 0x603150 <n32>: 0x0000000000000016 0x0000000000603270 0x603160 <n32+16>: 0x0000000000603230
|
x/3xg 0x603170:
1 2
| 0x603170 <n33>: 0x000000000000002d 0x00000000006031d0 0x603180 <n33+16>: 0x0000000000603290
|
x/3xg 0x6031b0:
1 2
| 0x6031b0 <n34>: 0x000000000000006b 0x0000000000603210 0x6031c0 <n34+16>: 0x00000000006032b0
|
x/3xg 0x6031f0:
1 2
| 0x6031f0 <n41>: 0x0000000000000001 0x0000000000000000 0x603200 <n41+16>: 0x0000000000000000
|
x/3xg 0x603250:
1 2
| 0x603250 <n42>: 0x0000000000000007 0x0000000000000000 0x603260 <n42+16>: 0x0000000000000000
|
x/3xg 0x603270:
1 2
| 0x603270 <n43>: 0x0000000000000014 0x0000000000000000 0x603280 <n43+16>: 0x0000000000000000
|
x/3xg 0x603230:
1 2
| 0x603230 <n44>: 0x0000000000000023 0x0000000000000000 0x603240 <n44+16>: 0x0000000000000000
|
x/3xg 0x6031d0:
1 2
| 0x6031d0 <n45>: 0x0000000000000028 0x0000000000000000 0x6031e0 <n45+16>: 0x0000000000000000
|
x/3xg 0x603290:
1 2
| 0x603290 <n46>: 0x000000000000002f 0x0000000000000000 0x6032a0 <n46+16>: 0x0000000000000000
|
x/3xg 0x603210:
1 2
| 0x603210 <n47>: 0x0000000000000063 0x0000000000000000 0x603220 <n47+16>: 0x0000000000000000
|
x/3xg 0x6032b0:
1 2
| 0x6032b0 <n48>: 0x00000000000003e9 0x0000000000000000 0x6032c0 <n48+16>: 0x0000000000000000
|
这是一棵4层的满二叉树,结点的层序遍历后结果值序列如下:
1
| 0x24 0x8 0x32 0x6 0x16 0x2d 0x6b 0x1 0x7 0x14 0x23 0x28 0x2f 0x63 0x3e9
|
此时有以下root移动方式使得结果为2:
less more
less more less
故结果值可能为0x16和0x14,均符合条件。
故答案为(一行一个):
通过截图
最后附上通过的截图:
