编译旧的C代码+ X86 Disassmbley它

时间:2018-06-29 06:02:09

标签: c gcc compilation x86 reverse-engineering

我正在写《黑客:剥削的艺术》一书,并试图与作家同行,弄脏我的手。
我下载了源代码,在编译它们时,我得到了相同的输出C可执行文件。但是当我使用GDB进行反汇编时,它们具有不同的地址和不同的反汇编代码!我执行与书中相同的命令!

顺便说一下,我已经使用以下命令进行编译:

gcc -m32 -g code.c

我正在使用64位PC并学习x86汇编。
那怎么了是因为它是旧的源代码还是什么?

1 个答案:

答案 0 :(得分:2)

TL;DR 在正常情况下,您无法匹配在不同于书中的机器上编译的二进制文件的完全相同的地址。

即使认为这个问题有点抽象,我也会尽量简洁。请记住,您的本地调试器与本书中的地址之间的地址众多的原因很多,因此我在下面列出的绝对不是详尽无遗的。

  1. ASLR(地址空间布局随机化)

ASLR 的作用是将内存地址的较高字节随机化(因此,它不会随机化 ELF 内部函数变量之间的偏移量),以此作为针对众所周知的二进制漏洞利用策略的安全机制

假设我们已经编译了一些代码,例如function_A 和 function_B(假设我们在类 Unix 系统上,并且编译器的标志正是您建议的标志):如果您在 ELF 文件加载到内存之前查看它,例如在 {{ 1}}(因此您正在查看 ELF 本身的字节表示)您会发现 gdb 的地址类似于 function_A,而 0x0000ABCD 的地址类似于 ```0x0000EF12 `.如果您在 function_B 中设置断点,运行二进制文件并再次检查地址,您会发现地址现在已更改为类似 main0xUUUUABCD0xUUUUEF12 . 附注GDB 默认禁用 ASLR,因此要观察不同的地址加载,您必须关闭它并再次重复该过程,或者从 U = Unknown 内部禁用 ASLR。

  1. 编译器更改

如果我没记错的话,这本书是在 2003 年左右首次出版的。从那时起,GCC 编译器发生了很大变化。考虑到即使对编译器代码进行很小的更改,也会对其生成的可执行文件产生显着差异。例如,理解为什么 gdb 的程序集表示甚至可能与近 20 年前的表示不接近的原因是很重要的。 (我知道这有点抽象)但深入研究这需要我写一本书来解释,但我建议你看看编译器:function_A aka Principles, Techniques, and Tools。< /p>

  1. 操作系统环境

自从 Ubuntu(以及一般的 Linux 发行版)这本书出版以来,它们的版本也发生了很大变化,它们也在不断发展,并添加了一些功能(并删除了其他功能),这些功能会影响例如负责将程序加载到 RAM 上的加载器。话虽如此,请记住,更改操作系统,尤其是如果您更改 Linux 发行版系列(例如,从基于 Debian 的系统变为基于 Fedora 的系统)会影响二进制文件在内存中加载的方式,这当然是区分内存中的地址。