12

那么反编译器真的是一个提供编译/解释代码的来源的东西吗?因为对我来说这听起来不可能。如果已编译,您将如何获得函数、变量、类等的名称。还是我误解了定义?它是如何工作的?制作一个背后的一般原则是什么?

4

4 回答 4

12

您对反编译器的定义是正确的:它需要一个已编译的应用程序并生成匹配的源代码。然而,在大多数情况下,它并不知道变量/函数/类的名称和结构——它只是猜测。它分析程序的流程并尝试找到一种方法来通过某种编程语言(通常是 C)来表示该流程。但是,因为选择的编程语言(在本例中为 C)通常处于比状态更高的级别对于底层程序(二进制可执行文件),程序的某些部分可能无法准确表示;在这种情况下,反编译器会失败,您需要使用反汇编器。这就是为什么许多人喜欢混淆他们的代码:它使反编译器更难打开它。

构建反编译器并不是一项简单的任务。基本上,您必须将要反编译的应用程序(无论是可执行文件还是其他形式的已编译应用程序)解析为可以在内存中使用的某种树。然后,您将分析程序的流程并尝试找到可能表明if在代码中的某个位置使用了语句/变量/函数/等的模式。这实际上只是一个猜谜游戏:您必须知道编译器在编译代码中生成的模式,然后搜索这些模式并用等效的人类可读源代码替换它们。

这对于像 Java 或 .NET 这样的高级程序来说要简单得多,在这些程序中,您不必处理汇编指令,而变量之类的事情主要由您处理。在那里,您不必猜测,只需直接翻译即可。您可能没有确切的变量/方法名称,但您至少可以相当容易地推断出程序结构。

免责声明:我从未编写过反编译器,因此不知道我在说什么的每一个细节。如果你真的对编写反编译器感兴趣,你应该买一本关于这个主题的书。

于 2010-05-25T04:50:17.927 回答
1

反编译器基本上会获取机器代码并将其恢复为格式化的语言。如果我没记错的话,我认为反编译器需要知道它是用什么语言编译的,否则它将无法工作。

反编译器的基本目的是回到你的源代码;例如,有一次我的 Java 文件损坏了,我唯一能将它恢复的方法就是使用反编译器(因为类文件没有损坏)。

于 2010-05-25T04:52:50.660 回答
1

它通过推断目标代码中内容的“合理”(基于一些启发式)表示来工作。它产生的内容与最初存在的内容之间的相似程度往往在很大程度上取决于它开始的二进制文件中包含多少信息。如果您从基本上“纯”二进制文件开始,它通常只会为变量编造“合理”的名称,例如使用诸如i,jkfor 循环索引之类的东西,而对于大多数其他变量则使用更长的名称。

另一方面,支持自省的语言需要将更多关于变量名、类型等的信息嵌入到可执行文件中。在这种情况下,反编译可以产生更接近原始的东西,例如通常保留函数、变量等的原始名称。在这种情况下,反编译器通常可以产生与原始非常相似的东西——可能会丢失只不过是格式化和注释而已。

于 2010-05-25T04:56:53.037 回答
0

这取决于您要反编译的语言。如果您要反编译 C 或 C++ 之类的东西,那么提供给您的唯一信息是函数名称和参数(在 DLL 中)。如果你在处理java,那么编译器通常会插入行号、变量名、字段和方法名等等。如果没有变量名,那么您会得到类似localInt1, localInt2,的名称localException1。或者无论编译器是什么。由于行号,它可以分辨行之间的间距。

于 2012-07-30T13:19:05.373 回答