CS APP ex2 bomb

CS APP experiment 2, dismantling bomb

Here is the linux environment through gdb debugger carried out

Enter gdb debugging mode

An input terminal$ gdb bomb

View main function

Entry(gdb) list main

Found initialization function initialize_bomb(), the two printoutput prompt, and then followed by a input = read_line(), we will call as a parameter input phase_1function.

So this phase_1should be the function of the input checking, see the compilation of the function.

phase_1 function

  • Entry(gdb) disassemble phase_1

Output follows

    Dump of assembler code for function phase_1:
        0x08048b80 <+0>:    push   %ebp
        0x08048b81 <+1>:    mov    %esp,%ebp
        0x08048b83 <+3>:    sub    $0x8,%esp
        0x08048b86 <+6>:    movl   $0x8049928,0x4(%esp)
        0x08048b8e <+14>:   mov    0x8(%ebp),%eax
        0x08048b91 <+17>:   mov    %eax,(%esp)
        0x08048b94 <+20>:   call   0x8049067 <strings_not_equal>
        0x08048b99 <+25>:   test   %eax,%eax
        0x08048b9b <+27>:   je     0x8048ba2 <phase_1+34>
        0x08048b9d <+29>:   call   0x804962e <explode_bomb>
        0x08048ba2 <+34>:   leave  
        0x08048ba3 <+35>:   ret    
    End of assembler dump.
  • Wherein two before the current contents of registers push ebp, esp stack pointer register and the base register and the current stack address ebp modified.

Current state

    栈底方向^
    ...
    main
    ...
    参数
    旧ebp  <- ebp, esp寄存器
  • The third line of the stack pointer move 8 bytes
    栈底方向^
    ...
    旧ebp <- ebp
    空
    空  <- esp寄存器
  • Mov instruction and then two, the two values are the air out of the stack into position, one of which is 0x08049928the other is based on an offset of 8 bytes ebp stack content to the bottom of the stack direction, that is, our argumentsinput
    栈底方向^
    ...
    旧ebp <- ebp
    0x8049928
    0x8(%ebp)  <- esp寄存器
  • Then call the function <strings_not_equal>, so we are in the memory 0x08049928for viewing content, is the string we need to dismantle the bomb.
(gdb) x/s 0x8049928

答案是:Why make trillions when we could make... billions?

