反编译如何工作?

Eph*_*aim 20 decompiling

我之前听过"反编译"这个术语几次,我开始对它的工作原理感到非常好奇.

我对它是如何工作有一个非常笼统的想法; 对应用程序进行逆向工程以查看它使用的功能,但除此之外我不太了解.

我也听过" 反汇编程序 " 这个术语,反汇编程序和反编译程序有什么区别?

总结一下我的问题:反编译过程究竟涉及到什么?通常怎么做?流程有多复杂/简单?它可以产生确切的代码吗?反编译器和反汇编程序有什么区别?

kub*_*uba 21

Hex-Rays Decompiler的作者Ilfak Guilfanov 发表了关于他的反编译器内部工作的演讲,这里是白皮书演示文稿.这描述了一个很好的概述,即构建反编译器的所有困难以及如何使其全部工作.

除此之外,还有一些相当古老的论文,例如Cristina Cifuentes经典博士论文.

至于复杂性,所有"反编译"的东西都取决于二进制文件的语言和运行时间.例如,反编译.NET和Java被认为是"完成",因为有可用的免费反编译器,它们具有非常高的成功率(它们产生原始源).但这是由这些运行时使用的虚拟机的特定性质引起的.

对于真正编译的语言,如C,C++,Obj-C,Delphi,Pascal,......任务变得复杂得多.阅读以上文章了解详情.

反汇编程序和反编译程序有什么区别?

当你有一个二进制程序(可执行文件,DLL库,......)时,它包含处理器指令.这些指令的语言称为汇编(或汇编程序).在二进制文件中,这些指令是二进制编码的,因此处理器可以直接执行它们.一个反汇编借此二进制代码并将其转换为文本表示.此转换通常为1对1,表示一条指令显示为一行文本.这项任务很复杂,但很简单,程序只需知道所有不同的指令以及它们如何用二进制表示.

另一方面,反编译器执行更艰巨的任务.它需要二进制代码或反汇编程序输出(基本相同,因为它是1比1)并产生高级代码.让我举个例子.假设我们有这个C函数:

int twotimes(int a) {
    return a * 2;
}
Run Code Online (Sandbox Code Playgroud)

编译时,编译器首先为该函数生成一个汇编文件,它可能如下所示:

_twotimes:
    SHL EAX, 1
    RET
Run Code Online (Sandbox Code Playgroud)

(第一行只是一个标签,而不是一个真正的指令,SHL左移操作,快速乘以2,RET表示该功能已完成).在结果二进制文件中,它看起来像这样:

08 6A CF 45 37 1A
Run Code Online (Sandbox Code Playgroud)

(我提出了这个,而不是真正的二进制指令).现在您知道,反汇编程序会将您从二进制形式带到汇编表单.甲反编译器将您从组件形式的C代码(或某些其他高级语言).

  • 这个答案的链接已失效,有人有最新的参考资料吗? (3认同)
  • @ProdigySim 1)https://web.archive.org/web/20200410182642/https://www.hex-rays.com/products/decompiler/compare_vs_disassemble/ 2)https://web.archive.org/web/ 20181014083034/https://www.hex-rays.com/products/ida/support/ppt/decompilers_and_beyond_white_paper.pdf 3)https://web.archive.org/web/20181222035256/https://www.hex-rays .com/products/ida/support/ppt/decompilers_and_beyond.ppt 4) https://web.archive.org/web/20130407233420/http://itee.uq.edu.au/~cristina/dcc.html (2认同)

Nic*_*ick 6

反编译本质上是编译的逆过程。也就是说,获取目标代码(二进制)并尝试从中重新创建源代码。

反编译取决于目标代码中留下的工件,这些工件可用于确定源代码的结构。

对于 C/C++ 来说,没有太多的东西可以帮助反编译过程,所以它非常困难。然而,对于 Java 和 C# 以及其他面向虚拟机的语言,反编译会更容易,因为这些语言在目标代码中留下了更多提示。

  • “反编译本质上是编译的逆过程”——多么奇妙的见解啊。 (7认同)
  • @MarcoPrins:Hexrays 说一般来说不,这并不总是可能的。必须对编译指南做出假设(例如使用了“通常的”流行编译器,而不是一些奇怪的特殊非标准化黑客实现或“邪恶的”手工汇编)。 (4认同)
  • 每个人都说这“很难”——但这总是_可能_吗? (2认同)