map exe反编译回C语言
map exe decompilation back to C language
我对汇编还很陌生,正在尽最大努力学习它。我正在上一门课程来学习它,他们提到了一个非常有帮助的 Hello World 示例,我没有遵守。
原始c文件:
#include <stdio.h>
int main()
{
printf("Hello Students!");
return 0;
}
这是使用以下命令反编译的:
C:> objdump -d -Mintel HelloStudents.exe > disasm.txt
反编译(汇编):
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
我在将反编译的输出映射到原始 C 文件时遇到问题,有人可以帮忙吗?
非常感谢!
将汇编反编译回 C 的技术术语是 "turning hamburger back into cows"。生成的程序集将 而不是 是源的 1 对 1 翻译,并且根据优化级别可能会有根本不同。您将获得在功能上与原始来源相同的东西,但它在结构上与该来源的相似程度存在很大差异。
push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
这都是序言,为 main
函数设置堆栈帧。它将堆栈指针 (ESP) 对齐 16 个字节,然后为传出函数参数保留另外 16 个字节的 space。
call 401e80, <___main>
这个对 ___main
的函数调用是 MinGW 如何在程序开始时将 libc 初始化函数安排到 运行,确保分配了 stdio 缓冲区和类似的东西。
序言到此结束;在您的源代码中实现 C 语句的函数部分以:
开头
mov DWORD PTR [esp], 0x404000
这写入字符串文字的地址 "Hello Students!" onto the stack. Combined with the earlier
sub esp, 16, this is like a
push` 指令。在此 32 位调用约定中,函数参数在堆栈上传递,而不是在寄存器上传递,因此编译器必须在函数调用之前将它们放在此处。
call 4025f8 <_puts>
这会调用 puts
函数。编译器意识到您没有在 printf
调用中进行任何格式处理,并将其替换为更简单的 puts
调用。
mov eax, 0x0
main
的return值加载到eax
寄存器
leave
ret
恢复之前的EBP值,并拆除栈帧,然后退出函数。 ret
从堆栈中弹出一个 return 地址,只有当 ESP 指向 return 地址时才能工作。
我对汇编还很陌生,正在尽最大努力学习它。我正在上一门课程来学习它,他们提到了一个非常有帮助的 Hello World 示例,我没有遵守。
原始c文件:
#include <stdio.h>
int main()
{
printf("Hello Students!");
return 0;
}
这是使用以下命令反编译的:
C:> objdump -d -Mintel HelloStudents.exe > disasm.txt
反编译(汇编):
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
我在将反编译的输出映射到原始 C 文件时遇到问题,有人可以帮忙吗?
非常感谢!
将汇编反编译回 C 的技术术语是 "turning hamburger back into cows"。生成的程序集将 而不是 是源的 1 对 1 翻译,并且根据优化级别可能会有根本不同。您将获得在功能上与原始来源相同的东西,但它在结构上与该来源的相似程度存在很大差异。
push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
这都是序言,为 main
函数设置堆栈帧。它将堆栈指针 (ESP) 对齐 16 个字节,然后为传出函数参数保留另外 16 个字节的 space。
call 401e80, <___main>
这个对 ___main
的函数调用是 MinGW 如何在程序开始时将 libc 初始化函数安排到 运行,确保分配了 stdio 缓冲区和类似的东西。
序言到此结束;在您的源代码中实现 C 语句的函数部分以:
开头mov DWORD PTR [esp], 0x404000
这写入字符串文字的地址 "Hello Students!" onto the stack. Combined with the earlier
sub esp, 16, this is like a
push` 指令。在此 32 位调用约定中,函数参数在堆栈上传递,而不是在寄存器上传递,因此编译器必须在函数调用之前将它们放在此处。
call 4025f8 <_puts>
这会调用 puts
函数。编译器意识到您没有在 printf
调用中进行任何格式处理,并将其替换为更简单的 puts
调用。
mov eax, 0x0
main
的return值加载到eax
寄存器
leave
ret
恢复之前的EBP值,并拆除栈帧,然后退出函数。 ret
从堆栈中弹出一个 return 地址,只有当 ESP 指向 return 地址时才能工作。