问题描述:

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 <[email protected]>

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.

网友答案:

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 <[email protected]>
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.

相关阅读:
Top