该工具扫描可执行文件中的 Delphi 数据,包括 RTTI 和虚函数表。它输出一个包含已识别类和函数信息的 JSON 文件,可用于进一步分析,例如:
提供了一个可以将输出加载到 IDA 的 IDAPython 脚本。
该脚本旨在补充其他用于逆向工程 Delphi 的工具。
NCC Group Plc 以开源形式发布 - http://www.nccgroup.com/
由 David Cannings (@edeca) [email protected] 开发
http://www.github.com/nccgroup/pythia
本项目基于 AGPL 许可证发布。更多信息请参阅 LICENSE。
高级流程如下:
Delphi 的 vftable 已有详尽的文档资料。最新版本的信息可从 Embarcadero 获取。Delphi 2005 的非官方文档也可在此处查看。
Free Pascal 的源代码也很有用(Github 镜像)。
vftable 中的第一项是 vmtSelfPtr,它指向虚函数表的起始位置。该脚本扫描 PE 文件中的每个代码段,查找指向前方 +0x4C 字节的位置。请注意,Delphi 编译器会将 vftable 对齐到 4 字节边界(以进行优化)。
例如,以下 VA 0x0046E1C8 包含偏移量 0x0046E214,该偏移量比当前位置靠前 0x4C 字节。如 IDA 所示:
.text:0046E1C8 ; Classes::TComponent *vftable_TDCP_misty1
.text:0046E1C8 14 E2 46 00 vftable_TDCP_misty1 dd offset off_46E214
这种方法可能会产生误报,因此会检查 vftable 中的其他字段以确保其取值合理。例如,会检查 vmtInstanceSize 以确保其不会过大,并验证函数指针位于可执行段内。尽管采用了暴力搜索方法,但在测试期间误报率非常低。
对 vftable 中发现的每个函数,都会检查它是从父类继承的还是重载的。Delphi 不支持多重继承,因此可以通过检查父 vftable 中相同偏移处的指针来实现这一点。
如果两个指针引用相同的函数,则为继承;如果子类具有不同的指针,则为重载。
该工具的主要输出是一个 JSON 文件,可以输入到后续的处理流程/工具中。不过,它也包含了一些其他输出格式。
使用 --save-tree 选项可生成如下文件:
TObject (at 0x0040112c)
|-- Exception (at 0x004081f8)
| |-- EAbort (at 0x00408260)
| |-- EAbstractError (at 0x00408ad4)
| |-- EAssertionFailed (at 0x00408a74)
| |-- EBcdException (at 0x004bd110)
| | +-- EBcdOverflowException (at 0x004bd16c)
| |-- EBitsError (at 0x0041ab04)
| |-- EComponentError (at 0x0041abbc)
| |-- EConvertError (at 0x00408850)
| |-- EDCP_cipher (at 0x0046a0ac)
| | +-- EDCP_blockcipher (at 0x0046a29c)
| |-- EDCP_hash (at 0x00469f20)
.. etc ..
PACKAGEINFO 或 DVCLAL 资源中获取),并针对不同的 vftable 布局调整扫描方式。call [ecx+3Fh] 匹配到实例方法)TComparer<System.Bindings.EvalProtocol.TPair<System.IInterface,System.Pointer>> 这样的名称,在 IDA 中相当难以辨认。请将本工具无法处理的二进制文件示例发送给我,以便进行改进。