编译后的二进制文件 - 反汇编指令对应于 C/C++ 源代码(Linux GCC)

逆向工程 C++ C 拆卸
2021-06-13 01:13:13

对凌乱的标题感到抱歉!基本上这就是我想知道的。

这听起来可能有点傻,但是,如果您有反汇编的指令,请说:

jz 0x8048e1a

并且您还有源代码,您如何弄清楚该指令与源代码相关的内容?

我应该提到我使用英特尔的 PIN 作为吐出这些反汇编指令的应用程序,所以我知道这些指令属于哪个函数/例程,我只是想更精确一点。

感谢您的任何帮助/提示。

3个回答

如果您有源代码(以及编译它的方法),则不应使用反编译器。编译器已经在原始源代码和汇编指令之间生成映射;这就是调试信息

查看它运行的最简单方法是在调试器中启动程序,设置一个断点,当该断点命中时,切换到反汇编视图。这将向您显示说明,以及导致它们的源代码行。(如果编译器启用了优化,两者之间不会总是有很好的对应关系,但您至少可以看到基本原理。)

您还可以告诉编译器在代码生成阶段后停止,并输出汇编文件而不是目标代码。根据编译器的不同,您也可以使用源代码行注释程序集;这将产生与您在调试器的反汇编视图中看到的类似的信息。

你如何做这一切的细节完全取决于你的 IDE。阅读其文档。

如果您使用 GCC 工具链,您可以使用 objdump 来反汇编和混合源代码:

objdump -S executable > disasm.txt

有关更多选项和信息,请参阅 objdump 手册页。

如果您使用不同的工具链,请参阅该工具链的文档。

对于该特定指令:

jz 0x8048e1a
  • 这是一个条件跳转,因此在您的函数中搜索if, for, do/while或三元表达式 ( ?:)
  • 如果设置了零标志,它会跳转,但您需要检查前面的指令以查看设置该标志的内容。您可以将该逻辑与您在上面确定的分支条件之一对齐
  • 它跳转到一个地址 - 它在哪里?该地址的代码有什么作用?您可以将其与条件分支的内容相匹配。
  • 如果它分支会发生什么您可以将与条件分支(或未采用的分支的隐式跳转)对齐
  • 请注意,编译器/优化器允许反转比较和分支的意义,例如跳转到嵌套块,然后返回

一般来说:

  • 如果您有源代码,请编译为汇编程序并包含您的编译器支持的所有源代码和行号注释
    • 在禁用优化的情况下执行一次可能会有所帮助,因此您可以获得相当干净的翻译,然后将其与优化版本进行比较。中间步骤可以帮助澄清您的优化器更改了什么。
  • 如果您有源代码但无法编译(或不知道使用的编译标志),请包含所有源代码等。反汇编程序支持的注释
  • 在代码中寻找与众不同的点:
    • 函数入口和出口很容易被发现
    • 对外部(尤其是 libc 或其他库)函数的调用应该清晰地显示出来,并限制优化器至少重新排序函数参数和依赖于其结果的逻辑的能力
  • 指令步骤通过在调试器的代码,看两者的源极线数和指令。如果优化器很忙,行号可能会疯狂地跳动,但它会让您了解两者之间的关系
  • 只需阅读源代码并了解其逻辑和控制流程即可。然后只需阅读程序集并了解它的逻辑和控制流程。然后想想他们是如何匹配的。