Delphi程序逆向反汇编技巧小记
0x00 Delphi语言基础
1.Delphi语言概述
Delphi本身并非一种独立的语言,而是一种软件开发工具,是Object Pascal语言的一种开发工具。本身是大名鼎鼎的Borland公司开发的一种开发环境,包含IDE、图形界面库Visual Component Library(VCL)及数据库相关功能。其图像界面库VCL类似MFC,使用PME(Property/Method/Event)的开发模式。
VCL采用特有的RCDATA资源格式,RCDATA中包含有Delphi窗口(Forms)信息,当程序运行时通过初始化代码建立窗口,从RCDATA中获取所需要的信息。RCDATA信息可以通过PE Explorer等PE编辑器查看。

Delphi版本较多,不同版本有一些差异,目前已经发布的版本包括1-7, 2005, 2006, 2007, 2009, 2010, XE-XE8、10、10.1、10.2、10.3。Delphi的API查询可以通过参考链接2进行查询。
### 2.Delphi二进制特点
可以通过exeinfo/Detect It Easy等工具判断PE文件是否为Delphi开发及确定具体的Delphi版本信息,确定具体的版本信息有助于后续反汇编工具的设置,使工具反汇编出可读性更高的汇编代码。
Delphi常用的字符串的内存布局不同于C/C++的char*或则string对象,Delphi使用的字符串都是Pascal的字符串,在原始字符串前面存放的是字符串的长度
1 | uint32_t len; |

Delphi遵循_fastcall调用约定,但是与Windows的_fastcall略有不同,参数顺序为eax为第一个参数、edx为第二个参数、ecx为第三个参数,大于3个的参数通过堆栈传递,大于三个的堆栈顺序从左到右依次压栈,堆栈由被调用者恢复。1
2
3
4
5
6
7Add(1,2,3,4,5);
00451F91 6A04 push $04
00451F93 6A05 push $05
00451F95 B903000000 mov ecx, $00000003
00451F9A BA02000000 mov edx, $00000002
00451F9F B801000000 mov eax, $00000001
00451FA4 E8C7FFFFFF call 00451F70
Delphi的按钮事件地址是通过按钮名字和地址绑定的,具体为一个按钮名称对应一个按钮事件响应函数地址。而按钮名称可以在Delphi的RCDATA资源中找到,具体为通过PE Explorer打开资源RC数据,找到相应界面的Form,找到按钮名称的字符串值。

这里为”Button1Click”,然后再IDA或则16进制编辑器中搜索该字符串,应该可以找到两个Button1Click字符串。其中一个是资源本身,另一个是事件地址和事件响应函数地址表,其中上面是地址下面是名称,Button1Click的地址表如下:

0x01 反汇编Delphi如何设置IDA pro
在使用ida进行反汇编时,大多数情况我们都会使用ida默认设置进行的反编译,在具体到某个函数时会对反汇编的字符串、语言、函数调用约定等进行一些小的调整。对一般程序这种设置反汇编效果都还不错,但是对Delphi程序这样反汇编出来的代码可读性很差,具体表现是函数的调用约定可能识别错误,字符串信息也不能自动识别。这时我们可以通过手动设置ida的反汇编选项对反汇编效果进行调节,具体如下:
- Load a new file,取消勾选的Analysis下的两个自动分析选项
- Options–>Compiler:Compiler(Delphi)、Calling convention(FastCall)
- Options–>General–>String:Default string literal type(Pascal/Pascal16)
- View–>View–>Open Subviews–>Type libraries, remove the defaults
- View–>Open Subviews–>Signatures–>Apply new Signatures:选择delphi相关Signatures
- Edit–>Select all,在IDA View区域右键Analyze selected area
经过这样一番设置后,IDA反汇编出来的效果比默认设置会好很多,但是IDA毕竟是一个通用反汇编工具,对Delphi程序的效果只能说差强人意,对delphi的一些库函数识别有限,并且对RCDATA的资源也未做特定解析,但是好在有另外一个神器,能大大优化IDA的不足,它就是IDR。
0x02 Delphi反汇编大杀器IDR

IDR全称为Interactive Delphi Reconstructor,从名字上我们就可以知道这是一款专门针对Delphi的反汇编工具,工具下载地址可以参考参考链接3、4,主要模块包括:
- Idr.exe,IDR主功能模块
- dis.dll 反汇编模块
- *.bin 类似IDA的sig文件,用于识别Delphi的库函数
IDR相对于IDA的优势如下:
- 得益于多个版本的符号bin文件,IDR能够识别大部分Delphi库函数,比IDA的识别率高很多
- 默认设置直接解析delphi程序的字符串信息,在IDR Strings可以查看和搜索这些字符串
- 可视化查看delphi的RCDATA信息Form界面信息,并且能够直接获得按钮等元素的响应函数地址
- ClassViewer窗口可直接查看部分类及函数名称,猜测这部分函数为RCDATA中声明的函数或则类似C++的RTTI信息
虽然IDR针对Delphi程序的反汇编有这么多优势,但是相对于IDA还是缺少一些反汇编的高级功能,如图形化展示反汇编函数图、F5功能等。但好在IDR提供了导出功能,可以导出map、idc文件供IDA使用,这样就可以结合两个工具的优势分析Delphi程序,这样简直得心应手啊。
0x03 简单总结
当分析一种新的语言或则类库开发的程序的时候,还是可以通过搜索或则询问学习一些该语言的基础知识,如字符串内存布局、默认调用约定等,这样在逆向分析时候可以大大增加我们的效率,减少体力活。
同时在学习到一些基础知识后,我们也能更好的使用所用的工具,不要迷信自动分析,必要时通过手动设置一些选项也能大大增加我们逆向分析的效率。
0x04 参考链接
1.Delphi维基百科
2.Delphi语言的MSDN
3.IDR github
4.IDR下载地址
5.Reverse engineering Delphi executables?
6.which-ida-pro-signature-should-be-used-for-borland-delphi-6-0-7-0-binaries-as-re