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