当前位置:网站首页>CSAPP bomb lab parsing

CSAPP bomb lab parsing

2022-07-07 10:38:00 yym68686

GDB Common commands

command function
gdb filename Start debugging
run Began to run / Re run after running
run 1 2 3 Began to run , And pass in parameters 1,2,3
kill Stop running
quit sign out gdb
break sum stay sum Set breakpoints at the beginning of the function
break *0x8048c3 stay 0x8048c3 Set a breakpoint at the address of
delete 1 Delete breakpoints 1
clear sum Delete on sum Breakpoint of function entry
stepi Run an instruction
stepi 4 function 4 Orders
continue Run to the next breakpoint
disas sum Disassembly sum function
disas 0X12345 Reverse remittance entry 0x12345 Function of
print /x /d /t $rax take rax The content in is marked with 16 Base number ,10 Base number ,2 Output in hexadecimal form
print 0x888 Output 0x888 The decimal form of
print (int)0x123456 take 0x123456 The content stored in the address is output in digital form
print (char*)0x123456 The output is stored in 0x123456 String
x/w $rsp Resolve in rsp Point to word
x/2w $rsp Resolve in rsp Two of the positions pointed word
x/2wd $rsp Resolve in rsp Point to word, Output in decimal form
info registers Register information
info functions The function of information
info stack The stack information

1. phase_1

Display assembly code :

disas phase_1

Assembly code :

Dump of assembler code for function phase_1:
   0x00001662 <+0>:     endbr32
   0x00001666 <+4>:     push   %ebp
   0x00001667 <+5>:     mov    %esp,%ebp
   0x00001669 <+7>:     push   %ebx
   0x0000166a <+8>:     sub    $0xc,%esp
   0x0000166d <+11>:    call   0x13d0 <__x86.get_pc_thunk.bx>
   0x00001672 <+16>:    add    $0x38f2,%ebx
   0x00001678 <+22>:    lea    -0x1e20(%ebx),%eax
   0x0000167e <+28>:    push   %eax
   0x0000167f <+29>:    pushl  0x8(%ebp)
   0x00001682 <+32>:    call   0x1c10 <strings_not_equal>
   0x00001687 <+37>:    add    $0x10,%esp
   0x0000168a <+40>:    test   %eax,%eax
   0x0000168c <+42>:    jne    0x1693 <phase_1+49>
   0x0000168e <+44>:    mov    -0x4(%ebp),%ebx
   0x00001691 <+47>:    leave
   0x00001692 <+48>:    ret
   0x00001693 <+49>:    call   0x1e95 <explode_bomb>
   0x00001698 <+54>:    jmp    0x168e <phase_1+44>
End of assembler dump.
  • If the system CPU Newer version ( Such as in the ten generations of core ), stay Ubuntu20.04 Will compile by default endbr32 Instructions . Please refer to here Add the corresponding compilation options to remove this new instruction . But there is no source code here, so there is no way to recompile .

Called strings_not_equal Function directly determines whether two strings are equal , Judge whether the string entered by the user is equal to the system preset , First of all, find data The built-in string in the segment , You need to know the address of the string , Then print it out . First of all, the string must not exist in the stack , So the instructions involving stack operation must have nothing to do with that string , According to the assembly, you can probably know the following instruction :

0x00001678 <+22>:    lea    -0x1e20(%ebx),%eax

Assign the string address to eax, So we need to know %ebx-0x1e20 What is the address of . Need to know ebx What is it? , You need to run here first and set a breakpoint at the main function b main, Press r After operation , Reuse disas phase_1 Output assembly code :

Dump of assembler code for function phase_1:
   0x00401662 <+0>:     endbr32
   0x00401666 <+4>:     push   %ebp
   0x00401667 <+5>:     mov    %esp,%ebp
   0x00401669 <+7>:     push   %ebx
   0x0040166a <+8>:     sub    $0xc,%esp
   0x0040166d <+11>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x00401672 <+16>:    add    $0x38f2,%ebx
   0x00401678 <+22>:    lea    -0x1e20(%ebx),%eax
   0x0040167e <+28>:    push   %eax
   0x0040167f <+29>:    pushl  0x8(%ebp)
   0x00401682 <+32>:    call   0x401c10 <strings_not_equal>
   0x00401687 <+37>:    add    $0x10,%esp
   0x0040168a <+40>:    test   %eax,%eax
   0x0040168c <+42>:    jne    0x401693 <phase_1+49>
   0x0040168e <+44>:    mov    -0x4(%ebp),%ebx
   0x00401691 <+47>:    leave
   0x00401692 <+48>:    ret
   0x00401693 <+49>:    call   0x401e95 <explode_bomb>
   0x00401698 <+54>:    jmp    0x40168e <phase_1+44>
End of assembler dump.

I found the address changed , The address at this time shall prevail . see %ebx-0x1e20 Place the value of the :

x/x $ebx-0x1e20

Output :

0x403144:       0x69206548

So the address of the built-in string is 0x403144, Output string :

x/s 0x403144

The echo :

0x403144:       "He is evil and fits easily into most overhead storage bins."

So the answer to the first question is He is evil and fits easily into most overhead storage bins.
 Please add a picture description

2. phase_2

First check the assembly code disas phase_2

Dump of assembler code for function phase_2:
   0x0040169a <+0>:     endbr32
   0x0040169e <+4>:     push   %ebp
   0x0040169f <+5>:     mov    %esp,%ebp
   0x004016a1 <+7>:     push   %edi
   0x004016a2 <+8>:     push   %esi
   0x004016a3 <+9>:     push   %ebx
   0x004016a4 <+10>:    sub    $0x34,%esp
   0x004016a7 <+13>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x004016ac <+18>:    add    $0x38b8,%ebx
   0x004016b2 <+24>:    mov    %gs:0x14,%eax
   0x004016b8 <+30>:    mov    %eax,-0x1c(%ebp)
   0x004016bb <+33>:    xor    %eax,%eax
   0x004016bd <+35>:    lea    -0x34(%ebp),%eax
   0x004016c0 <+38>:    push   %eax
   0x004016c1 <+39>:    pushl  0x8(%ebp)
   0x004016c4 <+42>:    call   0x401eeb <read_six_numbers> ;  Read six numbers 
   0x004016c9 <+47>:    add    $0x10,%esp
   0x004016cc <+50>:    cmpl   $0x0,-0x34(%ebp)      ;  Judge whether the first number input is less than zero 
   0x004016d0 <+54>:    js     0x4016dc <phase_2+66> ;  If it is less than zero, it will explode 
   0x004016d2 <+56>:    mov    $0x1,%esi             ; for  Loop iterator  i  The initial value of the assignment is  1
   0x004016d7 <+61>:    lea    -0x34(%ebp),%edi      ;  Read the address of the first number into the register edi
   0x004016da <+64>:    jmp    0x4016f0 <phase_2+86> ;  Jump to for Loop start 
   0x004016dc <+66>:    call   0x401e95 <explode_bomb>
   0x004016e1 <+71>:    jmp    0x4016d2 <phase_2+56>
   0x004016e3 <+73>:    call   0x401e95 <explode_bomb>
   0x004016e8 <+78>:    add    $0x1,%esi
   0x004016eb <+81>:    cmp    $0x6,%esi
   0x004016ee <+84>:    je     0x4016fd <phase_2+99>
   0x004016f0 <+86>:    mov    %esi,%eax              ; eax Deposit i Value , The initial value is one 
   0x004016f2 <+88>:    add    -0x4(%edi,%esi,4),%eax ; eax = eax + (edi + esi * 4 - 0x4)
   0x004016f6 <+92>:    cmp    %eax,(%edi,%esi,4)     ; Judge array[i - 1] + i And array[i] The size of the relationship 
   0x004016f9 <+95>:    je     0x4016e8 <phase_2+78>  ; If equal, continue for loop 
   0x004016fb <+97>:    jmp    0x4016e3 <phase_2+73>  ;  If not , Then the explosion 
   0x004016fd <+99>:    mov    -0x1c(%ebp),%eax       ; Put the sixth number in eax in , Array range %edp-0x34~%edp-0x1c
   0x00401700 <+102>:   xor    %gs:0x14,%eax
   0x00401707 <+109>:   jne    0x401711 <phase_2+119>
   0x00401709 <+111>:   lea    -0xc(%ebp),%esp
   0x0040170c <+114>:   pop    %ebx
   0x0040170d <+115>:   pop    %esi
   0x0040170e <+116>:   pop    %edi
   0x0040170f <+117>:   pop    %ebp
   0x00401710 <+118>:   ret
   0x00401711 <+119>:   call   0x402e30 <__stack_chk_fail_local>
