在阅读其他逆向工程论坛上的一些帖子时,我了解到在 Delphi 中编译的可执行程序具有特殊的属性。我不确定这些特殊属性是什么,但我认为它以某种方式使它们更难逆向工程。有谁知道这些特殊属性是什么?
Delphi (Object Pascal) 可执行文件的特殊属性
Delphi 使用一种基于 Pascal 的面向对象语言,它在许多方面类似于逆向 C++。以下是我发现在逆向此类应用程序时需要了解的一些特定于 Delphi 的内容。
RTL(Delphi 运行时库)中的库和所需函数通常在应用程序二进制文件中静态编译。这导致具有大量函数的大型二进制文件。组件代码通常由编译器放置在可执行文件的开头,而用户代码则放置在其后。正确识别和命名库函数可以为您节省大量时间,如果使用 IDA,请确保应用适当的 FLIRT 签名(可能是最近应用程序的 bds 签名之一)。IDR也有自己的一组签名,有时可以提供其他有用的信息,如类名和反编译代码。可以将数据从 IDR 导出到 IDC 脚本并加载到 IDA 中,之后应重新应用 IDA 签名,因为 IDC 将删除一些函数名称。
RTL 在购买 Delphi 的 Embarcadero 网站上有详细记录(不要浪费时间在 Borland 网站上搜索)。
Delphi 使用 fastcall 约定,但是它与 Windows fastcall 不同。参数按以下顺序传递:EAX、EDX、ECX,堆栈上的其他参数。对于类,this 指针在 EAX 中传递。当一个构造函数被调用时,类的结构在 EAX 中传递,this 指针在 EAX 中返回。可以在调用 System::ClassCreate() 时识别构造函数。
Delphi 使用 Pascal 风格的字符串。字符串的长度在字符串的开头指定。二进制文件中存储的字符串为C风格格式,首先需要调用LStrAsg方法进行转换。要了解程序中使用字符串的位置,您需要遵循转换后的字符串,典型的调用如下所示:
mov eax, ds:off_497050 ; Pascal string
mov edx, offset a1_37 ; C-style string "1.37"
call @System@@LStrAsg$qqrpvpxv ; System::LStrAsg(void*,void*)
有许多特定于 Delphi 的“编程元素”,例如类、单元、VCL 库等。有关更多信息,您可能需要参考A Beginner's Guide to Delphi Programming。
然而,就用 Delphi 编写的逆向工程应用程序(并提取有关这些“编程元素”的信息)而言,DeDe工具是无价的。
在对 Delphi/C++ builder 目标进行逆向工程时,我总是使用 IDR 工具。一个非常有用的功能是 IDR 可以为 Ida Pro 生成地图文件。
IDR(Interactive Delphi Reconstructor)——可执行文件(EXE)和动态库(DLL)的反编译器,用Delphi编写,在Windows32环境下执行。
该程序首先面向从事防病毒软件开发的公司。它还可以帮助程序员明显地恢复丢失的程序源代码。
当前版本的程序可以处理由 Delphi2 – DelphiXE2 版本的 Delphi 编译器编译的文件(GUI 和控制台应用程序)。
最终的项目目标是开发能够从编译文件中恢复大部分初始 Delphi 源代码的程序,但 IDR 以及其他 Delphi 反编译器还不能这样做。尽管如此,IDR 处于相当有利的地位,可以促进这一过程。与其他著名的 Delphi 反编译器相比,IDR 分析的结果具有最大的完整性和可靠性。此外,交互性确实使程序舒适且(我们不会害怕这个词)令人愉快。
IDR 进行静态分析(分析的文件未加载到内存并执行),允许安全地调查病毒、特洛伊木马和其他恶意软件应用程序,这些应用程序执行是危险的或不可取的。
该程序不需要任何安装活动,也不会在 Windows 注册表中做任何记录。
下面显示了 IDR 主窗口的屏幕截图。您可以在单独的页面上找到 IDR 工作结果的示例。为了详细了解机会 IDR,有一个 CHM 格式的帮助文件,可以在下载页面或直接从这个链接下载。