【发布时间】:2013-09-06 21:09:14
【问题描述】:
我有一个 exe 文件,我用 Ida 反编译了它。有人告诉我程序是用 Delphi 编码的,所以我尝试用 DeDe 反编译,但失败了,没有输出也没有错误。而且我想知道是否可以通过尝试专门为编程语言编写的不同反编译器来找到用于创建 exe 的语言?或者他们会因为其他原因而失败?
【问题讨论】:
标签: programming-languages exe decompiler
我有一个 exe 文件,我用 Ida 反编译了它。有人告诉我程序是用 Delphi 编码的,所以我尝试用 DeDe 反编译,但失败了,没有输出也没有错误。而且我想知道是否可以通过尝试专门为编程语言编写的不同反编译器来找到用于创建 exe 的语言?或者他们会因为其他原因而失败?
【问题讨论】:
标签: programming-languages exe decompiler
在许多情况下,可以识别用于编译代码的编译器,并从中识别出原始语言。
大多数语言实现都包含某种运行时库来实现语言的各种高级操作。例如,C 具有实现文件 I/O 操作的 CRT(fopen、fread 等),Delphi 具有针对其 string 类型(连接、赋值等)的编译器助手,ADA 具有各种低级确保语言安全等功能。通过比较程序的代码和候选编译器的运行时库,您也许能够找到匹配项。
IDA 在FLIRT technology 中实现了这种方法。通过使用签名,IDA 能够确定大多数 DOS 和 Windows 的主要编译器。在 Linux 上要困难一些,因为它没有单一的编译器二进制提供者,因此必须为每个发行版制作签名。
但是,即使不借助运行时库代码,也可以识别所使用的编译器。许多编译器使用非常不同的习语来表示各种操作。比如我was able to guess说杜曲病毒使用的编译器是Visual C++,后来是confirmed。
【讨论】:
编译是一个有损的过程,因此通常不可能反编译可执行文件(或其他已编译的程序模块,例如.so 或.dll)并恢复原始语言的源代码,甚至明确地确定原始语言是什么。甚至不一定只有一种原始源代码语言,因为在链接之前,不同的模块可能是用不同的语言编写的。通常,您可以反汇编二进制文件并恢复汇编语言,尽管这样做的价值可能非常有限。
在许多情况下,您可以告诉一些关于原始语言的信息,前提是二进制文件没有被剥离(符号)。例如,您通常可以通过查看二进制文件中的符号来判断二进制文件是否最初是用 C++ 编写的(在 Linux 上,使用 objdump,不知道在 Windows 上可能是什么等价物): C++ 符号以一种特殊的方式被破坏。这不是 100% 的保证,但可能性很大。
也就是说,一些反编译器在完成一项非常困难的任务时做得相当合理。从二进制文件中推断出可能的高级构造并不容易。在我(非常有限的)经验中,它们往往适用于相当琐碎的程序或使用原始编译器的一小部分版本编译的软件,但对任何实质性的东西都感到窒息:反编译器的作者很难跟上编译器的变化,她这样做的动力可能很小。
即使在反编译非常成功的情况下,结果也基本上是完全没有注释的代码,带有非常难以理解的无意义变量名。反编译是一回事,从结果中提取预期的语义是另一回事。请记住,许多变量、分支、循环和函数将被完全优化掉,许多函数将被内联等等。所以“源代码”,即使你可以通过这种方式获得它,也可能不是很多对你有用。
【讨论】:
objdump。它们安装在 binutils 包中。