map exe反编译回C语言

Jsh*_*hee 2 c windows assembly decompiling objdump

我对组装很陌生,我正在尽力学习它。我参加了一门课程来学习它,他们提到了一个非常补救的 Hello World 示例,我反编译了它。

原始c文件:

#include <stdio.h>
int main()
{
printf("Hello Students!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是使用以下命令反编译的:

C:> objdump -d -Mintel HelloStudents.exe > disasm.txt
Run Code Online (Sandbox Code Playgroud)

反编译(组装):

push ebp
mov  ebp, esp
and  esp, 0xfffffff0
sub esp, 0x10
call 401e80 <__main>
mov DWORD PTR [esp], 0x404000
call 4025f8 <_puts>
mov eax, 0x0
leave
ret
Run Code Online (Sandbox Code Playgroud)

我在将这个输出从反编译映射到原始 C 文件时遇到问题有人可以帮忙吗?

非常感谢!

Joh*_*ode 7

将汇编反编译回 C 的技术术语是“将汉堡包变回奶牛”。生成的程序集不会是源代码的 1 对 1 翻译,并且根据优化级别可能会完全不同。您将获得与原始源在功能上等效的东西,但它在结构上与源的相似程度是可变的。

push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
Run Code Online (Sandbox Code Playgroud)

这都是序言,为main函数设置堆栈帧。它将堆栈指针 (ESP) 对齐 16 个字节,然后为传出函数 args 保留另外 16 个字节的空间。

call 401e80, <___main>
Run Code Online (Sandbox Code Playgroud)

这个函数调用___main是 MinGW 如何安排 libc 初始化函数在程序开始时运行,确保分配 stdio 缓冲区等等。


这是序言的结尾;在源代码中实现 C 语句的函数部分以以下内容开头:

mov DWORD PTR [esp], 0x404000
Run Code Online (Sandbox Code Playgroud)

这将写入字符串字面量"Hello Students!" onto the stack. Combined with the earliersub esp, 16 , this is like apush` 指令的地址。在这个 32 位调用约定中,函数 args 在堆栈上传递,而不是寄存器,因此编译器必须将它们放在函数调用之前。

call 4025f8 <_puts>
Run Code Online (Sandbox Code Playgroud)

这会调用puts函数。编译器意识到您没有在printf调用中进行任何格式处理,并将其替换为更简单的puts调用。

mov eax, 0x0
Run Code Online (Sandbox Code Playgroud)

的返回值main加载到eax寄存器中

leave
ret
Run Code Online (Sandbox Code Playgroud)

恢复之前的 EBP 值,并拆除栈帧,然后退出函数。 ret从堆栈中弹出一个返回地址,只有当 ESP 指向返回地址时才能工作。

  • *这会加载字符串“Hello Students!”的地址 进入 esp 寄存器* - 不,它*存储*该地址到堆栈顶部!它不会修改 ESP,只会修改 ESP 指向的内存。GCC 已经移动了堆栈指针以腾出空间,因此它这样做而不是“push 0x404000”/“call”来将地址作为堆栈参数传递。ESP是堆栈指针。 (3认同)