End of assembler dump.

be aware :

0x004016f2 <+88>:    add    -0x4(%edi,%esi,4),%eax

The meaning of this sentence is eax = eax + (edi + esi * 4 - 0x4), Translation is sum = array[i - 1] + i. Therefore, we need to construct an array with the current array subscript plus the previous willing element equal to the current array element :

    0      1      2      3      4      5
┌──────┬──────┬──────┬──────┬──────┬──────┐
│   0  │   1  │   3  │   6  │  10  │  15  │
└──────┴──────┴──────┴──────┴──────┴──────┘

So the current answer is :

He is evil and fits easily into most overhead storage bins.
0 1 3 6 10 15

 Please add a picture description

3. phase_3

First look at assembly code disas phase_3

Dump of assembler code for function phase_3:
   0x00401716 <+0>:     endbr32
   0x0040171a <+4>:     push   %ebp
   0x0040171b <+5>:     mov    %esp,%ebp
   0x0040171d <+7>:     push   %ebx
   0x0040171e <+8>:     sub    $0x14,%esp
   0x00401721 <+11>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x00401726 <+16>:    add    $0x383e,%ebx
   0x0040172c <+22>:    mov    %gs:0x14,%eax
   0x00401732 <+28>:    mov    %eax,-0xc(%ebp)
   0x00401735 <+31>:    xor    %eax,%eax
   0x00401737 <+33>:    lea    -0x10(%ebp),%eax
   0x0040173a <+36>:    push   %eax
   0x0040173b <+37>:    lea    -0x14(%ebp),%eax
   0x0040173e <+40>:    push   %eax
   0x0040173f <+41>:    lea    -0x1b97(%ebx),%eax
   0x00401745 <+47>:    push   %eax
   0x00401746 <+48>:    pushl  0x8(%ebp)
   0x00401749 <+51>:    call   0x4012d0 <[email protected]> ;  You need to input something 
   0x0040174e <+56>:    add    $0x10,%esp
   0x00401751 <+59>:    cmp    $0x1,%eax              ; scanf The return value of cannot be empty 
   0x00401754 <+62>:    jle    0x40176f <phase_3+89>
   0x00401756 <+64>:    cmpl   $0x7,-0x14(%ebp)       ;  The first number entered is the same as 7 Compare 
   0x0040175a <+68>:    ja     0x4017ee <phase_3+216> ;  If it is greater than 7 Then the explosion 
   0x00401760 <+74>:    mov    -0x14(%ebp),%eax
   0x00401763 <+77>:    mov    %ebx,%edx
   0x00401765 <+79>:    add    -0x1da4(%ebx,%eax,4),%edx
   0x0040176c <+86>:    notrack jmp *%edx
   0x0040176f <+89>:    call   0x401e95 <explode_bomb>
   0x00401774 <+94>:    jmp    0x401756 <phase_3+64>
   0x00401776 <+96>:    mov    $0x12b,%eax             ; eax = 0x12b
   0x0040177b <+101>:   sub    $0xfc,%eax              ; eax = 0x12b - 0xfc = 0x2f
   0x00401780 <+106>:   add    $0x38,%eax              ; eax = 0x2f + 0x38 = 0x67
   0x00401783 <+109>:   sub    $0x230,%eax             ; eax = 0x67 - 0x230 = 0xfffffe37
   0x00401788 <+114>:   add    $0x230,%eax             ;  from  0x004017d2  Jump here   here eax = 0
   0x0040178d <+119>:   sub    $0x230,%eax
   0x00401792 <+124>:   add    $0x230,%eax
   0x00401797 <+129>:   sub    $0x230,%eax             ; eax No change is still 0
   0x0040179c <+134>:   cmpl   $0x5,-0x14(%ebp)        ;  The first number entered is the same as 5 Compare 
   0x004017a0 <+138>:   jg     0x4017a7 <phase_3+145>  ;  If it is greater than 5 Then the explosion 
   0x004017a2 <+140>:   cmp    %eax,-0x10(%ebp)        ;  Compare the second number with eax, here eax = 0
   0x004017a5 <+143>:   je     0x4017ac <phase_3+150>  ;  Equal to pass 
   0x004017a7 <+145>:   call   0x401e95 <explode_bomb> ;  It doesn't mean explosion 
   0x004017ac <+150>:   mov    -0xc(%ebp),%eax ;  The second number is saved to eax
   0x004017af <+153>:   xor    %gs:0x14,%eax
   0x004017b6 <+160>:   jne    0x4017fa <phase_3+228>
   0x004017b8 <+162>:   mov    -0x4(%ebp),%ebx
   0x004017bb <+165>:   leave
   0x004017bc <+166>:   ret
   0x004017bd <+167>:   mov    $0x0,%eax
   0x004017c2 <+172>:   jmp    0x40177b <phase_3+101>
   0x004017c4 <+174>:   mov    $0x0,%eax
   0x004017c9 <+179>:   jmp    0x401780 <phase_3+106>
   0x004017cb <+181>:   mov    $0x0,%eax
   0x004017d0 <+186>:   jmp    0x401783 <phase_3+109>
   0x004017d2 <+188>:   mov    $0x0,%eax ; eax = 0
   0x004017d7 <+193>:   jmp    0x401788 <phase_3+114>
   0x004017d9 <+195>:   mov    $0x0,%eax
   0x004017de <+200>:   jmp    0x40178d <phase_3+119>
   0x004017e0 <+202>:   mov    $0x0,%eax
   0x004017e5 <+207>:   jmp    0x401792 <phase_3+124>
   0x004017e7 <+209>:   mov    $0x0,%eax
   0x004017ec <+214>:   jmp    0x401797 <phase_3+129>
   0x004017ee <+216>:   call   0x401e95 <explode_bomb>
   0x004017f3 <+221>:   mov    $0x0,%eax
   0x004017f8 <+226>:   jmp    0x40179c <phase_3+134>
   0x004017fa <+228>:   call   0x402e30 <__stack_chk_fail_local>
