二进制炸弹汇编语言分配

时间:2013-11-19 15:24:25

标签: assembly x86 gdb gnu att

像这里的许多人一样,我被赋予了完成炸弹实验室的任务。我已经能够很容易地完成前3个,但是这个阶段让我失望了。我已经确定答案包含%d%d形式的2个答案,但我无法跟踪递归汇编。

这是一项给予学生炸弹的任务,并且必须输入各种输入以禁用所有6个阶段。如果用户输入了错误的输入,炸弹就会爆炸。您没有获得源代码,只有可执行文件。这是拆卸阶段“第4阶段”。它还需要func4,因此也会被反汇编。

这是解散炸弹所需的Phase_4和func4的objdump -d

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.

1 个答案:

答案 0 :(得分:0)

编辑:实际上,真的很累......混淆参数和局部变量通常不是我犯的错误......

纠正逆向工程:
对于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

因此,调用sscanf()格式字符串存储在0x804a64c(可能是"%d %d"),将参数phase4()作为字符串解析;即在C源中,sscanf("%d "%d", phase4_arg, &l, &m); lm为本地int vars。它测试了两个数字已经成功解析,然后检查它们的值。