Question

Like many people here, I have been given the task to do the bomb lab. I have been able to do the first 3 rather easily, but this phase escapes me. I have determined that the answer includes 2 answers in the form of %d %d, but I have been unable to follow the recursive assembly.

It is an assignment where a student is given a bomb, and has to input various inputs to disable all 6 stages. If the user inputs the wrong input, the bomb explodes. You are not given the source code, only the executable. This is the disassembled phase "phase 4". It also calls for func4, so that is disassembled as well.

Here is the objdump -d of the Phase_4 and func4 which are needed to defuse the bomb

Dump of assembler code for function phase_4:
0x08048f41 <+0>:     push   %ebp
0x08048f42 <+1>:     mov    %esp,%ebp
0x08048f44 <+3>:     sub    $0x28,%esp
0x08048f47 <+6>:     lea    -0x10(%ebp),%eax
0x08048f4a <+9>:     mov    %eax,0xc(%esp)
0x08048f4e <+13>:    lea    -0xc(%ebp),%eax
0x08048f51 <+16>:    mov    %eax,0x8(%esp)
0x08048f55 <+20>:    movl   $0x804a64c,0x4(%esp)
0x08048f5d <+28>:    mov    0x8(%ebp),%eax
0x08048f60 <+31>:    mov    %eax,(%esp)
0x08048f63 <+34>:    call   0x8048894 <__isoc99_sscanf@plt>
0x08048f68 <+39>:    cmp    $0x2,%eax
0x08048f6b <+42>:    jne    0x8048f79 <phase_4+56>
0x08048f6d <+44>:    mov    -0xc(%ebp),%eax
0x08048f70 <+47>:    test   %eax,%eax
0x08048f72 <+49>:    js     0x8048f79 <phase_4+56>
0x08048f74 <+51>:    cmp    $0xe,%eax
0x08048f77 <+54>:    jle    0x8048f7e <phase_4+61>
0x08048f79 <+56>:    call   0x80493e1 <explode_bomb>
0x08048f7e <+61>:    movl   $0xe,0x8(%esp)
0x08048f86 <+69>:    movl   $0x0,0x4(%esp)
0x08048f8e <+77>:    mov    -0xc(%ebp),%eax
0x08048f91 <+80>:    mov    %eax,(%esp)
0x08048f94 <+83>:    call   0x8048c80 <func4>
0x08048f99 <+88>:    cmp    $0x12,%eax
0x08048f9c <+91>:    jne    0x8048fa4 <phase_4+99>
0x08048f9e <+93>:    cmpl   $0x12,-0x10(%ebp)
0x08048fa2 <+97>:    je     0x8048fad <phase_4+108>
0x08048fa4 <+99>:    lea    0x0(%esi,%eiz,1),%esi
0x08048fa8 <+103>:   call   0x80493e1 <explode_bomb>
0x08048fad <+108>:   leave
0x08048fae <+109>:   xchg   %ax,%ax
0x08048fb0 <+111>:   ret
End of assembler dump.

