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 文件时遇到问题有人可以帮忙吗?
非常感谢!
将汇编反编译回 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 指向返回地址时才能工作。