phase_2 function

  • Entry(gdb) disassemble phase_1
   0x08048ba4 <+0>:     push    %ebp
   0x08048ba5 <+1>:     mov     %esp,%ebp
   0x08048ba7 <+3>:     sub     $0x28,%esp
   0x08048baa <+6>:     movl    $0x0,-0x4(%ebp)
   0x08048bb1 <+13>:    lea     -0x20(%ebp),%eax
   0x08048bb4 <+16>:    mov     %eax,0x4(%esp)
   0x08048bb8 <+20>:    mov     0x8(%ebp),%eax
   0x08048bbb <+23>:    mov     %eax,(%esp)
   0x08048bbe <+26>:    call    0x8048fd4 <read_six_numbers>
   0x08048bc3 <+31>:    movl    $0x0,-0x8(%ebp)
   0x08048bca <+38>:    jmp     0x8048bf3 <phase_2+79>
   0x08048bcc <+40>:    mov     -0x8(%ebp),%eax
   0x08048bcf <+43>:    mov     -0x20(%ebp,%eax,4),%edx
   0x08048bd3 <+47>:    mov     -0x8(%ebp),%eax
   0x08048bd6 <+50>:    add     $0x3,%eax
   0x08048bd9 <+53>:    mov     -0x20(%ebp,%eax,4),%eax
   0x08048bdd <+57>:    cmp     %eax,%edx
   0x08048bdf <+59>:    je      0x8048be6 <phase_2+66>
   0x08048be1 <+61>:    call    0x804962e <explode_bomb>
   0x08048be6 <+66>:    mov     -0x8(%ebp),%eax
   0x08048be9 <+69>:    mov     -0x20(%ebp,%eax,4),%eax
   0x08048bed <+73>:    add     %eax,-0x4(%ebp)
   0x08048bf0 <+76>:    incl    -0x8(%ebp)
   0x08048bf3 <+79>:    cmpl    $0x2,-0x8(%ebp)
   0x08048bf7 <+83>:    jle     0x8048bcc <phase_2+40>
   0x08048bf9 <+85>:    cmpl    $0x0,-0x4(%ebp)
   0x08048bfd <+89>:    jne     0x8048c04 <phase_2+96>
   0x08048bff <+91>:    call    0x804962e <explode_bomb>
   0x08048c04 <+96>:    leave  
   0x08048c05 <+97>:    ret
  • sub $0x28,%esp

    First, the downward pointer sp vacated space 40B is 0x28, 32-bit system, a total of 10 units, for convenience called M0 ~ M9

  • movl $0x0,-0x4(%ebp)

    No. 0h unit will then set to zero, i.e.M0=0

  • lea -0x20(%ebp),%eax; mov %eax,0x4(%esp)

    No. 7 address unit is assigned to No. 8 cells. That is, M8=&M7it can be inferred, M8 may be a pointer to an array, M7 is the first address of the array.

  • mov 0x8(%ebp),%eax;mov %eax,(%esp);call 0x8048fd4 <read_six_numbers>

    The arguments in the last unit M9, and then calls the function, read 6 digits. Exactly 10 remaining six units, consisting of an array of 6 elements, it should be placed in M6 ~ M2, where we become A0 ~ A5.

  • $movl 0x0,-0x8(%ebp)

    Zeroing out the number 1, M1 = 0

  • $cmpl 0x2,-0x8(%ebp);jle 0x8048bcc <phase_2+40>

    M1 and the second comparator, the loop condition is less than or equal

  • mov -0x8(%ebp),%eax; mov -0x20(%ebp,%eax,4),%edx

    The value ebp-20 + 4 * M1 into edx, in fact, edx = A [M1]

  • -0x8(%ebp),%eax; add $0x3,%eax; mov -0x20(%ebp,%eax,4),%eax

    eax=A[M1+3]

  • cmp %eax,%edx; je 0x8048be6 <phase_2+66>; call 0x804962e <explode_bomb>

    Compare eax and edx, if not equal this call exploed_bomb

  • mov -0x8(%ebp),%eax; mov -0x20(%ebp,%eax,4),%eax; add %eax,-0x4(%ebp); incl -0x8(%ebp)

    The A [M1] is written M0, M1 ++

  • By inference, the original function as follows

    void phase_2(char* input){
        int result = 0;
        int a[6];
        input >> a;
        for(int i=0;i<=2;i++){
            if (a[i]!=a[i+3])
                bomb();
            result += a[i];
        }
        if(reuslt == 0)
            bomb()
    }

So the answer is an array of six elements, a [i], and to a [i + 3] the same, and the sum (a [0], a [1], a [2])! = 0 can be. As 1 2 3 1 2 3or1 1 1 1 1 1

