反编译是如何工作的?

28

我之前听说过"反编译"这个词,现在对它的工作原理非常好奇。

大概明白它的工作原理是逆向工程一个应用程序以查看它使用了哪些功能,但除此之外我并不知道太多。

我还听说过"反汇编器"这个术语,那么反汇编器和反编译器有什么区别呢?

综上所述,我的问题是:反编译的过程具体涉及什么?通常如何进行?它的复杂程度如何?它能够生成精确的代码吗?反编译器和反汇编器之间有什么区别?


可能是什么是反编译器,它如何工作?的重复问题。 - Greg Bacon
2个回答

31
Ilfak Guilfanov是Hex-Rays反编译器的作者,在某个会议上发表了有关其反编译器内部工作原理的演讲,这里有白皮书演示文稿。它描述了构建反编译器所遇到的所有困难以及如何使其正常工作的概述。
除此之外,还有一些相当古老的论文,例如Cristina Cifuentes的经典博士论文
关于复杂性,所有“反编译”工作都取决于二进制文件的语言和运行时。例如,反编译.NET和Java被认为是“完成的”,因为有可用的免费反编译器,它们具有非常高的成功率(它们生成原始源代码)。但这是由于这些运行时使用的虚拟机的非常特定的性质所导致的。
至于像C、C++、Obj-C、Delphi、Pascal等真正编译的语言,任务变得更加复杂。有关详细信息,请阅读上述论文。
什么是反汇编器和反编译器之间的区别?
当您拥有一个二进制程序(可执行文件、DLL库等)时,它由处理器指令组成。这些指令的语言称为汇编语言(或汇编器)。在二进制文件中,这些指令以二进制编码的形式出现,以便处理器可以直接执行它们。反汇编器将这个二进制代码转换为文本表示形式。这个转换通常是1对1的,也就是说,一个指令显示为一行文本。这个任务很复杂,但很直接,程序只需要知道所有不同的指令以及它们在二进制中的表示方式。
另一方面,反编译器执行更困难的任务。它接收二进制代码或反汇编输出(基本上是相同的,因为它是一对一的),并生成高级代码。让我举个例子。假设我们有这个C函数:
int twotimes(int a) {
    return a * 2;
}

当您编译时,编译器首先为该函数生成一个汇编文件,它可能看起来像这样:
_twotimes:
    SHL EAX, 1
    RET

(第一行只是标签而不是实际指令,SHL执行左移操作,相当于快速乘以2,RET表示函数已完成)。在结果二进制中,它看起来像这样:

08 6A CF 45 37 1A

(我编造了这些,不是真正的二进制指令)。现在你知道,反汇编器将把你从二进制形式转换为汇编形式。反编译器将把你从汇编形式转换为C代码(或其他更高级别的语言)。

4
这个回答中的链接已经失效了,有没有最新的参考资料? - ProdigySim
2
@ProdigySim 1) https://web.archive.org/web/20200410182642/https://www.hex-rays.com/products/decompiler/compare_vs_disassembly/ 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 - Rain

6
解编译是编译的反向过程。就是说,它将目标代码(二进制代码)并尝试从中重建源代码。
解编译取决于在目标代码中留下的工件,这些工件可以用来确定源代码的结构。
对于C/C++而言,在解编译过程中几乎没有什么有用信息,所以很困难。但是,对于Java、C#等针对虚拟机的语言,由于语言在目标代码中留下了更多的提示信息,解编译可能会更容易一些。

2
每个人都说这很“困难” - 但它是否总是_可能的呢? - Marco Prins
4
Hexrays表示一般情况下,不总是自动可行的。需要做出编译指南的假设(例如使用了“通常”的流行编译器而不是某些奇怪的非标准化黑客实现或“邪恶”的手工汇编)。 - BullyWiiPlaza
6
反编译实质上是编译的相反过程。这是一个非常奇妙的洞察。 - theMayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接