End of assembler dump.

Find out :

   0x00401737 <+33>:    lea    -0x10(%ebp),%eax
   0x0040173a <+36>:    push   %eax
   0x0040173b <+37>:    lea    -0x14(%ebp),%eax
   0x0040173e <+40>:    push   %eax
   0x0040173f <+41>:    lea    -0x1b97(%ebx),%eax
   0x00401745 <+47>:    push   %eax
   0x00401746 <+48>:    pushl  0x8(%ebp)
   0x00401749 <+51>:    call   0x4012d0 <[email protected]>

Explain what needs to be input , Obviously, three in a row lea push Should be scanf Three parameters of , Note that you need to enter two variables , Parameters start from the last push Of , therefore -0x1b97(%ebx) Is the string of input format , Try to display the input format . First interrupt :

b *0x00401745

After operation , View input format string :

x/s $eax

Show :

0x4033cd:       "%d %d"

Explain that we need to enter two numbers , Next, let's see what these two numbers need to meet . It can be seen from the assembly instructions -0x14(%ebp) That is, the first number we enter must be less than or equal to 5, The available numbers are 0 1 2 3 4 5,-0x10(%ebp) It's the second number . The second number needs to be in 0x004017a2 And eax Compare , Equality will not explode , Run the program here , Find out eax stay 0x004017d2 To be an assignment 0, Jump to 0x00401788, Last eax still 0, So the second number is zero .

 Please add a picture description

4. phase_4

First look at assembly code :

Dump of assembler code for function phase_4:
   0x0040185e <+0>:     endbr32
   0x00401862 <+4>:     push   %ebp
   0x00401863 <+5>:     mov    %esp,%ebp
   0x00401865 <+7>:     push   %ebx
   0x00401866 <+8>:     sub    $0x14,%esp
   0x00401869 <+11>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x0040186e <+16>:    add    $0x36f6,%ebx
   0x00401874 <+22>:    mov    %gs:0x14,%eax
   0x0040187a <+28>:    mov    %eax,-0xc(%ebp)
   0x0040187d <+31>:    xor    %eax,%eax
   0x0040187f <+33>:    lea    -0x10(%ebp),%eax
   0x00401882 <+36>:    push   %eax
   0x00401883 <+37>:    lea    -0x14(%ebp),%eax
   0x00401886 <+40>:    push   %eax
   0x00401887 <+41>:    lea    -0x1b97(%ebx),%eax
   0x0040188d <+47>:    push   %eax
   0x0040188e <+48>:    pushl  0x8(%ebp)
   0x00401891 <+51>:    call   0x4012d0 <[email protected]>
   0x00401896 <+56>:    add    $0x10,%esp
   0x00401899 <+59>:    cmp    $0x2,%eax ;  Two parameters must be entered , Or it will explode 
   0x0040189c <+62>:    jne    0x4018a4 <phase_4+70>
   0x0040189e <+64>:    cmpl   $0xe,-0x14(%ebp) ;  The first number must be less than or equal to 0xe
   0x004018a2 <+68>:    jbe    0x4018a9 <phase_4+75>
   0x004018a4 <+70>:    call   0x401e95 <explode_bomb>
   0x004018a9 <+75>:    sub    $0x4,%esp
   0x004018ac <+78>:    push   $0xe        ;func4 The third parameter 14
   0x004018ae <+80>:    push   $0x0        ;func4 The second parameter 0
   0x004018b0 <+82>:    pushl  -0x14(%ebp) ;func4 The first parameter is the first number we enter 
   0x004018b3 <+85>:    call   0x4017ff <func4> ; call func4
   0x004018b8 <+90>:    add    $0x10,%esp
   0x004018bb <+93>:    or     -0x10(%ebp),%eax ;  Compare the second number with the return value  eax  Size 
   0x004018be <+96>:    je     0x4018c5 <phase_4+103> ; eax =  The second number  = 0  Will not explode 
   0x004018c0 <+98>:    call   0x401e95 <explode_bomb>
   0x004018c5 <+103>:   mov    -0xc(%ebp),%eax
   0x004018c8 <+106>:   xor    %gs:0x14,%eax
   0x004018cf <+113>:   jne    0x4018d6 <phase_4+120>
   0x004018d1 <+115>:   mov    -0x4(%ebp),%ebx
   0x004018d4 <+118>:   leave
   0x004018d5 <+119>:   ret
   0x004018d6 <+120>:   call   0x402e30 <__stack_chk_fail_local>
End of assembler dump.

Same as the last question , Still input two numbers :

   0x0040187f <+33>:    lea    -0x10(%ebp),%eax   ;  The second number 
   0x00401882 <+36>:    push   %eax
   0x00401883 <+37>:    lea    -0x14(%ebp),%eax   ;  The first number 
   0x00401886 <+40>:    push   %eax
   0x00401887 <+41>:    lea    -0x1b97(%ebx),%eax ;  Input format 
   0x0040188d <+47>:    push   %eax
   0x0040188e <+48>:    pushl  0x8(%ebp)
   0x00401891 <+51>:    call   0x4012d0 <[email protected]>

View the input format , First interrupt :

b *0x0040188d

After operation , View input format string :

x/s $eax

Show :

0x4033cd:       "%d %d"

Explain that we need to enter two numbers , Next, let's see what these two numbers need to meet . It can be seen from the assembly instructions -0x14(%ebp) That is, the first number we enter must be less than or equal to 0xe,-0x10(%ebp) It's the second number , adopt :

0x004018be <+96>:    je     0x4018c5 <phase_4+103> ; eax =  The second number  = 0  Will not explode 

You know , So the second number must be equal to zero . Next, judge how to let the first number pass func4 After that, the return value is 0.func4 Assembly code for :