phase_3 function

    Dump of assembler code for function phase_3:
    0x08048c06 <+0>:    push   %ebp
    0x08048c07 <+1>:    mov    %esp,%ebp
    0x08048c09 <+3>:    sub    $0x28,%esp
    0x08048c0c <+6>:    movl   $0x0,-0x8(%ebp)
    0x08048c13 <+13>:   movl   $0x0,-0x4(%ebp)
    0x08048c1a <+20>:   lea    -0x10(%ebp),%eax
    0x08048c1d <+23>:   mov    %eax,0xc(%esp)
    0x08048c21 <+27>:   lea    -0xc(%ebp),%eax
    0x08048c24 <+30>:   mov    %eax,0x8(%esp)
    0x08048c28 <+34>:   movl   $0x804995b,0x4(%esp)
    0x08048c30 <+42>:   mov    0x8(%ebp),%eax
    0x08048c33 <+45>:   mov    %eax,(%esp)
    0x08048c36 <+48>:   call   0x8048868 <sscanf@plt>
    0x08048c3b <+53>:   mov    %eax,-0x4(%ebp)
    0x08048c3e <+56>:   cmpl   $0x1,-0x4(%ebp)
    0x08048c42 <+60>:   jg     0x8048c49 <phase_3+67>
    0x08048c44 <+62>:   call   0x804962e <explode_bomb>
    0x08048c49 <+67>:   mov    -0xc(%ebp),%eax
    0x08048c4c <+70>:   mov    %eax,-0x14(%ebp)
    0x08048c4f <+73>:   cmpl   $0x7,-0x14(%ebp)
    0x08048c53 <+77>:   ja     0x8048c98 <phase_3+146>
    0x08048c55 <+79>:   mov    -0x14(%ebp),%edx
    0x08048c58 <+82>:   mov    0x8049964(,%edx,4),%eax
    0x08048c5f <+89>:   jmp    *%eax
    0x08048c61 <+91>:   addl   $0x2cc,-0x8(%ebp)
    0x08048c68 <+98>:   subl   $0x3a9,-0x8(%ebp)
    0x08048c6f <+105>:  addl   $0x12f,-0x8(%ebp)
    0x08048c76 <+112>:  subl   $0xcb,-0x8(%ebp)
    0x08048c7d <+119>:  addl   $0x5d,-0x8(%ebp)
    0x08048c81 <+123>:  subl   $0x2f4,-0x8(%ebp)
    0x08048c88 <+130>:  addl   $0x2f4,-0x8(%ebp)
    0x08048c8f <+137>:  subl   $0x207,-0x8(%ebp)
    0x08048c96 <+144>:  jmp    0x8048c9d <phase_3+151>
    0x08048c98 <+146>:  call   0x804962e <explode_bomb>
    0x08048c9d <+151>:  mov    -0xc(%ebp),%eax
    0x08048ca0 <+154>:  cmp    $0x5,%eax
    0x08048ca3 <+157>:  jg     0x8048cad <phase_3+167>
    0x08048ca5 <+159>:  mov    -0x10(%ebp),%eax
    0x08048ca8 <+162>:  cmp    %eax,-0x8(%ebp)
    0x08048cab <+165>:  je     0x8048cb2 <phase_3+172>
    0x08048cad <+167>:  call   0x804962e <explode_bomb>
    0x08048cb2 <+172>:  leave  
    0x08048cb3 <+173>:  ret    
    End of assembler dump.
  • 0x08048c06 ~ 0x08048c36

    Were as follows, the application 10 words (4B / word) space M0=0, M1=0, M6=&M3, M7=&M2,M8=0x804995b, M9=%ebp+8(still from ebp-0x4 to ebp-0x28, each as a unit 4B), and then calls the function sscanf.

    Our convention where M9 is input, then the unknown M8, M7, M2 as a parameter to pass a pointer value into M2, M3, since the parameters of the stack in reverse order.

  • We check the contents M8 (0x804995b) of

    It can be found, which is stored character string "% d% d"

    Which tells us two digital inputs and two digital transfer is achieved by precisely two pointers.

  • 0x08048c3b~0x08048c44

    On the sscanfresults of the check to see if greater than 1, otherwise the call bomb ()

  • 0x08048c49~0x08048c53

    Num1 to check requires not more than 7.

  • 0x08048c55~0x08048c5f

    An unconditional jump statement to jump (num1 * 4 + 0x8049964), attention outside *, the branch destination is not num1*4+0x8049964, but the value of the address in the memory, since the current range is not more than 7 num1, little Big

  • 0x08048c61~0x08048c96

    This part should be on a jump statement to jump position, namely M1 plus or minus a certain number.

  • 0x08048c9d~0x08048ca3

    Num1 and then check for required no more than 5, once again reduced the scope herein num1

  • 0x08048ca5~0x08048cab

    And num2 compared to M1, equal requirements

Therefore, it should be num2 calculation result of M1, while the value num1 is less than or equal to 5, we can take 5, num2 calculated position -519

