【发布时间】:2019-01-22 00:58:50
【问题描述】:
我从代码中发现了可执行文件
int main(int argc, char** argv) {
printf("Hello World\n");
return 0;
}
可以反汇编成(使用gcc -m32编译)
此代码来自另一个人
; Variables:
; arg_4: 12
; arg_0: 8
; var_4: -4
; var_8: -8
; var_C: -12
; var_10: -16
; var_18: -24
push ebp
mov ebp, esp
sub esp, 0x18
call _main+11
pop eax ; CODE XREF=_main+6
mov ecx, dword [ebp+arg_4]
mov edx, dword [ebp+arg_0]
lea eax, dword [eax-0x1f5b+0x1fa6] ; "Hello World!\\n"
mov dword [ebp+var_4], 0x0
mov dword [ebp+var_8], edx
mov dword [ebp+var_C], ecx
mov dword [esp+0x18+var_18], eax ; method imp___symbol_stub__printf
call imp___symbol_stub__printf
xor ecx, ecx
mov dword [ebp+var_10], eax
mov eax, ecx
add esp, 0x18
pop ebp
ret
但是当我用相同的代码反汇编可执行文件时(使用 gcc -m32 编译)
我得到了一个很长的反汇编代码(here is the link)
我的问题是
为什么相同代码的指令不同?或者,它们是一样的吗?
是否有任何编译器或编译器选项可供我使用,以提供与其他人一样的反汇编代码?
您是否推荐任何我可以阅读的参考资料来理解长汇编代码中的术语? (如__x86.get_pc_thunk.dx)
最好的问候, 泰森
【问题讨论】:
-
你确定不是第一种情况下的
gcc -m32 -O2吗?当我使用-O2编译时,我得到了短代码,而当我没有它编译时,我得到了长代码。 -
您可以反汇编以下任意一种:
foo.o通过gcc -m32 -c foo.c创建。或者,foo来自gcc -m32 -o foo foo.c。第一个只是目标文件,并且会更短,只是反汇编其中的main函数。后者是完全链接的可执行文件,将具有运行程序所需的所有功能,并且会更大。你反汇编了完整的可执行文件。 -
注意对方的代码叫
printf。但是,您的编译器将printf("Hello world\n");转换为puts("Hello world\n");这些是编译器和stdio.h在两个系统上的差异。 -
可能不值得从可执行文件中破解
get_pc_thunk。 如果你真的想知道,追踪这些函数的源代码 [应该有cmets]。这是一个很高的要求,因为起源可能在编译器、ELF 解释器、ld链接器或glibc中。此外,您还需要了解链接器等以及它们是如何工作的。 -
@Craig 哇,谢谢你的 cmets,Craig!我可以更好地理解。我知道看到了区别。
标签: c compiler-optimization disassembly