Dump of assembler code for function func4:
0x08048c80 <+0>:     push   %ebp
0x08048c81 <+1>:     mov    %esp,%ebp
0x08048c83 <+3>:     sub    $0x18,%esp
0x08048c86 <+6>:     mov    %ebx,-0x8(%ebp)
0x08048c89 <+9>:     mov    %esi,-0x4(%ebp)
0x08048c8c <+12>:    mov    0x8(%ebp),%eax
0x08048c8f <+15>:    mov    0xc(%ebp),%edx
0x08048c92 <+18>:    mov    0x10(%ebp),%esi
0x08048c95 <+21>:    mov    %esi,%ecx
0x08048c97 <+23>:    sub    %edx,%ecx
0x08048c99 <+25>:    mov    %ecx,%ebx
0x08048c9b <+27>:    shr    $0x1f,%ebx
0x08048c9e <+30>:    lea    (%ebx,%ecx,1),%ecx
0x08048ca1 <+33>:    sar    %ecx
0x08048ca3 <+35>:    lea    (%ecx,%edx,1),%ebx
0x08048ca6 <+38>:    cmp    %eax,%ebx
0x08048ca8 <+40>:    jle    0x8048cc1 <func4+65>
0x08048caa <+42>:    lea    -0x1(%ebx),%ecx
0x08048cad <+45>:    mov    %ecx,0x8(%esp)
0x08048cb1 <+49>:    mov    %edx,0x4(%esp)
0x08048cb5 <+53>:    mov    %eax,(%esp)
0x08048cb8 <+56>:    call   0x8048c80 <func4>
0x08048cbd <+61>:    add    %eax,%ebx
0x08048cbf <+63>:    jmp    0x8048cda <func4+90>
0x08048cc1 <+65>:    cmp    %eax,%ebx
0x08048cc3 <+67>:    jge    0x8048cda <func4+90>
0x08048cc5 <+69>:    mov    %esi,0x8(%esp)
0x08048cc9 <+73>:    lea    0x1(%ebx),%edx
0x08048ccc <+76>:    mov    %edx,0x4(%esp)
0x08048cd0 <+80>:    mov    %eax,(%esp)
0x08048cd3 <+83>:    call   0x8048c80 <func4>
0x08048cd8 <+88>:    add    %eax,%ebx
0x08048cda <+90>:    mov    %ebx,%eax
0x08048cdc <+92>:    mov    -0x8(%ebp),%ebx
0x08048cdf <+95>:    mov    -0x4(%ebp),%esi
0x08048ce2 <+98>:    mov    %ebp,%esp
0x08048ce4 <+100>:   pop    %ebp
0x08048ce5 <+101>:   ret
End of assembler dump.
Was it helpful?

Solution

Edit: actually, been really tired... mixing up arguments and local vars isn't usually an error I make ...

Corrected reverse engineering:
Still only parts of this, for phase4():

0x08048f47 <+6>:     lea    -0x10(%ebp),%eax
0x08048f4a <+9>:     mov    %eax,0xc(%esp)            <== arg3 (&(int l)) sscanf()
0x08048f4e <+13>:    lea    -0xc(%ebp),%eax
0x08048f51 <+16>:    mov    %eax,0x8(%esp)            <== arg2 (&(int m)) sscanf()
0x08048f55 <+20>:    movl   $0x804a64c,0x4(%esp)      <== arg0 (fmt) sscanf()
0x08048f5d <+28>:    mov    0x8(%ebp),%eax
0x08048f60 <+31>:    mov    %eax,(%esp)               <== arg0 --> arg1 sscanf()
0x08048f63 <+34>:    call   0x8048894 <__isoc99_sscanf@plt>
0x08048f68 <+39>:    cmp    $0x2,%eax
0x08048f6b <+42>:    jne    0x8048f79 <phase_4+56>    <== if (sscanf(...) != 2)
0x08048f6d <+44>:    mov    -0xc(%ebp),%eax                   explode_bomb();
0x08048f70 <+47>:    test   %eax,%eax
0x08048f72 <+49>:    js     0x8048f79 <phase_4+56>    <== if (m < 0) // signed
0x08048f74 <+51>:    cmp    $0xe,%eax                         explode_bomb();
0x08048f77 <+54>:    jle    0x8048f7e <phase_4+61>    <== if (!(m <= 14))
0x08048f79 <+56>:    call   0x80493e1 <explode_bomb>          explode_bomb();
[ ... ]
0x08048f94 <+83>:    call   0x8048c80 <func4>
0x08048f99 <+88>:    cmp    $0x12,%eax                <== if (func4(...) != 18)
0x08048f9c <+91>:    jne    0x8048fa4 <phase_4+99>            explode_bomb();
0x08048f9e <+93>:    cmpl   $0x12,-0x10(%ebp)         <== if (l != 18)
0x08048fa2 <+97>:    je     0x8048fad <phase_4+108>           explode_bomb();
0x08048fa4 <+99>:    lea    0x0(%esi,%eiz,1),%esi
0x08048fa8 <+103>:   call   0x80493e1 <explode_bomb>
0x08048fad <+108>:   leave

So this calls sscanf() with the format string stored at 0x804a64c (likely "%d %d"), giving the argument to phase4() as string-to-parse; i.e. in C source, it's sscanf("%d "%d", phase4_arg, &l, &m); with l and m being local int vars. It tests that two numbers have sucessfully been parsed, and later checks their values.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top