phase_4 function

    Dump of assembler code for function phase_4:
        0x08048ce3 <+0>:    push   %ebp
        0x08048ce4 <+1>:    mov    %esp,%ebp
        0x08048ce6 <+3>:    sub    $0x28,%esp
        0x08048ce9 <+6>:    lea    -0xc(%ebp),%eax
        0x08048cec <+9>:    mov    %eax,0x8(%esp)
        0x08048cf0 <+13>:   movl   $0x8049984,0x4(%esp)
        0x08048cf8 <+21>:   mov    0x8(%ebp),%eax
        0x08048cfb <+24>:   mov    %eax,(%esp)
        0x08048cfe <+27>:   call   0x8048868 <sscanf@plt>
        0x08048d03 <+32>:   mov    %eax,-0x4(%ebp)
        0x08048d06 <+35>:   cmpl   $0x1,-0x4(%ebp)
        0x08048d0a <+39>:   jne    0x8048d13 <phase_4+48>
        0x08048d0c <+41>:   mov    -0xc(%ebp),%eax
        0x08048d0f <+44>:   test   %eax,%eax
        0x08048d11 <+46>:   jg     0x8048d18 <phase_4+53>
        0x08048d13 <+48>:   call   0x804962e <explode_bomb>
        0x08048d18 <+53>:   mov    -0xc(%ebp),%eax
        0x08048d1b <+56>:   mov    %eax,(%esp)
        0x08048d1e <+59>:   call   0x8048cb4 <func4>
        0x08048d23 <+64>:   mov    %eax,-0x8(%ebp)
        0x08048d26 <+67>:   cmpl   $0x78,-0x8(%ebp)
        0x08048d2a <+71>:   je     0x8048d31 <phase_4+78>
        0x08048d2c <+73>:   call   0x804962e <explode_bomb>
        0x08048d31 <+78>:   leave  
        0x08048d32 <+79>:   ret    
    End of assembler dump.
  • 0x08048ce3~0x08048cfe

    Performed as follows: the application stack space 4B * 10, and the M2 ( ebp-0xc) writes the address M7 ( esp+0x8), the 0x8049984write M8, pass incoming parameters into the upper M9, then call<sscanf@plt>

    We 0x8049984check, which is a string %d, an integer with visible read write pointer M2 M7

  • 0x08048d03~0x08048d06

    Of sscanfreturn value check it requires only a numerical value input

  • 0x08048d0c~0x08048d11

    Checking the number of the input request is greater than 0

  • 0x08048d18~0x08048d1e

    As the input parameters, calling func4

  • Check func4

    Can be found, func4 is a recursive factorial function.

  • 0x08048d23~0x08048d2a

    The return value into func4 M1, M1, and 0x78 is compared to the required equal, i.e. in claim M1 == 120

We just need to find the factorial of the number of 120-bit result of that answer: 5

phase_5

    (gdb) disassemble phase_5
    Dump of assembler code for function phase_5:
        0x08048d33 <+0>:    push   %ebp
        0x08048d34 <+1>:    mov    %esp,%ebp
        0x08048d36 <+3>:    sub    $0x18,%esp
        0x08048d39 <+6>:    mov    0x8(%ebp),%eax
        0x08048d3c <+9>:    mov    %eax,(%esp)
        0x08048d3f <+12>:   call   0x804903d <string_length>
        0x08048d44 <+17>:   mov    %eax,-0x4(%ebp)
        0x08048d47 <+20>:   cmpl   $0x6,-0x4(%ebp)
        0x08048d4b <+24>:   je     0x8048d52 <phase_5+31>
        0x08048d4d <+26>:   call   0x804962e <explode_bomb>
        0x08048d52 <+31>:   movl   $0x0,-0x8(%ebp)
        0x08048d59 <+38>:   movl   $0x0,-0xc(%ebp)
        0x08048d60 <+45>:   jmp    0x8048d7e <phase_5+75>
        0x08048d62 <+47>:   mov    -0xc(%ebp),%eax
        0x08048d65 <+50>:   add    0x8(%ebp),%eax
        0x08048d68 <+53>:   movzbl (%eax),%eax
        0x08048d6b <+56>:   movsbl %al,%eax
        0x08048d6e <+59>:   and    $0xf,%eax
        0x08048d71 <+62>:   mov    0x804a5c0(,%eax,4),%eax
        0x08048d78 <+69>:   add    %eax,-0x8(%ebp)
        0x08048d7b <+72>:   incl   -0xc(%ebp)
        0x08048d7e <+75>:   cmpl   $0x5,-0xc(%ebp)
        0x08048d82 <+79>:   jle    0x8048d62 <phase_5+47>
        0x08048d84 <+81>:   cmpl   $0x49,-0x8(%ebp)
        0x08048d88 <+85>:   je     0x8048d8f <phase_5+92>
        0x08048d8a <+87>:   call   0x804962e <explode_bomb>
        0x08048d8f <+92>:   leave  
        0x08048d90 <+93>:   ret    
    End of assembler dump.
  • 0x08048d33~0x08048d44

    Application stack space 4B * 6, the function is called as an input <string_length>, and writes the results M0, i.e.,M0=length(input)

  • 0x08048d47~0x08048d4d

    Checking the input length, length in claim 6.

  • 0x08048d52~0x08048d60

    The M1, M2 assigned to 0, jump

  • 0x08048d62~0x08048d6e

    The (input + M2) 0 expanded into the eax, eax then removed in the corresponding address value, because the input string is in fact, which is equivalent to eax=input[M2], and taken after the eight eax, sign extension write back, and finally taken the last four digits. Here is an ascii code as input, so the range of 0 to 127 0 sign extension must be extended. The final series of operations which is equivalent to the four inputs take ascii code value for each character.

  • 0x08048d71~0x08048d78

    Taken based on 0x804a5c0the content of the shift memory, the accumulated into M1

  • 0x08048d7b~0x08048d82

    M2 increment, is less than or equal to 5 is determined, continue to cycle

  • 0x08048d84

    0x49 bit accumulation results in claim

  • Check the 0x804a5c0contents

    Corresponding values: 2, 10, 6, 1, 12, 16, 9, 3, 4, 7, 14, 5, 11, 8, 15,

    If we take the six, and make equal 0x49