Dump of assembler code for function func4:
   0x004017ff <+0>:     endbr32
   0x00401803 <+4>:     push   %ebp
   0x00401804 <+5>:     mov    %esp,%ebp
   0x00401806 <+7>:     push   %esi
   0x00401807 <+8>:     push   %ebx
   0x00401808 <+9>:     mov    0x8(%ebp),%ecx  ; ebp+0x8 Is the first parameter a1
   0x0040180b <+12>:    mov    0xc(%ebp),%eax  ; ebp+0xc It's the second parameter a2
   0x0040180e <+15>:    mov    0x10(%ebp),%ebx ; ebp+0x10 It's the third parameter a3
   0x00401811 <+18>:    mov    %ebx,%esi  ; esi = a3
   0x00401813 <+20>:    sub    %eax,%esi  ; esi = a3 - a2
   0x00401815 <+22>:    mov    %esi,%edx  ; edx = a3 - a2
   0x00401817 <+24>:    shr    $0x1f,%edx ;  Logical shift right 31 position  edx = (a3 - a2) >> 31, Only sign bits are reserved 
   0x0040181a <+27>:    add    %esi,%edx
   0x0040181c <+29>:    sar    %edx       ; Arithmetic shift right 1 position , namely edx / 2 = (a3 - a2) / 2
   0x0040181e <+31>:    add    %eax,%edx  ;  In the middle  mid = edx = a2 + (a3 - a2) / 2
   0x00401820 <+33>:    cmp    %ecx,%edx  ;  Compare  a2 + (a3 - a2) / 2  And  a1  Size 
   0x00401822 <+35>:    jg     0x401832 <func4+51> ;  if  a2 + (a3 - a2) / 2 > a1
   0x00401824 <+37>:    mov    $0x0,%eax           ; eax = 0, When  mid == a1  when , Go straight back to 0
   0x00401829 <+42>:    jl     0x401847 <func4+72> ;  if  a2 + (a3 - a2) / 2 < a1
   0x0040182b <+44>:    lea    -0x8(%ebp),%esp
   0x0040182e <+47>:    pop    %ebx
   0x0040182f <+48>:    pop    %esi
   0x00401830 <+49>:    pop    %ebp
   0x00401831 <+50>:    ret
   0x00401832 <+51>:    sub    $0x4,%esp ;  here  a2 + (a3 - a2) / 2 > a1
   0x00401835 <+54>:    sub    $0x1,%edx ; mid - 1
   0x00401838 <+57>:    push   %edx      ;func4 The third parameter mid - 1
   0x00401839 <+58>:    push   %eax      ;func4 The second parameter a2
   0x0040183a <+59>:    push   %ecx      ;func4 The first parameter a1
   0x0040183b <+60>:    call   0x4017ff <func4> ; func4(a1, a2, mid - 1)
   0x00401840 <+65>:    add    $0x10,%esp
   0x00401843 <+68>:    add    %eax,%eax ; eax = eax * 2
   0x00401845 <+70>:    jmp    0x40182b <func4+44>
   0x00401847 <+72>:    sub    $0x4,%esp ;  here  a2 + (a3 - a2) / 2 < a1
   0x0040184a <+75>:    push   %ebx      ;func4 The third parameter a3
   0x0040184b <+76>:    add    $0x1,%edx
   0x0040184e <+79>:    push   %edx      ;func4 The second parameter mid + 1
   0x0040184f <+80>:    push   %ecx      ;func4 The first parameter a1
   0x00401850 <+81>:    call   0x4017ff <func4>      ; func4(a1, mid + 1, a3)
   0x00401855 <+86>:    add    $0x10,%esp
   0x00401858 <+89>:    lea    0x1(%eax,%eax,1),%eax ; eax = eax * 2 + 1
   0x0040185c <+93>:    jmp    0x40182b <func4+44>
End of assembler dump.

This function is a binary function .a3 Add a2 It is possible to exceed the scope , So to calculate the middle value of two numbers, you can use a2 + (a3 - a2) / 2.

  • Logical shift right and arithmetic shift right : Logical shift right is to ignore the sign bit , Moves to the right one , Fill in zero on the left . The arithmetic shift right needs to consider the sign bit , Moves to the right one , If the sign bit is 1, It's on the left 1,; otherwise , Make up for it 0. Therefore, arithmetic shift right can also be divided by signed bits , Move right ,n Bit is equal to division 2 Of n Power .

be aware :

   0x00401822 <+35>:    jg     0x401832 <func4+51> ;  if  a2 + (a3 - a2) / 2 > a1
   0x00401824 <+37>:    mov    $0x0,%eax           ; eax = 0, When  mid == a1  when , Go straight back to 0
   0x00401829 <+42>:    jl     0x401847 <func4+72> ;  if  a2 + (a3 - a2) / 2 < a1

As long as you're not satisfied jg and jl Conditions ,func4 You can go straight back to 0, Only mid == a1 when ,func4 Go straight back to , And for the first time mid = 7, So the first number should be 7. The answer to this question is :7 0

 Please add a picture description

5. phase_5

First look at assembly code :

Dump of assembler code for function phase_5:
   0x004018db <+0>:     endbr32
   0x004018df <+4>:     push   %ebp
   0x004018e0 <+5>:     mov    %esp,%ebp
   0x004018e2 <+7>:     push   %edi
   0x004018e3 <+8>:     push   %esi
   0x004018e4 <+9>:     push   %ebx
   0x004018e5 <+10>:    sub    $0x18,%esp
   0x004018e8 <+13>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x004018ed <+18>:    add    $0x3677,%ebx
   0x004018f3 <+24>:    mov    0x8(%ebp),%esi ; ebp+0x8  Is the beginning byte of the string 
   0x004018f6 <+27>:    push   %esi
   0x004018f7 <+28>:    call   0x401bea <string_length>
   0x004018fc <+33>:    add    $0x10,%esp
   0x004018ff <+36>:    cmp    $0x6,%eax ;  The string length must be equal to 6
   0x00401902 <+39>:    jne    0x401931 <phase_5+86>
   0x00401904 <+41>:    mov    %esi,%eax          ; eax = esi  String start byte 
   0x00401906 <+43>:    add    $0x6,%esi          ; esi + esi + 6  String end byte 
   0x00401909 <+46>:    mov    $0x0,%ecx          ; ecx = 0, Records of the results 
   0x0040190e <+51>:    lea    -0x1d84(%ebx),%edi ;  Put the starting address of the array into  edi  in 
   0x00401914 <+57>:    movzbl (%eax),%edx        ; 32  position  0  Expand 
   0x00401917 <+60>:    and    $0xf,%edx          ;  Take the characters asscii The fourth digit of the code is used as the index of the array edx
   0x0040191a <+63>:    add    (%edi,%edx,4),%ecx ; ecx  = ecx + edi[edx]
   0x0040191d <+66>:    add    $0x1,%eax          ;  Counter , Record the current number of characters 
   0x00401920 <+69>:    cmp    %esi,%eax
   0x00401922 <+71>:    jne    0x401914 <phase_5+57> ;  if   It's not the end yet , Then continue the cycle 
   0x00401924 <+73>:    cmp    $0x2f,%ecx ; ecx  And  47  Compare 
   0x00401927 <+76>:    jne    0x401938 <phase_5+93> ; ecx  Must be equal to  47
   0x00401929 <+78>:    lea    -0xc(%ebp),%esp
   0x0040192c <+81>:    pop    %ebx
   0x0040192d <+82>:    pop    %esi
   0x0040192e <+83>:    pop    %edi
   0x0040192f <+84>:    pop    %ebp
   0x00401930 <+85>:    ret
   0x00401931 <+86>:    call   0x401e95 <explode_bomb>
   0x00401936 <+91>:    jmp    0x401904 <phase_5+41>
   0x00401938 <+93>:    call   0x401e95 <explode_bomb>
   0x0040193d <+98>:    jmp    0x401929 <phase_5+78>
End of assembler dump.

be aware :

0x0040190e <+51>:    lea    -0x1d84(%ebx),%edi ;  Put the starting address of the array into  edi  in 

have a look -0x1d84(%ebx) What is it , Add Breakpoint :b *0x0040190e, Output -0x1d84(%ebx) Content :

x/16x $ebx - 0x1d84

The echo :

0x4031e0 <array.3068>:     0x02    0x00    0x00    0x00    0x0a    0x00    0x00    0x00
0x4031e8 <array.3068+8>:   0x06    0x00    0x00    0x00    0x01    0x00    0x00    0x00

