clinuxassemblyx86binary-bomb

how to defuse this binary bomb phase 4


I am having trouble this piece of code in assembly language. Essentially I have to input 2 numbers that matches 2 numbers the code is comparing with. On line 0x08048c47 in phase_4, it compares the first input with 2, so I know the first input has to be 2. It then moves 4 spaces from the first input to next input, which then gets 2 subtracted from it. Now the (input-2) is compared with 2. It will continue the instruction if the inputs are below than or equal to 2. I've tested this with numbers 2,3,4 which pass the comparison. Other numbers greater than 4 and less than 2 do not pass the comparison and will cause the bomb to explode.
I'm stuck on this part because the value being returned from func4 is not the same was the value represented at 0x08048c6e in phase_4, which is 8(%esp). On my computer when I debug it, it shows that it is 8, and the answers to my inputs 2,3,4 are 40, 60, 80 respectively.

disas func4
0x08048bda <+0>:    push   %edi
0x08048bdb <+1>:    push   %esi
0x08048bdc <+2>:    push   %ebx
0x08048bdd <+3>:    mov    0x10(%esp),%ebx
0x08048be1 <+7>:    mov    0x14(%esp),%edi
0x08048be5 <+11>:   test   %ebx,%ebx
0x08048be7 <+13>:   jle    0x8048c14 <func4+58>
0x08048be9 <+15>:   mov    %edi,%eax
0x08048beb <+17>:   cmp    $0x1,%ebx
0x08048bee <+20>:   je     0x8048c19 <func4+63>
0x08048bf0 <+22>:   sub    $0x8,%esp
0x08048bf3 <+25>:   push   %edi
0x08048bf4 <+26>:   lea    -0x1(%ebx),%eax
0x08048bf7 <+29>:   push   %eax
0x08048bf8 <+30>:   call   0x8048bda <func4>
0x08048bfd <+35>:   add    $0x8,%esp
0x08048c00 <+38>:   lea    (%edi,%eax,1),%esi
0x08048c03 <+41>:   push   %edi
0x08048c04 <+42>:   sub    $0x2,%ebx
0x08048c07 <+45>:   push   %ebx
0x08048c08 <+46>:   call   0x8048bda <func4>
0x08048c0d <+51>:   add    $0x10,%esp
0x08048c10 <+54>:   add    %esi,%eax
0x08048c12 <+56>:   jmp    0x8048c19 <func4+63>
0x08048c14 <+58>:   mov    $0x0,%eax
0x08048c19 <+63>:   pop    %ebx
0x08048c1a <+64>:   pop    %esi
0x08048c1b <+65>:   pop    %edi
0x08048c1c <+66>:   ret    



disas phase_4
0x08048c1d <+0>:    sub    $0x1c,%esp
0x08048c20 <+3>:    mov    %gs:0x14,%eax
0x08048c26 <+9>:    mov    %eax,0xc(%esp)
0x08048c2a <+13>:   xor    %eax,%eax
0x08048c2c <+15>:   lea    0x4(%esp),%eax
0x08048c30 <+19>:   push   %eax
0x08048c31 <+20>:   lea    0xc(%esp),%eax
0x08048c35 <+24>:   push   %eax
0x08048c36 <+25>:   push   $0x804a25f
0x08048c3b <+30>:   pushl  0x2c(%esp)
0x08048c3f <+34>:   call   0x8048810 <__isoc99_sscanf@plt>
0x08048c44 <+39>:   add    $0x10,%esp
0x08048c47 <+42>:   cmp    $0x2,%eax
0x08048c4a <+45>:   jne    0x8048c58 <phase_4+59>
0x08048c4c <+47>:   mov    0x4(%esp),%eax
0x08048c50 <+51>:   sub    $0x2,%eax
0x08048c53 <+54>:   cmp    $0x2,%eax
0x08048c56 <+57>:   jbe    0x8048c5d <phase_4+64>
0x08048c58 <+59>:   call   0x8049123 <explode_bomb>
0x08048c5d <+64>:   sub    $0x8,%esp
0x08048c60 <+67>:   pushl  0xc(%esp)
0x08048c64 <+71>:   push   $0x6
0x08048c66 <+73>:   call   0x8048bda <func4>
0x08048c6b <+78>:   add    $0x10,%esp
0x08048c6e <+81>:   cmp    0x8(%esp),%eax
0x08048c72 <+85>:   je     0x8048c79 <phase_4+92>
0x08048c74 <+87>:   call   0x8049123 <explode_bomb>
0x08048c79 <+92>:   mov    0xc(%esp),%eax
0x08048c7d <+96>:   xor    %gs:0x14,%eax
0x08048c84 <+103>:  je     0x8048c8b <phase_4+110>
0x08048c86 <+105>:  call   0x8048790 <__stack_chk_fail@plt>
0x08048c8b <+110>:  add    $0x1c,%esp
0x08048c8e <+113>:  ret    

Solution

  • 8(%esp) is the first number, under the framework of x86. enter 40 2 or 60 3 or 80 4 should work.

    Equivalent to the following logic

    #include <stdio.h>
    #include <stdlib.h>
    
    void explode_bomb()
    {
        printf("explode bomb.\n");
        exit(1);
    }
    
    unsigned func4(int val, unsigned num)
    {
        int ret;
    
        if (val <= 0)
            return 0;
    
        if (num == 1)
            return 1;
    
        ret = func4(val - 1, num);
        ret += num;
        val -= 2;
        ret += func4(val, num);
        return ret;
    }
    
    void phase_4(const char *input)
    {
        unsigned num1, num2;
    
        if (sscanf(input, "%u %u", &num1, &num2) != 2)
            explode_bomb();
    
        if (num2 - 2 > 2)
            explode_bomb();
    
        if (func4(6, num2) != num1)
            explode_bomb();
    }
    
    int main()
    {
        phase_4("40 2");
        phase_4("60 3");
        phase_4("80 4");
        printf("success.\n");
        return 0;
    }