[deep understanding of computer system csapp] Bob lab experiment 3

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

  1. b: Set breakpoints. Such as b phase_1. Indicates that a breakpoint is set in the phase1 function
  2. r: Execute until it stops at the first breakpoint.
  3. ni: single step execution.
  4. x/8x 0x400124: print 8 bytes of 0x400124 in hexadecimal
  5. x/8d 0x400124: print 8 bytes of 0x400124 in decimal system
  6. x/2s 0x400124: print the string beginning with address 0x400124
  7. info reg: print the value of the register.

objdump command

  1. objdump -d bomb outputs the disassembly result of the bomb program
  2. 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

  1. The valid part of the plain address $0x804a0fc is after the dollar sign
  2. cmp/cmpl instruction
  3. <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:

  1. Right click to open the terminal and enter gdb bomb
  2. Then break the point and enter B phase_ one
  3. 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.

  1. x/s 0x400e6d get the content in the address
  2. 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:

  1. 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;

  2. When the first number is not negative, jump to 400eae.

  3. 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)

  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).

  5. 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

  6. 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

  1. Look for the clear code to see what to enter. I found that let me enter two integers.
  2. *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
  3. 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


  1. Get ready to check the code.

  2. You can see that the problem is still to enter two integers

  3. From line 400ff7, the point is still stored with two int integers.

  4. Compare line 401001 with 2, indicating that the number of input parameters is 2.

  5. Line 40100a is compared with 14, indicating that the first parameter must be less than 14.

  6. Line 4010111016101b passes three parameters 0x4(%rsp),0,14 to func4().

  7. 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.

  8. Line 401028 indicates that the second parameter must be 3.

  9. 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
  1. 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.
  2. 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>
  1. Check the clear code, or let's enter two integers
  2. Look at the second clear code 0x402480
    There's an array here
  3. 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
  4. 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>

  1. Find the clear code and see the operation

    There seems to be a node in this place
  2. 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

  1. 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:
  2. Put the string after the answer of the fourth level.
  3. Start analyzing secret_phase function
  4. Check 0x402408 clear code: it corresponds to a string
  5. 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

Posted by SecureMind on Sun, 17 Apr 2022 15:44:56 +0930