The hint is an array , One element every four bytes , Output in another format :

x/6xg $ebx - 0x1d84

The echo :

0x4031e0 <array.3068>:          0x0000000a00000002      0x0000000100000006
0x4031f0 <array.3068+16>:       0x000000100000000c      0x0000000300000009
0x403200 <array.3068+32>:       0x0000000700000004      0x000000050000000e

Our goal is to find a set of character sequences , their asscii The elements under the array index formed by the fourth bit of the code are added as 47, It is found that the first six of this array add up exactly 47, Check it out. asscii clock , Find six characters whose lower four digits are 0 1 2 3 4 5, What I'm looking for is pqrstu, Of course, there are other answers .

 Please add a picture description

6. phase_6

First look at assembly code :

Dump of assembler code for function phase_6:
   0x0040193f <+0>:     endbr32
   0x00401943 <+4>:     push   %ebp
   0x00401944 <+5>:     mov    %esp,%ebp
   0x00401946 <+7>:     push   %edi
   0x00401947 <+8>:     push   %esi
   0x00401948 <+9>:     push   %ebx
   0x00401949 <+10>:    sub    $0x64,%esp
   0x0040194c <+13>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x00401951 <+18>:    add    $0x3613,%ebx
   0x00401957 <+24>:    mov    %gs:0x14,%eax
   0x0040195d <+30>:    mov    %eax,-0x1c(%ebp)
   0x00401960 <+33>:    xor    %eax,%eax
   0x00401962 <+35>:    lea    -0x4c(%ebp),%eax
   0x00401965 <+38>:    push   %eax
   0x00401966 <+39>:    pushl  0x8(%ebp)
   0x00401969 <+42>:    call   0x401eeb <read_six_numbers> ;  Read six numbers 
   0x0040196e <+47>:    lea    -0x48(%ebp),%eax            ; eax = array[1]
   0x00401971 <+50>:    mov    %eax,-0x64(%ebp)            ; ebp-0x64 = array[1]
   0x00401974 <+53>:    add    $0x10,%esp
   0x00401977 <+56>:    movl   $0x0,-0x60(%ebp)            ; v16 = ebp - 0x60 = 0
   0x0040197e <+63>:    lea    -0x34(%ebp),%eax            ; v19 = ebp - 0x34 = eax = array[2]
   0x00401981 <+66>:    mov    %eax,-0x5c(%ebp)            ; ebp - 0x5c = v19 = ebp - 0x34
   0x00401984 <+69>:    jmp    0x4019a7 <phase_6+104>

 The following paragraph is a cycle , Pseudo code :
 while ( 1 )
  {
    
    if ( (unsigned int)(*((_DWORD *)v15 - 1) - 1) > 5 )
      explode_bomb();
    if ( ++v16 > 5 )
      break;
    v1 = (int *)v15;
    do
    {
    
      if ( *((_DWORD *)v15 - 1) == *v1 )
        explode_bomb();
      ++v1;
    }
    while ( &v19 != v1 );
    v15 += 4;
  }

   0x00401986 <+71>:    call   0x401e95 <explode_bomb>
   0x0040198b <+76>:    jmp    0x4019ba <phase_6+123>
   0x0040198d <+78>:    call   0x401e95 <explode_bomb>
   0x00401992 <+83>:    add    $0x4,%esi              ; v1++ = esi + 0x4
   0x00401995 <+86>:    cmp    %esi,-0x5c(%ebp)       ;
   0x00401998 <+89>:    je     0x4019a3 <phase_6+100> ; while (v19 != v1)
   0x0040199a <+91>:    mov    (%esi),%eax            ; eax = *v15
   0x0040199c <+93>:    cmp    %eax,-0x4(%edi)
   0x0040199f <+96>:    jne    0x401992 <phase_6+83>
   0x004019a1 <+98>:    jmp    0x40198d <phase_6+78>
   0x004019a3 <+100>:   addl   $0x4,-0x64(%ebp)       ; v15 = v15 + 0x4 = *(ebp - 0x64) + 4
   0x004019a7 <+104>:   mov    -0x64(%ebp),%eax       ; eax = *(ebp - 0x64) = array[1]
   0x004019aa <+107>:   mov    %eax,%edi              ; edi = eax = *(ebp - 0x64) = array[1]
   0x004019ac <+109>:   mov    -0x4(%eax),%eax        ; eax = array[0]
   0x004019af <+112>:   mov    %eax,-0x68(%ebp)
   0x004019b2 <+115>:   sub    $0x1,%eax              ; eax = eax - 1
   0x004019b5 <+118>:   cmp    $0x5,%eax              ;  Follow 5 Compare 
   0x004019b8 <+121>:   ja     0x401986 <phase_6+71>  ;  Not greater than 5
   0x004019ba <+123>:   addl   $0x1,-0x60(%ebp)       ; v16++ = *(ebp - 0x60) + 1
   0x004019be <+127>:   mov    -0x60(%ebp),%eax       ; eax = v16
   0x004019c1 <+130>:   cmp    $0x5,%eax              ; v16  And  5  Compare 
   0x004019c4 <+133>:   jg     0x4019cb <phase_6+140> ; v16  Not greater than  5
   0x004019c6 <+135>:   mov    -0x64(%ebp),%esi       ; esi = v15
   0x004019c9 <+138>:   jmp    0x40199a <phase_6+91>

 The following paragraph is a cycle , Pseudo code :
  do
  {
    
    *v2 = 7 - *v2;
    ++v2;
  }
  while ( &v19 != v2 );

   0x004019cb <+140>:   lea    -0x4c(%ebp),%eax       ; v2 = eax = ebp - 0x4c
   0x004019ce <+143>:   lea    -0x34(%ebp),%esi       ; v19 = esi = ebp - 0x34
   0x004019d1 <+146>:   mov    $0x7,%ecx              ; ecx = 7
   0x004019d6 <+151>:   mov    %ecx,%edx              ; edx = 7
   0x004019d8 <+153>:   sub    (%eax),%edx            ; v2 = edx = 7 - *eax
   0x004019da <+155>:   mov    %edx,(%eax)            ; *v2 = *eax = (ebp - 0x4c) = edx
   0x004019dc <+157>:   add    $0x4,%eax              ; v2 = eax = eax + 4 = (ebp - 0x4c)++
   0x004019df <+160>:   cmp    %eax,%esi              ; v19 = esi
   0x004019e1 <+162>:   jne    0x4019d6 <phase_6+151> ; while v19 != v2

 The following paragraph is a cycle , Pseudo code :
  for ( i = 0; i != 6; ++i )
  {
    
    v4 = *(&v17 + i);
    v5 = 1;
    v6 = &node1;
    if ( v4 > 1 )
    {
    
      do
      {
    
        v6 = (_DWORD *)v6[2];
        ++v5;
      }
      while ( v5 != v4 );
    }
    *(&v19 + i) = (int)v6;
  }

   0x004019e3 <+164>:   mov    $0x0,%esi               ;  Initial value of the cycle counter , A total of six cycles 
   0x004019e8 <+169>:   mov    %esi,%edi               ; i = edi = esi = 0
   0x004019ea <+171>:   mov    -0x4c(%ebp,%esi,4),%ecx ; v4 = ecx = (ebp - 0x4c + esi * 4)
   0x004019ee <+175>:   mov    $0x1,%eax               ; v5 = eax = 1
   0x004019f3 <+180>:   lea    0x594(%ebx),%edx        ;
   0x004019f9 <+186>:   cmp    $0x1,%ecx
   0x004019fc <+189>:   jle    0x401a08 <phase_6+201>  ; if ecx <= 1
   0x004019fe <+191>:   mov    0x8(%edx),%edx
   0x00401a01 <+194>:   add    $0x1,%eax               ; v5++
   0x00401a04 <+197>:   cmp    %ecx,%eax               ; v5  And  v4  Compare 
   0x00401a06 <+199>:   jne    0x4019fe <phase_6+191>  ; while v5 != v4
   0x00401a08 <+201>:   mov    %edx,-0x34(%ebp,%edi,4)
   0x00401a0c <+205>:   add    $0x1,%esi               ; i = esi++
   0x00401a0f <+208>:   cmp    $0x6,%esi               ;  Cycle six times 
   0x00401a12 <+211>:   jne    0x4019e8 <phase_6+169>

 There is also a cycle in the next paragraph , Pseudo code :
  v7 = v19;
  v8 = v20;
  *(_DWORD *)(v19 + 8) = v20;
  v9 = v21;
  *(_DWORD *)(v8 + 8) = v21;
  v10 = v22;
  *(v9 + 8) = v22;
  v11 = v23;
  *(v10 + 8) = v23;
  v12 = v24;
  *(v11 + 8) = v24;
  *(v12 + 8) = 0;
  v13 = 5;
  do
  {
    
    if ( *v7 < *(v7 + 8) )
      explode_bomb();
    v7 = *(v7 + 8);
    --v13;
  }
  while ( v13 );

   0x00401a14 <+213>:   mov    -0x34(%ebp),%esi ; v7 = esi = v19
   0x00401a17 <+216>:   mov    -0x30(%ebp),%eax ; v8 = eax = v20
   0x00401a1a <+219>:   mov    %eax,0x8(%esi)   ;  This paragraph will node end to end 
   0x00401a1d <+222>:   mov    -0x2c(%ebp),%edx
   0x00401a20 <+225>:   mov    %edx,0x8(%eax)
   0x00401a23 <+228>:   mov    -0x28(%ebp),%eax
   0x00401a26 <+231>:   mov    %eax,0x8(%edx)
   0x00401a29 <+234>:   mov    -0x24(%ebp),%edx
   0x00401a2c <+237>:   mov    %edx,0x8(%eax)
   0x00401a2f <+240>:   mov    -0x20(%ebp),%eax
   0x00401a32 <+243>:   mov    %eax,0x8(%edx)
   0x00401a35 <+246>:   movl   $0x0,0x8(%eax)
   0x00401a3c <+253>:   mov    $0x5,%edi
   0x00401a41 <+258>:   jmp    0x401a4b <phase_6+268>

   0x00401a43 <+260>:   mov    0x8(%esi),%esi ;  The next element 
   0x00401a46 <+263>:   sub    $0x1,%edi ;  Counter 
   0x00401a49 <+266>:   je     0x401a5b <phase_6+284> ;  The counter is equal to 0, Exit loop 
   0x00401a4b <+268>:   mov    0x8(%esi),%eax ; eax  Point to  esi  The next element 
   0x00401a4e <+271>:   mov    (%eax),%eax    ;  take  eax  The content of is assigned to  eax
   0x00401a50 <+273>:   cmp    %eax,(%esi)    ;  Compare   The element value of two elements 
   0x00401a52 <+275>:   jge    0x401a43 <phase_6+260> ;  The previous element must be smaller than the latter 
   0x00401a54 <+277>:   call   0x401e95 <explode_bomb>
   0x00401a59 <+282>:   jmp    0x401a43 <phase_6+260>

   0x00401a5b <+284>:   mov    -0x1c(%ebp),%eax
   0x00401a5e <+287>:   xor    %gs:0x14,%eax
   0x00401a65 <+294>:   jne    0x401a6f <phase_6+304>
   0x00401a67 <+296>:   lea    -0xc(%ebp),%esp
   0x00401a6a <+299>:   pop    %ebx
   0x00401a6b <+300>:   pop    %esi
   0x00401a6c <+301>:   pop    %edi
   0x00401a6d <+302>:   pop    %ebp
   0x00401a6e <+303>:   ret
   0x00401a6f <+304>:   call   0x402e30 <__stack_chk_fail_local>
