【问题标题】:linux 32 bit assembly to C programming convertionlinux 32位汇编到C编程转换
【发布时间】:2019-03-05 11:03:21
【问题描述】:

我想将此 asm 代码转换为 C++ 或 C,我可以理解 main 中的主要概念,例如变量 decleration 和调用函数,但我被 push 和 pop 命令卡住了,无法理解它们是如何工作的。

    main:
   0x080489cc <+0>: lea    ecx,[esp+0x4]
   0x080489d0 <+4>: and    esp,0xfffffff0
   0x080489d3 <+7>: push   DWORD PTR [ecx-0x4]
   0x080489d6 <+10>:    push   ebp
   0x080489d7 <+11>:    mov    ebp,esp
   0x080489d9 <+13>:    push   ebx
   0x080489da <+14>:    push   ecx
   0x080489db <+15>:    sub    esp,0x10
   0x080489de <+18>:    call   0x80488b0 <__x86.get_pc_thunk.bx>
   0x080489e3 <+23>:    add    ebx,0xa261d
   0x080489e9 <+29>:    mov    DWORD PTR [ebp-0xc],0x1
   0x080489f0 <+36>:    mov    DWORD PTR [ebp-0x10],0x3
   0x080489f7 <+43>:    mov    DWORD PTR [ebp-0x14],0x9
   0x080489fe <+50>:    sub    esp,0x4
   0x08048a01 <+53>:    push   DWORD PTR [ebp-0x14]
   0x08048a04 <+56>:    push   DWORD PTR [ebp-0x10]
   0x08048a07 <+59>:    push   DWORD PTR [ebp-0xc]
   0x08048a0a <+62>:    call   0x8048a34 <blender>
   0x08048a0f <+67>:    add    esp,0x10
   0x08048a12 <+70>:    sub    esp,0x8
   0x08048a15 <+73>:    push   eax
   0x08048a16 <+74>:    lea    eax,[ebx-0x2ed18]
   0x08048a1c <+80>:    push   eax
   0x08048a1d <+81>:    call   0x804f100 <printf>
   0x08048a22 <+86>:    add    esp,0x10
   0x08048a25 <+89>:    mov    eax,0x0
   0x08048a2a <+94>:    lea    esp,[ebp-0x8]
   0x08048a2d <+97>:    pop    ecx
   0x08048a2e <+98>:    pop    ebx
   0x08048a2f <+99>:    pop    ebp
   0x08048a30 <+100>:   lea    esp,[ecx-0x4]
   0x08048a33 <+103>:   ret    

blender:
   0x08048a34 <+0>: push   ebp
   0x08048a35 <+1>: mov    ebp,esp
   0x08048a37 <+3>: call   0x8048a51 <__x86.get_pc_thunk.ax>
   0x08048a3c <+8>: add    eax,0xa25c4
   0x08048a41 <+13>:    mov    edx,DWORD PTR [ebp+0x8] 
   0x08048a44 <+16>:    mov    eax,DWORD PTR [ebp+0xc] 
   0x08048a47 <+19>:    add    eax,edx 
   0x08048a49 <+21>:    add    eax,eax 
   0x08048a4b <+23>:    imul   eax,DWORD PTR [ebp+0x10] 
   0x08048a4f <+27>:    pop    ebp
   0x08048a50 <+28>:    ret

【问题讨论】:

标签: assembly x86 stack


【解决方案1】:

main() 内部 从 0x080489e9 到 0x080489f7 // 清除三个 4 字节整数并用 1,3 和 9 初始化它们 我们可以假设这部分是:

int a = 1;
int b = 3;
int c = 9;

从 0x08048a01 到 0x08048a0a // 从右到左推送变量以将它们作为参数发送到搅拌机函数,然后调用搅拌机 搅拌机(a,b,c);

内部搅拌器()

 0x08048a41 <+13>:  mov    edx,DWORD PTR [ebp+0x8] // edx = 1
   0x08048a44 <+16>:    mov    eax,DWORD PTR [ebp+0xc] // eax = 3
   0x08048a47 <+19>:    add    eax,edx // eax = eax+edx = 4
   0x08048a49 <+21>:    add    eax,eax //eax = 2*eax
   0x08048a4b <+23>:    imul   eax,DWORD PTR [ebp+0x10] //[ebp +0x10] = 9 imul means signed multiply so this means; eax = eax * 9 
        pop

类似

return 2*(a+b) *c // 2*(1+3) * 9 = 72

blender 调用后调用 0x08048a1d : call 0x804f100 函数并打印结果,中间没有其他变量声明我认为是printf里面直接调用

prinf("%d" , blender())

最终代码如下所示:

int main()
{
    int a = 1;
    int b = 3;
    int c = 9;

    printf("%d" , blender(a,b,c));
    return 0;
}

int blender(int a, int b, int c)
{
    return 2*(a+b) * c;
}

【讨论】:

  • imul 的多操作数形式,如imul r32, r/m32,没有具体的有符号或无符号,它们都是,如add。只有单操作数 mul r/m32imul r/m32 是明确无符号或有符号的,因为结果的上半部分(在 EDX 中)不同。这就是英特尔没有同时制作 2 操作数或 mul 的直接版本的原因。
  • 是的,从这显然是未优化的编译器输出这一事实来看,blender 结果的源中没有临时变量是对的。否则它将被存储/重新加载。
  • 另外值得一提的是,可能令人困惑的call 0x80488b0 &lt;__x86.get_pc_thunk.bx&gt; 将thunk 返回地址加载到EBX 中,而gcc 这样做是因为它是用-fPIE 编译的,以生成与位置无关的可执行文件。但是 32 位 x86 不支持 RIP 相对寻址。对于逆向工程的初学者来说,这是一个奇怪的额外障碍;使用gcc -no-pie -fno-pie 构建的普通可执行文件会更好(即使这不是现代 Linux 的默认设置。)
猜你喜欢
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
相关资源
最近更新 更多