Here, I remove the standard number of 2,5,5,5,5,7 6, as long as the four conditions can be satisfied, so that the string can take255557

phase_6

    (gdb) disassemble phase_6
    Dump of assembler code for function phase_6:
        0x08048e25 <+0>:    push   %ebp
        0x08048e26 <+1>:    mov    %esp,%ebp
        0x08048e28 <+3>:    sub    $0x18,%esp
        0x08048e2b <+6>:    movl   $0x804a660,-0x8(%ebp)
        0x08048e32 <+13>:   mov    0x8(%ebp),%eax
        0x08048e35 <+16>:   mov    %eax,(%esp)
        0x08048e38 <+19>:   call   0x8048858 <atoi@plt>
        0x08048e3d <+24>:   mov    %eax,-0xc(%ebp)
        0x08048e40 <+27>:   mov    -0x8(%ebp),%eax
        0x08048e43 <+30>:   mov    %eax,(%esp)
        0x08048e46 <+33>:   call   0x8048d91 <fun6>
        0x08048e4b <+38>:   mov    %eax,-0x8(%ebp)
        0x08048e4e <+41>:   mov    -0x8(%ebp),%eax
        0x08048e51 <+44>:   mov    %eax,-0x4(%ebp)
        0x08048e54 <+47>:   movl   $0x1,-0x10(%ebp)
        0x08048e5b <+54>:   jmp    0x8048e69 <phase_6+68>
        0x08048e5d <+56>:   mov    -0x4(%ebp),%eax
        0x08048e60 <+59>:   mov    0x8(%eax),%eax
        0x08048e63 <+62>:   mov    %eax,-0x4(%ebp)
        0x08048e66 <+65>:   incl   -0x10(%ebp)
        0x08048e69 <+68>:   cmpl   $0x4,-0x10(%ebp)
        0x08048e6d <+72>:   jne    0x8048e5d <phase_6+56>
        0x08048e6f <+74>:   mov    -0x4(%ebp),%eax
        0x08048e72 <+77>:   mov    (%eax),%eax
        0x08048e74 <+79>:   cmp    -0xc(%ebp),%eax
        0x08048e77 <+82>:   je     0x8048e7e <phase_6+89>
        0x08048e79 <+84>:   call   0x804962e <explode_bomb>
        0x08048e7e <+89>:   leave  
        0x08048e7f <+90>:   ret    
    End of assembler dump.
  • 0x08048e25~0x08048e3d

    Application stack space 4B * 6 will 0x804a660put M1, the input invoked as an argument <atoi@plt>and returns the result is written M2

  • 0x08048e40~0x08048e4b

    The M1 as an argument, call fun6, will return to write the result back M1

  • emmm, fun6 not look

To be continued, ha ha ha

Guess you like

Origin www.cnblogs.com/Axi8/p/11670088.html