End of assembler dump.

be aware

0x004019f3 <+180>:   lea    0x594(%ebx),%edx

I don't know what it is , First output , Run here first , Output ebx+0x594, Found equal to 0x4054f8, Output the information here , The discovery is a node, It could be a structure , The third element is the pointer to the next element , Description is a linked list , Output all elements :

 Please add a picture description

Arrange the numbers in the order of elements , The third row is sorted from large to small :

123456
0x3c20x2ca0x420x18a0x460x29c
125643

Check the pseudo code , It should be sorted from large to small , The order should be 1 2 6 4 5 3, Because after 7 - array[i] To deal with , So you should enter 6 5 1 3 2 4.

7. final result

 Please add a picture description

8. Hide the level

stay bomb.c Find out phase_6 Then there's another phase_defused function , Look at assembly code :

Dump of assembler code for function phase_defused:
   0x0040206d <+0>:     endbr32
   0x00402071 <+4>:     push   %ebp
   0x00402072 <+5>:     mov    %esp,%ebp
   0x00402074 <+7>:     push   %ebx
   0x00402075 <+8>:     sub    $0x70,%esp
   0x00402078 <+11>:    call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x0040207d <+16>:    add    $0x2ee7,%ebx
   0x00402083 <+22>:    mov    %gs:0x14,%eax
   0x00402089 <+28>:    mov    %eax,-0xc(%ebp)
   0x0040208c <+31>:    xor    %eax,%eax
   0x0040208e <+33>:    push   $0x1
   0x00402090 <+35>:    call   0x401dc1 <send_msg>
   0x00402095 <+40>:    add    $0x10,%esp
   0x00402098 <+43>:    cmpl   $0x6,0x7e0(%ebx)
   0x0040209f <+50>:    je     0x4020b6 <phase_defused+73>
   0x004020a1 <+52>:    mov    -0xc(%ebp),%eax
   0x004020a4 <+55>:    xor    %gs:0x14,%eax
   0x004020ab <+62>:    jne    0x402149 <phase_defused+220>
   0x004020b1 <+68>:    mov    -0x4(%ebp),%ebx
   0x004020b4 <+71>:    leave
   0x004020b5 <+72>:    ret
   0x004020b6 <+73>:    sub    $0xc,%esp
   0x004020b9 <+76>:    lea    -0x5c(%ebp),%eax
   0x004020bc <+79>:    push   %eax
   0x004020bd <+80>:    lea    -0x60(%ebp),%eax
   0x004020c0 <+83>:    push   %eax
   0x004020c1 <+84>:    lea    -0x64(%ebp),%eax   ;  Here is what we entered  7 0
   0x004020c4 <+87>:    push   %eax
   0x004020c5 <+88>:    lea    -0x1b3d(%ebx),%eax ;  Input format 
   0x004020cb <+94>:    push   %eax
   0x004020cc <+95>:    lea    0x7fc(%ebx),%eax   ;  The first question is the input string 
   0x004020d2 <+101>:   lea    0xf0(%eax),%eax
   0x004020d8 <+107>:   push   %eax
   0x004020d9 <+108>:   call   0x4012d0 <[email protected]>
   0x004020de <+113>:   add    $0x20,%esp
   0x004020e1 <+116>:   cmp    $0x3,%eax ;  The input parameter of question 4 is three , To jump to secret_phase
   0x004020e4 <+119>:   je     0x402108 <phase_defused+155>
   0x004020e6 <+121>:   sub    $0xc,%esp
   0x004020e9 <+124>:   lea    -0x1c88(%ebx),%eax
   0x004020ef <+130>:   push   %eax
   0x004020f0 <+131>:   call   0x401280 <[email protected]>
   0x004020f5 <+136>:   lea    -0x1c5c(%ebx),%eax
   0x004020fb <+142>:   mov    %eax,(%esp)
   0x004020fe <+145>:   call   0x401280 <[email protected]>
   0x00402103 <+150>:   add    $0x10,%esp
   0x00402106 <+153>:   jmp    0x4020a1 <phase_defused+52>
   0x00402108 <+155>:   sub    $0x8,%esp
   0x0040210b <+158>:   lea    -0x1b34(%ebx),%eax ;  The third parameter of question 4 needs to be  DrEvil
   0x00402111 <+164>:   push   %eax
   0x00402112 <+165>:   lea    -0x5c(%ebp),%eax
   0x00402115 <+168>:   push   %eax
   0x00402116 <+169>:   call   0x401c10 <strings_not_equal> ;  Judgment is not DrEvil
   0x0040211b <+174>:   add    $0x10,%esp
   0x0040211e <+177>:   test   %eax,%eax ;  The third parameter of question 4 must be  DrEvil  To jump to secret_phase
   0x00402120 <+179>:   jne    0x4020e6 <phase_defused+121>
   0x00402122 <+181>:   sub    $0xc,%esp
   0x00402125 <+184>:   lea    -0x1ce8(%ebx),%eax
   0x0040212b <+190>:   push   %eax
   0x0040212c <+191>:   call   0x401280 <[email protected]>
   0x00402131 <+196>:   lea    -0x1cc0(%ebx),%eax
   0x00402137 <+202>:   mov    %eax,(%esp)
   0x0040213a <+205>:   call   0x401280 <[email protected]>
   0x0040213f <+210>:   call   0x401aca <secret_phase>
   0x00402144 <+215>:   add    $0x10,%esp
   0x00402147 <+218>:   jmp    0x4020e6 <phase_defused+121>
   0x00402149 <+220>:   call   0x402e30 <__stack_chk_fail_local>
