brief introduction
Each bomb stage examines a different aspect of the machine level programming language, and the difficulty increases step by step:
Phase 1: string comparison
Phase 2: cycle
Phase 3: condition / Branch
Phase 4: recursive call and stack
Stage 5: pointer
Stage 6: linked list / pointer / structure
There is also a hidden phase, which only appears when you attach a specific string to the solution in phase 4.
In order to complete the binary bomb removal task, you need to use gdb debugger and objdump to disassemble the executable file of the bomb, track and debug the machine code at each stage, understand the behavior or function of each assembly language code, and then try to infer the target string required to remove the bomb. For example, set breakpoints before the start code of each stage and before the function that detonates the bomb.
Preparatory knowledge
gdb debug command
- b: Set breakpoints. Such as b phase_1. Indicates that a breakpoint is set in the phase1 function
- r: Execute until it stops at the first breakpoint.
- ni: single step execution.
- x/8x 0x400124: print 8 bytes of 0x400124 in hexadecimal
- x/8d 0x400124: print 8 bytes of 0x400124 in decimal system
- x/2s 0x400124: print the string beginning with address 0x400124
- info reg: print the value of the register.
objdump command
- objdump -d bomb outputs the disassembly result of the bomb program
- Objdump - t Bob print the symbol table of the Bob program, which contains the names and storage addresses of all functions and global variables in the Bob
At & T instruction
The instruction in at & T format is operand 2 - operand 1
Experimental steps
The first step is to use objdump - D Bob to output the disassembly result of the Bob program and generate a bob_ disas. TXT text file.
Step 2: create a new text file test Txt, which stores the answers to the questions completed in turn, without debugging for many times.
The third step is to generate the disassembly file Bob_ disas. Txt_ 1 position.
The fourth step is to observe the overall function and find out the breakthrough
- The valid part of the plain address $0x804a0fc is after the dollar sign
- cmp/cmpl instruction
- <explode_ Bob > called position and its jump or trigger reason
Step 5: execute gdb bomb at the terminal
phase_1
0000000000400e6d <phase_1>: 400e6d: 48 83 ec 08 sub $0x8,%rsp //Expand function stack space by 8 bytes 400e71: be d0 23 40 00 mov $0x4023d0,%esi //Obviously, the clear code here is the answer. We'll find out what's in this address later 400e76: e8 cf 04 00 00 callq 40134a <strings_not_equal> //It can be inferred from this that we need to enter a string 400e7b: 85 c0 test %eax,%eax //XOR, same as 0 400e7d: 75 05 jne 400e84 <phase_1+0x17> //Jump if the two are not equal 400e7f: 48 83 c4 08 add $0x8,%rsp 400e83: c3 retq //return 400e84: e8 be 05 00 00 callq 401447 <explode_bomb> //blast 400e89: eb f4 jmp 400e7f <phase_1+0x12>
Experimental steps:
- Right click to open the terminal and enter gdb bomb
- Then break the point and enter B phase_ one
- Then enter r
As you can see, line 11 calls < explode_ Bob >, that is to detonate the bomb, which is not what we want, so we should avoid running the program to this line. Observe the structure of the program. The program calls strings on line 8_ not_ Equal, compared the contents of% eax and% eax. Before that, the program push ed the register at $0x804b1d8. It can be guessed that the data at address $0x804b1d8 is the correct answer built into the program, which is the string we entered.
- x/s 0x400e6d get the content in the address
- Enter "Slave,..." after the breakpoint is completed
complete ✅
phase_2
After reading this question for a long time, my head hurts.
0000000000400e8b <phase_2>: //Part I: input 400e8b: 53 push %rbx 400e8c: 48 83 ec 20 sub $0x20,%rsp //Give a stack of 20 bytes 400e90: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 400e97: 00 00 400e99: 48 89 44 24 18 mov %rax,0x18(%rsp) 400e9e: 31 c0 xor %eax,%eax //Exclusive or, eax=0 400ea0: 48 89 e6 mov %rsp,%rsi //The above are the initialization of stack 400ea3: e8 c1 05 00 00 callq 401469 <read_six_numbers>//Read in six numbers (key) 400ea8: 83 3c 24 00 cmpl $0x0,(%rsp) //rsp and 0 comparison 400eac: 78 07 js 400eb5 <phase_2+0x2a> //If rsp is negative, jump to b5 explosion 400eae: bb 01 00 00 00 mov $0x1,%ebx //If rsp is not negative, go to this step, ebx=1 //Part II: circulation 400eb3: eb 11 jmp 400ec6 <phase_2+0x3b> //(1) Jump to c6 400eb5: e8 8d 05 00 00 callq 401447 <explode_bomb> 400eba: eb f2 jmp 400eae <phase_2+0x23> // 400ebc: 48 83 c3 01 add $0x1,%rbx //(7) The content of rbx at the bottom of the stack is set to 1 400ec0: 48 83 fb 06 cmp $0x6,%rbx //(8)rbx?=6 400ec4: 74 12 je 400ed8 <phase_2+0x4d> //(9) If equal, skip to d8 400ec6: 89 d8 mov %ebx,%eax //(2)eax=ebx=1 400ec8: 03 44 9c fc add -0x4(%rsp,%rbx,4),%eax //(3)R(eax)=R(eax)+M(R(rsp)+4R(rbx)-4) 400ecc: 39 04 9c cmp %eax,(%rsp,%rbx,4) //(4)R(eax)?=M(R(rsp)+4R(rbx)) 400ecf: 74 eb je 400ebc <phase_2+0x31> //(5) If the above formula is satisfied, jump to bc //Part III 400ed1: e8 71 05 00 00 callq 401447 <explode_bomb> 400ed6: eb e4 jmp 400ebc <phase_2+0x31> 400ed8: 48 8b 44 24 18 mov 0x18(%rsp),%rax //(10)rax=rsp+18 400edd: 64 48 33 04 25 28 00 xor %fs:0x28,%rax //The following is withdrawal 400ee4: 00 00 400ee6: 75 06 jne 400eee <phase_2+0x63> 400ee8: 48 83 c4 20 add $0x20,%rsp //Return 20 bit space 400eec: 5b pop %rbx //POP drop stack frame 400eed: c3 retq 400eee: e8 0d fc ff ff callq 400b00 <__stack_chk_fail@plt>
Program analysis:
-
Through the analysis of the first part of the program, we can understand that it is necessary to input 6 numbers, and the first number cannot be negative;
-
When the first number is not negative, jump to 400eae.
-
The sequence goes to - 0x4(%rsp,%rbx,4) is the proportional index addressing mode, and the address is R(eax)+M(R(rsp)+4R(rbx)-4)
-
Then compare the values of operands of% eax and 0x4(%rsp,%rbx,4). If they are equal, the value of% eax is + + (loop variable + +). If it is not 6, continue the loop. If there is no explode in the loop body_ Bob, it will cycle 5 times.
Loop body without explode_ Bob, the second level is cracked. Therefore, the key is where the value is compared at the loop 400ecc. The actual comparison is whether the latter number 0x4(%rsp,%rbx,4) is equal to the current number + cyclic variable (% eax). -
If the first number we input is 1, the password for the second pass should be 1 2 (1 + 1) 4 (2 + 2) 7 (4 + 3) 1 (7 + 4) 16 (11 + 5), that is, 1 2 4 7 11 16. The answer is not unique. It can meet this rule, but the first number cannot be negative
-
1 2 4 7 11 16 put it into test and run it at the terminal/ bomb test
Run it and try:
Answer: 1 2 4 7 11 16 the answer is not unique
Pseudo code:
int num[100]; num[0]=0; for(int rbx=1;rbx<6;rbx++){ int eax=rbx; eax+=num[rbx-1]; cout<<eax<<endl; if(num[i]!=eax) cout<<"bomb"<<endl; }
phase_3
0000000000400ef3 <phase_3>: 400ef3: 48 83 ec 18 sub $0x18,%rsp 400ef7: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 400efe: 00 00 400f00: 48 89 44 24 08 mov %rax,0x8(%rsp) 400f05: 31 c0 xor %eax,%eax 400f07: 48 8d 4c 24 04 lea 0x4(%rsp),%rcx 400f0c: 48 89 e2 mov %rsp,%rdx 400f0f: be cf 25 40 00 mov $0x4025cf,%esi //Initialization, data protection, assignment 400f14: e8 87 fc ff ff callq 400ba0 <__isoc99_sscanf@plt> //Key input //The first number entered should be greater than 1 and less than or equal to 7 400f19: 83 f8 01 cmp $0x1,%eax //eax?<= 1. It is an explosion 400f1c: 7e 10 jle 400f2e <phase_3+0x3b> 400f1e: 83 3c 24 07 cmpl $0x7,(%rsp) //rsp?> 7. If yes, it will explode, so the input digital range (1,7]) is obtained 400f22: 77 42 ja 400f66 <phase_3+0x73> 400f24: 8b 04 24 mov (%rsp),%eax //eax=rsp //Jump according to the input value. Here, all possible jump addresses can be output (switch) through debugging 400f27: ff 24 c5 40 24 40 00 jmpq *0x402440(,%rax,8) //The following is a transfer and assignment jump of eax. 400f2e: e8 14 05 00 00 callq 401447 <explode_bomb> 400f33: eb e9 jmp 400f1e <phase_3+0x2b> 400f35: b8 35 02 00 00 mov $0x235,%eax //1 565 400f3a: eb 3b jmp 400f77 <phase_3+0x84> 400f3c: b8 a7 01 00 00 mov $0x1a7,%eax //2 423 400f41: eb 34 jmp 400f77 <phase_3+0x84> 400f43: b8 2b 02 00 00 mov $0x22b,%eax //3 555 400f48: eb 2d jmp 400f77 <phase_3+0x84> 400f4a: b8 6c 00 00 00 mov $0x6c,%eax //4 108 400f4f: eb 26 jmp 400f77 <phase_3+0x84> 400f51: b8 f1 02 00 00 mov $0x2f1,%eax //5 753 400f56: eb 1f jmp 400f77 <phase_3+0x84> 400f58: b8 3e 00 00 00 mov $0x3e,%eax //6 62 400f5d: eb 18 jmp 400f77 <phase_3+0x84> 400f5f: b8 48 02 00 00 mov $0x248,%eax //7 584 400f64: eb 11 jmp 400f77 <phase_3+0x84> 400f66: e8 dc 04 00 00 callq 401447 <explode_bomb> 400f6b: b8 00 00 00 00 mov $0x0,%eax 400f70: eb 05 jmp 400f77 <phase_3+0x84> 400f72: b8 21 01 00 00 mov $0x121,%eax //0 289 //The second input above is compared with the value in the corresponding% eax. Only when it is equal to, the explosion program will not be triggered 400f77: 39 44 24 04 cmp %eax,0x4(%rsp) 400f7b: 74 05 je 400f82 <phase_3+0x8f> 400f7d: e8 c5 04 00 00 callq 401447 <explode_bomb> 400f82: 48 8b 44 24 08 mov 0x8(%rsp),%rax 400f87: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 400f8e: 00 00 400f90: 75 05 jne 400f97 <phase_3+0xa4> 400f92: 48 83 c4 18 add $0x18,%rsp 400f96: c3 retq 400f97: e8 64 fb ff ff callq 400b00 <__stack_chk_fail@plt>
Program analysis
- Look for the clear code to see what to enter. I found that let me enter two integers.
- *0x402440 here is the transfer of input numbers, so find the address to jump after input here
The number entered after the corresponding address is the second number.
For example, the corresponding 0x121 of 400f72 is converted to decimal 289, so 0 289 is the answer, and so on - Put 0 289 into test and run it at the terminal/ Bob test, passed
Answer: 0 289 the answer is not unique
phase_4
This problem is recursive, but func4 doesn't understand much. I saw one Blog of Harbin Industrial and technological giant I found it was a binary search, but I still didn't understand the details.
0000000000400fdb <phase_4>: 400fdb: 48 83 ec 18 sub $0x18,%rsp //18 Bit stack 400fdf: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 400fe6: 00 00 400fe8: 48 89 44 24 08 mov %rax,0x8(%rsp) 400fed: 31 c0 xor %eax,%eax //Above stack initialization 400fef: 48 8d 4c 24 04 lea 0x4(%rsp),%rcx //The second parameter passed in is rcx 400ff4: 48 89 e2 mov %rsp,%rdx //The first parameter passed in is rdx 400ff7: be cf 25 40 00 mov $0x4025cf,%esi //Clear code position = = = enter two numbers 400ffc: e8 9f fb ff ff callq 400ba0 <__isoc99_sscanf@plt> //input 401001: 83 f8 02 cmp $0x2,%eax //Enter two parameters 401004: 75 06 jne 40100c <phase_4+0x31> //If eax is not equal to 2, jump to 0c and explode 401006: 83 3c 24 0e cmpl $0xe,(%rsp) 40100a: 76 05 jbe 401011 <phase_4+0x36> //If the first parameter pointed by rsp is less than 14, it jumps to position 11, so the input number is less than 14 40100c: e8 36 04 00 00 callq 401447 <explode_bomb> 401011: ba 0e 00 00 00 mov $0xe,%edx 401016: be 00 00 00 00 mov $0x0,%esi //Three parameters 40101b: 8b 3c 24 mov (%rsp),%edi //Pass three parameters to func4:% rsp, 0, 14 40101e: e8 79 ff ff ff callq 400f9c <func4> //function call 401023: 83 f8 03 cmp $0x3,%eax 401026: 75 07 jne 40102f <phase_4+0x54> //Eax is not equal to 3, jump to bomb explosion, so the return value eax=3 401028: 83 7c 24 04 03 cmpl $0x3,0x4(%rsp) //See if the second parameter passed in is 3 40102d: 74 05 je 401034 <phase_4+0x59> //If it is not 3, it will explode, so the second parameter passed in is 3 40102f: e8 13 04 00 00 callq 401447 <explode_bomb> 401034: 48 8b 44 24 08 mov 0x8(%rsp),%rax //Following withdrawal 401039: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 401040: 00 00 401042: 75 05 jne 401049 <phase_4+0x6e> 401044: 48 83 c4 18 add $0x18,%rsp 401048: c3 retq 401049: e8 b2 fa ff ff callq 400b00 <__stack_chk_fail@plt> //The third input parameter edx=14, and the second input parameter esi=0 //Let x in edi, y in esi, z in edx 0000000000400f9c <func4>: 400f9c: 48 83 ec 08 sub $0x8,%rsp //Initialization stack //((((z - y) >> 31) + (z - y)) >> 1) + y 400fa0: 89 d0 mov %edx,%eax //Eax = EDX EDX third parameter eax=14 400fa2: 29 f0 sub %esi,%eax //Eax = eax ESI ESI the second parameter eax=14 400fa4: 89 c1 mov %eax,%ecx //ecx=eax ecx=14 400fa6: c1 e9 1f shr $0x1f,%ecx //ecx logic shift right (divide) 31 bits ecx=0 400fa9: 01 c1 add %eax,%ecx //ecx=ecx+eax ecx=14 400fab: d1 f9 sar %ecx //ecx arithmetic shift right exc=7 400fad: 01 f1 add %esi,%ecx //ecx=ecx+esi ecx=7 //eax=edx-esi //if(ret<0) return 2*func4(x,ret+1,z); 400faf: 39 f9 cmp %edi,%ecx //edi first parameter 400fb1: 7f 0e jg 400fc1 <func4+0x25> //If ECX = 7 > the first parameter edi is transferred to c1 400fb3: b8 00 00 00 00 mov $0x0,%eax 400fb8: 39 f9 cmp %edi,%ecx 400fba: 7c 11 jl 400fcd <func4+0x31> 400fbc: 48 83 c4 08 add $0x8,%rsp //if(ret==0) return 0; 400fc0: c3 retq //if(ret>0) return 2*func4(x,y,ret-1); 400fc1: 8d 51 ff lea -0x1(%rcx),%edx //edx= rcx-1 address assignment 400fc4: e8 d3 ff ff ff callq 400f9c <func4> //recursion 400fc9: 01 c0 add %eax,%eax //eax=2*eax 400fcb: eb ef jmp 400fbc <func4+0x20> //return 400fcd: 8d 71 01 lea 0x1(%rcx),%esi //esi=rcx+1 400fd0: e8 c7 ff ff ff callq 400f9c <func4> //Recursive call 400fd5: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax//eax=rax+rax 400fd9: eb e1 jmp 400fbc <func4+0x20> //return
-
Get ready to check the code.
-
You can see that the problem is still to enter two integers
-
From line 400ff7, the point is still stored with two int integers.
-
Compare line 401001 with 2, indicating that the number of input parameters is 2.
-
Line 40100a is compared with 14, indicating that the first parameter must be less than 14.
-
Line 4010111016101b passes three parameters 0x4(%rsp),0,14 to func4().
-
Line 401023 tests whether the return value of the function is 3. In order not to explode, the return value of the function must be 3.
-
Line 401028 indicates that the second parameter must be 3.
-
The func4 function in the latter part is a binary search recursion, which can be obtained by converting the disassembled into c + +
int func4(int x, int l, int r) { int mid = (((r - l) >> 31) + (r - l))/ 2 + l; if(mid == x) return 0; else if(mid > x) return 2 * func(x, l,mid - 1); else return 2 * func(x, mid + 1, r) + 1; } //Sigh again for the big man's arrogance
- Check the output below and find that if the return value is 3, the first parameter can only enter 12, so the answer is 12.
- 12.3 put in test and run it at the terminal/ Bob test, passed
Answer: 12 3
phase_5
000000000040104e <phase_5>: 40104e: 48 83 ec 18 sub $0x18,%rsp 401052: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 401059: 00 00 40105b: 48 89 44 24 08 mov %rax,0x8(%rsp) 401060: 31 c0 xor %eax,%eax 401062: 48 8d 4c 24 04 lea 0x4(%rsp),%rcx //x in rsp 401067: 48 89 e2 mov %rsp,%rdx //y in 0x4(rsp) 40106a: be cf 25 40 00 mov $0x4025cf,%esi //Clearly mark the location. Check it later 40106f: e8 2c fb ff ff callq 400ba0 <__isoc99_sscanf@plt> //Waiting for input 401074: 83 f8 01 cmp $0x1,%eax 401077: 7e 57 jle 4010d0 <phase_5+0x82> //If eax < = 1, bomb so eax < 1, eax may be equal to 0 401079: 8b 04 24 mov (%rsp),%eax //eax=x 40107c: 83 e0 0f and $0xf,%eax //eax & 15 => x & 15 40107f: 89 04 24 mov %eax,(%rsp) //rsp points to eax 401082: 83 f8 0f cmp $0xf,%eax 401085: 74 2f je 4010b6 <phase_5+0x68> //if eax(x) == 15 bomb 401087: b9 00 00 00 00 mov $0x0,%ecx //ecx(t)=0 40108c: ba 00 00 00 00 mov $0x0,%edx //edx(i)=0 401091: 83 c2 01 add $0x1,%edx //edx(i)+=1 Accumulation 401094: 48 98 cltq 401096: 8b 04 85 80 24 40 00 mov 0x402480(,%rax,4),%eax //eax(x) points to array = > x = array [x] // at 0x403200 : array[16] = {10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5} 40109d: 01 c1 add %eax,%ecx //ecx(t)+=eax (x) 40109f: 83 f8 0f cmp $0xf,%eax 4010a2: 75 ed jne 401091 <phase_5+0x43> //if array[x] != 15 ,edx++ 4010a4: c7 04 24 0f 00 00 00 movl $0xf,(%rsp) //rsp=15 4010ab: 83 fa 03 cmp $0x3,%edx //if edx(i) != 3 4010ae: 75 06 jne 4010b6 <phase_5+0x68> //then bomb 4010b0: 39 4c 24 04 cmp %ecx,0x4(%rsp) //if ecx(t) == y 4010b4: 74 05 je 4010bb <phase_5+0x6d> //then return 4010b6: e8 8c 03 00 00 callq 401447 <explode_bomb> 4010bb: 48 8b 44 24 08 mov 0x8(%rsp),%rax 4010c0: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 4010c7: 00 00 4010c9: 75 0c jne 4010d7 <phase_5+0x89> 4010cb: 48 83 c4 18 add $0x18,%rsp 4010cf: c3 retq 4010d0: e8 72 03 00 00 callq 401447 <explode_bomb> 4010d5: eb a2 jmp 401079 <phase_5+0x2b> 4010d7: e8 24 fa ff ff callq 400b00 <__stack_chk_fail@plt>
- Check the clear code, or let's enter two integers
- Look at the second clear code 0x402480
There's an array here
- Enter P* 0x402480@16 , here is the second clear code
Tamping tamping found the array!!
You can't find array directly here, because there is no name, so you can only find the address plus the following length, See for details - gdb display array
- C language cycle
const int array[16] = {10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5}; // t in %ecx , i in %edx void phase_5(int x, int y) { x &= 15, t = 0, i = 0; while (x != 15) { i++, x = array[x], t += x; } if (i != 3 || y != t) explode_bomb(); return; }
Cycle results:
Answer: 2 35
phase_6
00000000004010dc <phase_6>: 4010dc: 41 56 push %r14 4010de: 41 55 push %r13 4010e0: 41 54 push %r12 4010e2: 55 push %rbp 4010e3: 53 push %rbx //Register stack 4010e4: 48 83 ec 60 sub $0x60,%rsp //Stack space 0x60 bytes 4010e8: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 4010ef: 00 00 4010f1: 48 89 44 24 58 mov %rax,0x58(%rsp) //rax should point to num[0] of the array 4010f6: 31 c0 xor %eax,%eax 4010f8: 48 89 e6 mov %rsp,%rsi //Part I: ensure that the input is the full arrangement of 1 2 3 4 5 6 4010fb: e8 69 03 00 00 callq 401469 <read_six_numbers>//Read in six numbers 401100: 49 89 e4 mov %rsp,%r12 401103: 49 89 e5 mov %rsp,%r13 401106: 41 be 00 00 00 00 mov $0x0,%r14d 40110c: eb 25 jmp 401133 <phase_6+0x57> 40110e: e8 34 03 00 00 callq 401447 <explode_bomb> 401113: eb 2d jmp 401142 <phase_6+0x66> 401115: 83 c3 01 add $0x1,%ebx //ebx++ 401118: 83 fb 05 cmp $0x5,%ebx //if ebx > 5 40111b: 7f 12 jg 40112f <phase_6+0x53> //then 40111d: 48 63 c3 movslq %ebx,%rax //rax=ebx 401120: 8b 04 84 mov (%rsp,%rax,4),%eax 401123: 39 45 00 cmp %eax,0x0(%rbp) //if rbp!=eax 401126: 75 ed jne 401115 <phase_6+0x39> //then call ebx++ 401128: e8 1a 03 00 00 callq 401447 <explode_bomb> //else boom 40112d: eb e6 jmp 401115 <phase_6+0x39> //jump ebx++ 40112f: 49 83 c5 04 add $0x4,%r13 //r13+=4 401133: 4c 89 ed mov %r13,%rbp //rbp=r13 401136: 41 8b 45 00 mov 0x0(%r13),%eax //eax=>r13 40113a: 83 e8 01 sub $0x1,%eax //eax-- 40113d: 83 f8 05 cmp $0x5,%eax //if eax > 5 401140: 77 cc ja 40110e <phase_6+0x32> //then bomb => eax<=5 401142: 41 83 c6 01 add $0x1,%r14d //r14d++ 401146: 41 83 fe 06 cmp $0x6,%r14d //if r14d == 6 40114a: 74 05 je 401151 <phase_6+0x75> //then 40114c: 44 89 f3 mov %r14d,%ebx //ebx=r14d 40114f: eb cc jmp 40111d <phase_6+0x41> //Part II 401151: 49 8d 4c 24 18 lea 0x18(%r12),%rcx 401156: ba 07 00 00 00 mov $0x7,%edx //edx=7 40115b: 89 d0 mov %edx,%eax //eax=edx=7 40115d: 41 2b 04 24 sub (%r12),%eax //eax-=r12 401161: 41 89 04 24 mov %eax,(%r12) 401165: 49 83 c4 04 add $0x4,%r12 401169: 4c 39 e1 cmp %r12,%rcx 40116c: 75 ed jne 40115b <phase_6+0x7f> 40116e: be 00 00 00 00 mov $0x0,%esi 401173: eb 1a jmp 40118f <phase_6+0xb3> 401175: 48 8b 52 08 mov 0x8(%rdx),%rdx 401179: 83 c0 01 add $0x1,%eax 40117c: 39 c8 cmp %ecx,%eax 40117e: 75 f5 jne 401175 <phase_6+0x99> 401180: 48 89 54 f4 20 mov %rdx,0x20(%rsp,%rsi,8) 401185: 48 83 c6 01 add $0x1,%rsi 401189: 48 83 fe 06 cmp $0x6,%rsi 40118d: 74 14 je 4011a3 <phase_6+0xc7> 40118f: 8b 0c b4 mov (%rsp,%rsi,4),%ecx 401192: b8 01 00 00 00 mov $0x1,%eax 401197: ba d0 32 60 00 mov $0x6032d0,%edx 40119c: 83 f9 01 cmp $0x1,%ecx 40119f: 7f d4 jg 401175 <phase_6+0x99> 4011a1: eb dd jmp 401180 <phase_6+0xa4> 4011a3: 48 8b 5c 24 20 mov 0x20(%rsp),%rbx 4011a8: 48 8b 44 24 28 mov 0x28(%rsp),%rax 4011ad: 48 89 43 08 mov %rax,0x8(%rbx) 4011b1: 48 8b 54 24 30 mov 0x30(%rsp),%rdx 4011b6: 48 89 50 08 mov %rdx,0x8(%rax) 4011ba: 48 8b 44 24 38 mov 0x38(%rsp),%rax 4011bf: 48 89 42 08 mov %rax,0x8(%rdx) 4011c3: 48 8b 54 24 40 mov 0x40(%rsp),%rdx 4011c8: 48 89 50 08 mov %rdx,0x8(%rax) 4011cc: 48 8b 44 24 48 mov 0x48(%rsp),%rax 4011d1: 48 89 42 08 mov %rax,0x8(%rdx) 4011d5: 48 c7 40 08 00 00 00 movq $0x0,0x8(%rax) 4011dc: 00 4011dd: bd 05 00 00 00 mov $0x5,%ebp 4011e2: eb 09 jmp 4011ed <phase_6+0x111> 4011e4: 48 8b 5b 08 mov 0x8(%rbx),%rbx 4011e8: 83 ed 01 sub $0x1,%ebp 4011eb: 74 11 je 4011fe <phase_6+0x122> 4011ed: 48 8b 43 08 mov 0x8(%rbx),%rax 4011f1: 8b 00 mov (%rax),%eax 4011f3: 39 03 cmp %eax,(%rbx) 4011f5: 7d ed jge 4011e4 <phase_6+0x108> 4011f7: e8 4b 02 00 00 callq 401447 <explode_bomb> 4011fc: eb e6 jmp 4011e4 <phase_6+0x108> 4011fe: 48 8b 44 24 58 mov 0x58(%rsp),%rax 401203: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 40120a: 00 00 40120c: 75 0d jne 40121b <phase_6+0x13f> 40120e: 48 83 c4 60 add $0x60,%rsp 401212: 5b pop %rbx 401213: 5d pop %rbp 401214: 41 5c pop %r12 401216: 41 5d pop %r13 401218: 41 5e pop %r14 40121a: c3 retq 40121b: e8 e0 f8 ff ff callq 400b00 <__stack_chk_fail@plt>
- Find the clear code and see the operation
There seems to be a node in this place - Enter 1 2 3 4 5 6 and check the address
It is easy to know that the six input numbers are the full arrangement of 1, 2, 3, 4, 5, 6, and then they are in descending or ascending order through a function, and then all -7 take the absolute value (refer to the conclusion obtained from the last answer on the Internet).
Convert the hexadecimal of the first column into decimal, and arrange the following answers according to the decimal descending or ascending order: 645123, 321546 ascending and descending order are wrong, so it is considered that all - 7 take the absolute value: 132654, 456231, and the last one is the correct answer.
Answer: 4 5 6 2 3 1
secret_phase
- This level needs to enter a string after the fourth level to trigger the hidden level.
First look at the function phase_defused, find a clear code 0x402619 in it and find a string to enter the password of the hidden level:
- Put the string after the answer of the fourth level.
- Start analyzing secret_phase function
- Check 0x402408 clear code: it corresponds to a string
- The next clear code corresponds to a large structure. It can be seen from the answer on the Internet that it is a full binary tree.
We can see that it just conforms to the search structure of binary tree: left son < root < right son. So now we just need to figure out the behavior of func7.
0000000000401220 <fun7>: //rdi(p) ea //if(p==0) return -1 401220: 48 85 ff test %rdi,%rdi //Not 0 401223: 74 34 je 401259 <fun7+0x39> 401225: 48 83 ec 08 sub $0x8,%rsp //Allocate 8 bytes of stack space //compare val and p->val 401229: 8b 17 mov (%rdi),%edx //edx=rdi=p //if(val==p->val) reutrn 0 40122b: 39 f2 cmp %esi,%edx //Input parameter, esp = EDX 40122d: 7f 0e jg 40123d <fun7+0x1d> 40122f: b8 00 00 00 00 mov $0x0,%eax // 401234: 39 f2 cmp %esi,%edx 401236: 75 12 jne 40124a <fun7+0x2a> 401238: 48 83 c4 08 add $0x8,%rsp 40123c: c3 retq //if(val<p->ral) return 2*func(lson,val) 40123d: 48 8b 7f 08 mov 0x8(%rdi),%rdi 401241: e8 da ff ff ff callq 401220 <fun7> //Recursive eax=2*eax+1 401246: 01 c0 add %eax,%eax 401248: eb ee jmp 401238 <fun7+0x18> //if(val>p->val) return 2*func(rson,cal)+1 40124a: 48 8b 7f 10 mov 0x10(%rdi),%rdi 40124e: e8 cd ff ff ff callq 401220 <fun7> 401253: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax 401257: eb df jmp 401238 <fun7+0x18> 401259: b8 ff ff ff ff mov $0xffffffff,%eax 40125e: c3 retq
This function corresponds to a binary tree search process.
See the link below for details.
https://blog.csdn.net/wyn1564464568/article/details/123918590
Answer: 7
Reference articles
https://www.cnblogs.com/zhyh/p/16094547.html
https://blog.csdn.net/weixin_43858870/article/details/102995380
https://blog.csdn.net/wyn1564464568/article/details/123918590
https://blog.csdn.net/qq_37500516/article/details/120903236
https://zhuanlan.zhihu.com/p/339461318
https://zhuanlan.zhihu.com/p/339575162
https://cloud.tencent.com/developer/article/1826663
https://blog.csdn.net/qq_40017011/article/details/113483570
https://blog.csdn.net/Eternitykc/article/details/110427039
https://blog.csdn.net/cena1001/article/details/109570188
https://blog.csdn.net/XiaoXuM_LXM/article/details/83417576
https://www.cnblogs.com/wkfvawl/p/10742405.html
https://blog.csdn.net/astrotycoon/article/details/73249435
https://dingfen.github.io/csapp/2021/05/26/CSAPPLab02.html#secret_phase
https://blog.csdn.net/XiaoXuM_LXM/article/details/83417576