End of assembler dump.

Set the breakpoint at 0x004020e1, Run here and see :

x/s $ebx-0x1b3d

Show :

0x403427:       "%d %d %s"

see $ebp-0x64 What is it :

x/xg $ebp-0x64

Show :

0xbffff494:     0x0000000000000007

$ebp-0x64 Corresponding to the first parameter 7,$ebp-0x60 Corresponding to the second parameter 0, This is what we entered in question 4 7 0, He needs three parameters , Check unknown address :

x/s $ebx-0x1b34

Found echo is DrEvil. according to

  0x00402116 <+169>:   call   0x401c10 <strings_not_equal> ;  Judgment is not DrEvil

You know , The third parameter of question 4 must be DrEvil To jump to secret_phase. Continue to read the compilation and find :

0x0040213f <+210>:   call   0x401aca <secret_phase>

have a look secret_phase Assembly code :

Dump of assembler code for function secret_phase:
   0x00401aca <+0>:     endbr32
   0x00401ace <+4>:     push   %ebp
   0x00401acf <+5>:     mov    %esp,%ebp
   0x00401ad1 <+7>:     push   %esi
   0x00401ad2 <+8>:     push   %ebx
   0x00401ad3 <+9>:     call   0x4013d0 <__x86.get_pc_thunk.bx>
   0x00401ad8 <+14>:    add    $0x348c,%ebx
   0x00401ade <+20>:    call   0x401f3a <read_line>
   0x00401ae3 <+25>:    sub    $0x4,%esp
   0x00401ae6 <+28>:    push   $0xa
   0x00401ae8 <+30>:    push   $0x0
   0x00401aea <+32>:    push   %eax
   0x00401aeb <+33>:    call   0x401340 <[email protected]> ;strtol take eax The stored string is converted to 10 Hexadecimal integer , Make the result not ""
   0x00401af0 <+38>:    mov    %eax,%esi
   0x00401af2 <+40>:    lea    -0x1(%eax),%eax
   0x00401af5 <+43>:    add    $0x10,%esp
   0x00401af8 <+46>:    cmp    $0x3e8,%eax
   0x00401afd <+51>:    ja     0x401b34 <secret_phase+106>
   0x00401aff <+53>:    sub    $0x8,%esp
   0x00401b02 <+56>:    push   %esi
   0x00401b03 <+57>:    lea    0x540(%ebx),%eax
   0x00401b09 <+63>:    push   %eax
   0x00401b0a <+64>:    call   0x401a74 <fun7>
   0x00401b0f <+69>:    add    $0x10,%esp
   0x00401b12 <+72>:    test   %eax,%eax ;  Check  fun7  Whether the return value is  0
   0x00401b14 <+74>:    jne    0x401b3b <secret_phase+113> ;  No 0, Just explode 
   0x00401b16 <+76>:    sub    $0xc,%esp
   0x00401b19 <+79>:    lea    -0x1de4(%ebx),%eax
   0x00401b1f <+85>:    push   %eax
   0x00401b20 <+86>:    call   0x401280 <[email protected]>
   0x00401b25 <+91>:    call   0x40206d <phase_defused>
   0x00401b2a <+96>:    add    $0x10,%esp
   0x00401b2d <+99>:    lea    -0x8(%ebp),%esp
   0x00401b30 <+102>:   pop    %ebx
   0x00401b31 <+103>:   pop    %esi
   0x00401b32 <+104>:   pop    %ebp
   0x00401b33 <+105>:   ret
   0x00401b34 <+106>:   call   0x401e95 <explode_bomb>
   0x00401b39 <+111>:   jmp    0x401aff <secret_phase+53>
   0x00401b3b <+113>:   call   0x401e95 <explode_bomb>
   0x00401b40 <+118>:   jmp    0x401b16 <secret_phase+76>
End of assembler dump.

Focus on :

   0x00401b0a <+64>:    call   0x401a74 <fun7>
   0x00401b0f <+69>:    add    $0x10,%esp
   0x00401b12 <+72>:    test   %eax,%eax ;  Check  fun7  Whether the return value is  0
   0x00401b14 <+74>:    jne    0x401b3b <secret_phase+113> ;  No 0, Just explode 

as long as fun7 The return value of 0 That's it .fun7 Function assembly code :

Dump of assembler code for function fun7:
   0x00401a74 <+0>:     endbr32
   0x00401a78 <+4>:     push   %ebp
   0x00401a79 <+5>:     mov    %esp,%ebp
   0x00401a7b <+7>:     push   %ebx
   0x00401a7c <+8>:     sub    $0x4,%esp
   0x00401a7f <+11>:    mov    0x8(%ebp),%edx
   0x00401a82 <+14>:    mov    0xc(%ebp),%ecx
   0x00401a85 <+17>:    test   %edx,%edx
   0x00401a87 <+19>:    je     0x401ac3 <fun7+79>
   0x00401a89 <+21>:    mov    (%edx),%ebx
   0x00401a8b <+23>:    cmp    %ecx,%ebx
   0x00401a8d <+25>:    jg     0x401a9b <fun7+39> ;  Call the left child 
   0x00401a8f <+27>:    mov    $0x0,%eax ;  to result Copy to 0
   0x00401a94 <+32>:    jne    0x401aae <fun7+58> ;  Call the right child 
   0x00401a96 <+34>:    mov    -0x4(%ebp),%ebx
   0x00401a99 <+37>:    leave
   0x00401a9a <+38>:    ret
   0x00401a9b <+39>:    sub    $0x8,%esp
   0x00401a9e <+42>:    push   %ecx
   0x00401a9f <+43>:    pushl  0x4(%edx) ;  Call the left child 
   0x00401aa2 <+46>:    call   0x401a74 <fun7>
   0x00401aa7 <+51>:    add    $0x10,%esp
   0x00401aaa <+54>:    add    %eax,%eax
   0x00401aac <+56>:    jmp    0x401a96 <fun7+34>
   0x00401aae <+58>:    sub    $0x8,%esp
   0x00401ab1 <+61>:    push   %ecx
   0x00401ab2 <+62>:    pushl  0x8(%edx) ;  Call the right child 
   0x00401ab5 <+65>:    call   0x401a74 <fun7>
   0x00401aba <+70>:    add    $0x10,%esp
   0x00401abd <+73>:    lea    0x1(%eax,%eax,1),%eax
   0x00401ac1 <+77>:    jmp    0x401a96 <fun7+34>
   0x00401ac3 <+79>:    mov    $0xffffffff,%eax ;  return -1
   0x00401ac8 <+84>:    jmp    0x401a96 <fun7+34>
End of assembler dump.

fun7 Assembly is equivalent to :

int __cdecl fun7(_DWORD *a1, int a2)
{
    
  int result; // eax

  if ( !a1 )
    return -1;
  if ( *a1 > a2 )
    return 2 * fun7(a1[1], a2);
  result = 0;
  if ( *a1 != a2 )
    result = 2 * fun7(a1[2], a2) + 1;
  return result;
}

a1 Is the currently searched value ,a2 Is the value entered , When the input value is equal to the current search value , return 0. call fun7 Before , There's an instruction :

 0x00401b03 <+57>:    lea    0x540(%ebx),%eax

Output here :

(gdb) x/24wx $ebx+0x540
0x4054a4 <n1>:          0x00000024      0x004054b0      0x004054bc      0x00000008
0x4054b4 <n21+4>:       0x004054e0      0x004054c8      0x00000032      0x004054d4
0x4054c4 <n22+8>:       0x004054ec      0x00000016      0x0040505c      0x00405044
0x4054d4 <n33>:         0x0000002d      0x00405020      0x00405068      0x00000006
0x4054e4 <n31+4>:       0x0040502c      0x00405050      0x0000006b      0x00405038
0x4054f4 <n34+8>:       0x00405074      0x000003c2      0x00000001      0x00405504

It is found that this is another structure , The first word is the node value , The last two are addresses . Output one by one :

(gdb) x/3wx $ebx+0x540
0x4054a4 <n1>:  0x00000024      0x004054b0      0x004054bc
(gdb) x/3wx 0x004054b0
0x4054b0 <n21>: 0x00000008      0x004054e0      0x004054c8
(gdb) x/3wx 0x004054bc
0x4054bc <n22>: 0x00000032      0x004054d4      0x004054ec
(gdb) x/3wx 0x004054e0
0x4054e0 <n31>: 0x00000006      0x0040502c      0x00405050
(gdb) x/3wx 0x004054c8
0x4054c8 <n32>: 0x00000016      0x0040505c      0x00405044
(gdb) x/3wx 0x004054d4
0x4054d4 <n33>: 0x0000002d      0x00405020      0x00405068
(gdb) x/3wx 0x004054ec
0x4054ec <n34>: 0x0000006b      0x00405038      0x00405074
(gdb) x/3wx 0x0040502c
0x40502c <n41>: 0x00000001      0x00000000      0x00000000
(gdb) x/3wx 0x00405050
0x405050 <n42>: 0x00000007      0x00000000      0x00000000
(gdb) x/3wx 0x0040505c
0x40505c <n43>: 0x00000014      0x00000000      0x00000000
(gdb) x/3wx 0x00405044
0x405044 <n44>: 0x00000023      0x00000000      0x00000000
(gdb) x/3wx 0x00405020
0x405020 <n45>: 0x00000028      0x00000000      0x00000000
(gdb) x/3wx 0x00405068
0x405068 <n46>: 0x0000002f      0x00000000      0x00000000
(gdb) x/3wx 0x00405038
0x405038 <n47>: 0x00000063      0x00000000      0x00000000
(gdb) x/3wx 0x00405074
0x405074 <n48>: 0x000003e9      0x00000000      0x00000000

Sort it out , This is a binary tree :

          ┌─────────0x24─────────┐
          ▼                      ▼
    ┌───0x08────┐          ┌────0x32────┐
    ▼           ▼          ▼            ▼
 ┌─0x6─┐    ┌─0x16─┐    ┌─0x2d─┐    ┌─0x6b─┐
 ▼     ▼    ▼      ▼    ▼      ▼    ▼      ▼
0x1   0x7  0x14  0x23  0x28  0x2f  0x63  0x3e9

be aware :

0x00401a89 <+21>:    mov    (%edx),%ebx
0x00401a8b <+23>:    cmp    %ecx,%ebx

here ecx It is the root node of binary tree 36,ebx It's the number we entered , So as long as our input is also 36, Two if Conditions will not be implemented , Finally, go straight back to 0, result :

Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
He is evil and fits easily into most overhead storage bins.
Phase 1 defused. How about the next one?
0 1 3 6 10 15
That's number 2.  Keep going!
4 0
Halfway there!
7 0 DrEvil
So you got that one.  Try this one.
pqrstu
Good work!  On to the next...
6 5 1 3 2 4
Curses, you've found the secret phase!
But finding it and solving it are quite different...
36
Wow! You've defused the secret stage!
Congratulations! You've defused the bomb!
Your instructor has been notified and will verify your solution.

References

CSAPP Experiment of bomb lab( On )

《 Deep understanding of computer systems 》Bomb Lab Experimental analysis

《 Deep understanding of computer systems /CSAPP》Bomb Lab

CSAPP-bomblab

Introduction to CSAPP( nineteen ): This is probably the most comprehensive analysis you can find Bomblab 了

Deep understanding of computer systems (CSAPP) Experiment two Bomb Lab

原网站

版权声明
本文为[yym68686]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070827521641.html