
简介DELPHI反编译工具是一款面向DELPHI开发者、逆向工程人员和安全分析师的实用型逆向分析软件专门用于解析DELPHI编译生成的DLL与OCX等二进制组件解决缺少源代码时难以理解、维护和调试遗留系统的问题。压缩包采用RAR格式整体大小约532KB便于快速获取使用上游未提供文件总数与文件类型明细故不再罗列内部结构。目前已有1000人学习/下载在DELPHI逆向相关场景中具有一定参考价值。工具围绕反编译核心流程提供符号解析、反汇编、源码重构和调试支持可将机器码还原为接近Pascal原语形态的函数与类结构帮助开发者识别组件内部逻辑。实际使用中可用于老项目代码维护、分析他人编程思路、排查旧版编译组件在新环境中的兼容性问题以及配合调试器开展安全验证同时需注意反编译结果无法完全恢复原始注释与设计结构且操作时应尊重知识产权并遵守法律法规。 干这行久了你会发现同样是 Windows 下的 PE 文件有的反编译起来让人想砸电脑有的却像拆乐高一样顺畅。DELPHI 编译出来的程序就属于后者——不是因为 Delphi 开发者水平不行而是 Delphi 编译器本身在 PE 文件里留下了太多“脚印”。RTTI、DFM 资源、VCL 类名……这些东西让反编译从“猜谜”变成了“拼图”。这篇东西就专门聊 DELPHI 反编译工具从原理到实操从老版本 D7 到新版本 11/12 怎么处理一次讲清楚。适合刚接触逆向、或者做了几年汇编逆向但没碰过 Delphi 程序的朋友。1. DELPHI 程序的“基因特征”为什么是逆向者的福利1.1 RTTI编译器白送的类型与类名信息Delphi 默认开启了 RTTIRun-Time Type Information这意味着每一个类、每一个 published 属性、每一个方法名都会以字符串形式留在可执行文件里。你用 IDA 打开一个 C 语言写的 exe看到的是一堆sub_401000这种无名函数但打开 Delphi 写的 exe满屏都是TForm1.btnLoginClick这种带完整类名和方法名的函数名。这不是巧合。Delphi 的 RTTI 机制最初是为了支持 IDE 的“对象检视器”和流式加载 DFM 窗体编译器必须把 published 方法的地址和名字绑定在一起程序运行时才能通过字符串找到方法。这个设计给反编译器开了后门只要解析 RTTI 数据就能拿到一份“类名→方法名→方法地址”的映射表。我还记得几年前帮朋友分析一个老的 Delphi 7 程序IDR 跑完一遍直接列出了 200 多个方法名连按钮点击事件、定时器事件都分得清清楚楚。这种体验在 VC 程序上想都不敢想。RTTI 就是白送的地图关键是你得知道怎么用。1.2 DFM 资源图形化界面相当于半成品源码Delphi 程序的第二个特征是窗体文件DFM作为资源编译进 exe。在资源段里能找到TForm1对应的窗体定义里面包含了每个控件的类型、名称、位置、尺寸、属性值。这意味着什么意味着即使没有源码你也能把界面 100% 还原出来甚至可以直接在 Delphi IDE 里打开这个还原出来的窗体。原理在于 Delphi 的窗体持久化机制设计期你在 IDE 上拖一个 Button改一下 Caption保存时这些属性会被序列化到 DFM 文件里编译时 DFM 又被当成 RCDATA 资源塞进 exe。运行时主窗体创建时会去读这些资源把控件一块块 new 出来。所以 DFM 本身就是“半源码”反编译工具只需要把这个资源提取出来再转换回文本格式。对做逆向的人来说这是巨大的信息泄露。通过对 DFM 的分析你能知道程序里有哪些窗口、哪些按钮、哪些输入框甚至能看到默认的 SQL 语句、API 地址、数据库连接串。很多时候根本不用看汇编代码光看 DFM 就能把业务逻辑猜个七七八八。1.3 版本变化D7 的黄金时代与 XE 后的复杂性为什么网上流传的 DELPHI 反编译教程一半以上都在讲 Delphi 7因为 D7 是 2002 年的版本当时 RTTI 结构简单稳定VCL 源码流传广IDR 这类工具对它的解析最完善。而到了 Delphi 2009也就是 Unicode 版之后字符串从 ANSI 变成了 UTF-16RTTI 结构也调整过Delphi 2010 引入了增强 RTTIExtended RTTI主要是为了支持TVirtualMethodInterceptor这个改动把一部分类信息从传统的 VMTVirtual Method Table区域拆了出去。到了 Delphi 10.3、11、12 这些新版本编译器又加入了更多元数据部分代码段还默认做了优化函数之间不再有明显的 RTTI 锚点。结果就是老工具 IDR 对 XE8 之后的程序支持越来越差要么识别不出单元名要么窗体列表是空的。但这不代表新版本 Delphi 程序就无法逆向只是需要换工具组合和思路。2. 工具链选型老工具与新工具怎么搭配2.1 IDR中文社区用得最熟的“一键反编译”IDR 全称 Interactive Delphi Reconstructor是由俄罗斯开发者维护的免费工具。它最大的价值是把“识别 RTTI 解析 DFM 生成 Map 文件 标记事件入口”这一整套流程自动化了。你打开一个 Delphi 写的 exe点一下 Start它就能输出一份带有单元名、方法名、类名的分析报告。IDR 能解析的东西包括代码段里的方法起始地址、类继承关系、published 属性名、DFM 窗体资源、字符串引用、单元初始化列表。生成的结果可以导出为 MAP 文件再配合 IDA/Ghidra 加载 MAP 文件就能把函数名同步到反汇编窗口里。但 IDR 有个明显的软肋它的最后一次正式更新停留在 Delphi XE7 前后对 Unicode 版本的支持并不完美。用它能跑老版本 Delphi 程序几乎是指哪打哪但遇到高版本程序就捉襟见肘了。2.2 DeDe老一辈逆向工程师的回忆DeDe 是我刚入行时用的工具说实话它比 IDR 更简陋界面停留在 Win9x 时代最后一次发布好像是 2003 年左右。但 DeDe 有一个独门技能对 Delphi 7 及更早版本的函数签名提取有些情况下比 IDR 还细尤其是在还原事件处理函数event handler的入口表时DeDe 给出的结果一度比 IDR 更完整。不过现在再让新手去装 DeDe 就有点不现实了它在 Win10/Win11 上经常闪退右键菜单也要手动注册。我的建议是如果你想研究老物件的逆向原理可以翻一翻 DeDe 的源码但日常干活还是优先 IDR。工具这东西能用顺手的就是最好的没必要追求考古。2.3 Ghidra 针对 Delphi 的脚本Ghidra 是 NSA 开源的逆向框架它对 Delphi 的支持虽然没有原生的一键按钮但胜在可扩展。社区里有现成的 Delphi 脚本能识别System.pas、Classes.pas等 VCL 单元签名把常见的 RTL 函数自动标注出来。我个人的经验是Ghidra 适合做高版本 Delphi 程序的深度逆向尤其是遇到 IDR 解析不了的 XE8 程序。流程是先用 DIEDetect It Easy确认编译器版本再用 Ghidra 的自动分析跑一遍接着手动定位 RTTI 区把类名和方法名标上去。虽然效率比 IDR 低但至少能往前推进不至于卡死。2.4 识别与辅助工具PEiD、DIE、Resource Hacker反编译之前先要确认这个 exe 究竟是不是 Delphi 写的、有没有加壳、是哪个版本。PEiD 是老牌工具通过特征字符串能识别“Borland Delphi 6.0 - 7.0”之类的标记但 PEiD 已经停更对新版本 Delphi 的识别经常失效。DIE 是更好的替代它把 Delphi 版本识别做到了更细还能提示是否加壳识别哪个壳。Resource Hacker 主要用于手动提取和修改资源。对 Delphi 程序来说如果反编译工具没能正确还原窗体你还可以用 Resource Hacker 把 RCDATA 类型的 DFM 资源导出来再用专门的 DFM 转换脚本转成文本人工阅读。工具搭配的思路很简单DIE 判断身份IDR 处理老版本Ghidra 处理新版本Resource Hacker 做补充提取。下面这张表是我平时用的组合速查可以直接存起来参考。使用场景首选工具备选方案注意事项批量还原 Delphi 2~7 程序IDRDeDeIDR 导出 MAP 再配合 IDA 使用Delphi 2009~XE8 程序IDR部分支持Ghidra注意字符串是 Unicode查找时用 UTF-16Delphi 10.3 程序GhidraIDA Pro重点靠 RTTI 定位别指望自动还原识别是否有壳DIEPEiD看到压缩壳先脱壳再分析提取/修改 DFM 资源Resource Hacker010 Editor导出后注意 DFM 的版本头格式3. 实操流程把一个 Delphi EXE 拆到可读3.1 确认程序确实是 Delphi 编译的拿到一个未知 exe不急着上重武器先用 DIE 扫一下。打开 DIE拖入 exe几秒钟后就能看到编译器的识别结果通常显示为 “Borland Delphi” 或 “Embarcadero Delphi”后面跟版本号。如果 DIE 显示版本是 “Delphi 7” 或者 “Delphi 6”就直接上 IDR如果显示 “Delphi 11/12” 这种高版本那就走 Ghidra 路线。还有一种情况是 DIE 什么都识别不出来但零散字符串里能看到 “Borland”“System.pas” 这类关键字多半是程序加壳或者被处理过先脱壳再判断。判断方法还有一个隐蔽技巧Delphi 程序的入口点附近会有大量push; push; call连续调用而且代码段里能看到System这种符号名这是 Delphi RTL 的典型特征。IDA 里扫一眼导入表如果出现GetModuleHandleA、GetProcAddress、LoadLibraryA这三个组合配合 RTTI 字符串基本也能确定是 Delphi 系程序。3.2 IDR 整体扫描拿到 Unit 表、窗体列表、事件入口以 Delphi 7 程序为例打开 IDR点 File-Open 选择目标 exe然后点工具栏上的 Start 按钮。IDR 会花十几秒扫描代码段最后生成一个树形结构按类名、单元名、窗体名、方法名分类展示。如果 IDR 提示“Out of memory”或者直接闪退可以把 exe 先拷到内存比较充裕的机器上或者关闭杀毒软件的实时防护。对付老版本 Delphi 程序IDR 的稳定性还是可以的。扫描完成后你要先看三个地方Unit 列表这里列出了所有编译进 exe 的单元名从System.pas到MainUnit.pas都有。这是还原项目结构的第一手资料。窗体列表每个窗体对应一个 DFM 资源接口名称也是源码里的窗体类名。事件方法列表比如TForm1.Button1Click点一下就能跳到对应的汇编地址。我建议你把 IDR 生成的 MAP 文件导出然后在 IDA 里加载这个 MAP 文件这样 IDA 的函数名就能自动同步成 Delphi 的原始名字。这个操作能省下 80% 的命名时间。3.3 还原 DFM 窗体布局与控件属性IDR 左侧树形结构里双击窗体名称会弹出该窗体的 DFM 预览窗口显示控件树。默认是二进制显示模式点窗口里的 “DFM → Text” 切换按钮就能看到文本格式的窗体定义比如object Form1: TForm1 Left 192 Top 125 Width 500 Height 350 Caption Login Form object ButtonLogin: TButton Left 200 Top 180 Width 90 Height 25 Caption Login OnClick ButtonLoginClick end end看到OnClick ButtonLoginClick这种字段了吗它直接告诉你这个按钮被哪个方法处理而这个方法的入口地址 IDR 已经帮你标出来了。接下来你在反汇编代码里跳到ButtonLoginClick对应的地址就能跟踪具体的登录逻辑。如果你的目标是复刻界面更简单的办法是把 DFM 文本保存为.dfm文件然后在 Delphi IDE 里新建一个空白窗体右键选择View as Text把内容粘贴进去再切回窗体视图整个界面就原样回来了。这个操作对理解对方业务结构特别直观。3.4 核心逻辑还原从汇编到伪代码的思路拿到方法地址之后具体逻辑还是要靠反汇编。IDR 本身有内置反汇编器但可读性一般我的习惯是复制方法地址到 IDA / Ghidra 里看那里有伪代码功能。在 IDA 里跳到事件方法地址按 F5 生成伪代码你会看到类似这样的东西void __fastcall TForm1::ButtonLoginClick(TForm1 *this) { UnicodeString input_user this-EditUser-Text; UnicodeString input_pass this-EditPass-Text; if ( (unsigned __int8)check_user(input_user, input_pass) ) show_message(LLogin OK); else show_message(LLogin Failed); }注意这里check_user是自定义函数IDR 不会帮你命名你只能根据它的调用参数和返回值猜测功能。但如果程序调用了 VCL 的函数比如TStringList-LoadFromFile、TFDQuery-SQL-Text因为这些 VCL 函数名在 RTTI 和导入表里有迹可循烦人的命名工作能少不少。我的经验是逐行翻译汇编是最傻的做法。更高效的路径是先把 RTTI 给出的事件方法全部标出来再看哪个事件方法里调用了自定义函数最后顺着调用关系一层层往上扒。先画出“函数调用树”再去读懂每一个叶子节点能少走一半弯路。4. 特殊场景加壳、BPL 动态库、高版本 Delphi4.1 先脱壳再反编译UPX 与 VMP 类壳Delphi 程序很常见被 UPX 压缩壳保护因为 UPX 对小体积的 Delphi 程序压缩效果明显且能挡住对新手的直接反编译。如果 IDR 打开提示格式错误先查壳。UPX 脱壳很简单下载命令行版 UPX执行upx -d target.exe通常几秒就能还原原始入口点。脱壳后的 exe 再用 IDR 跑一遍效果和没加壳一样。但如果遇到 Themida、VMProtect 这类加密壳情况就复杂了。这类壳会把代码虚拟化RTTI 表也被加密IDR 直接报废。我的建议是别硬刚脱壳优先尝试在内存中 dump 进程等壳程序运行起来、窗口显示之后用 OllyDbg/x64dbg 附加到进程在内存里找到原始代码段并 dump 出来。这个技巧对 Delphi 程序效果出奇的好因为 VCL 程序在运行期再怎么加壳RTTI 数据在内存里终究是要解密的dump 就能拿到结果。4.2 动态链接 BPL 包的反编译思路BPLBorland Package Library相当于 Delphi 的 DLL模块化设计时用得很频繁。主 exe 可能只有几 KB真正的业务逻辑全在 BPL 里。遇到这种情况不要光盯着 exe 反编译BPL 本身就是 PE 文件同样可以用 IDR 打开。一个典型场景是主程序启动时动态加载Runtime.bpl然后在运行时创建某个窗体类这个类的完整定义在 BPL 里。你在主程序的 RTTI 里只能看到类和方法的引用名但具体实现要进到 BPL 里才看得到。所以遇到带 BPL 的项目把主程序和依赖的所有 BPL 都丢进 IDR分别分析然后把方法调用关系串起来。注意 BPL 的单元名很可能被裁剪过比如只保留了System、Classes这种短名这是因为 Delphi 的包机制允许隐藏对外可见的类。另外一种做法是用 IDA 打开主程序导入表里能看到对 BPL 导出的引用顺着这些引用可以定位关键 API再去 BPL 里找对应的导出函数。4.3 Delphi 11/12/13 程序该怎么办新版 Delphi 程序的反编译基本是 Ghidra 的主场。你在 Ghidra 里加载 exe 后自动分析跑完可以看到FUN_00401000这种匿名函数。关键步骤是手动定位 RTTI打开 Ghidra 的字符串窗口搜索.pas结尾的字符串比如System.pas、Vcl.Controls.pas。找到这些文件名之后往上翻找引用它的位置通常在 RTTI 结构附近。顺着 RTTI 结构解析出类名和 published 方法列表。在函数列表里找到对应方法地址打上标签。还有一个更省力的捷径新版 Delphi 的异常处理块里经常带有存储过程名因为编译器可能会把源码文件名和行号写进调试信息里。在 Ghidra 里搜索.dpr或.pas你会得到一份意外惊喜。如果程序开发者错误地发布了包含调试信息的版本那反编译的难度会直接下降一个数量级。5. 常见问题排查与避坑速查5.1 IDR 提示“无效的授权说明”这其实是 IDR 的一个 bug多见于操作系统区域设置不是英语或俄语的机器上。解决办法是在 Windows 的“区域设置”里把非 Unicode 程序的语言临时改成英语然后重新打开 IDR。如果还不行就直接从命令行启动或者用特权兼容模式运行。多年前我在这上面卡过一下午最后发现纯粹是编码问题纯属浪费时间。5.2 还原出的窗体中文乱码Delphi 7 及以前的程序DFM 里存的是 ANSI 字符串如果你用文本模式打开 DFM中文字符会乱码。这时候别惊慌用 Delphi 7 的 IDE 打开 DFM以文本方式粘贴然后保存为二进制再重新转文本。或者更简单用Iconv把 DFM 文本从GB2312转成UTF-8再打开问题就解决了。到了 Delphi 2009 之后的程序字符串用 UTF-16 存储乱码反而少见只要工具正确识别了 Unicode 标志就行。5.3 方法列表不完整怎么办IDR 对 Delphi 7 程序的识别基本覆盖全部 published 方法但偶尔会漏掉部分动态创建的方法尤其是运行时用Create创建的对象实例方法不注册到 RTTI 中。这种情况你可以在 Ghidra 中定位该对象的 VMT通过虚方法表查找方法地址。搜索唯一字符串比如某个消息文本然后 Xref 查找引用它的代码地址。这个方法对任何 Delphi 版本都适用字符串引用往往比 RTTI 还能揭示真实的业务逻辑。5.4 与“运行 DOS 命令”“线程”相关代码的识别在做 Delphi 程序逆向时经常遇到两种功能需要特别关注一是调用外部命令二是多线程操作。进程相关代码通常能搜到CreateProcessW、ShellExecuteW、WinExec等导入函数而线程相关功能则需要找BeginThread或CreateThread。不过还有个更 Delphi 的特征进程外执行可能封装在TProcess或TShellExecute类里线程则可能使用TThread派生类RTTI里能看到类的名字。如果你想从可执行文件里看出它是用匿名线程还是TThread一般看Execute方法是否存在。如果能看到TThread.CreateAnonymousThread的调用说明用了匿名线程看到TMyThread.Execute这个方法名就是继承了TThread的重写实现。6. 关于反编译边界的一点个人看法反编译工具作为一种分析手段本身没有善恶属性。做安全研究、做兼容性调试、给老项目找历史逻辑这些都是正常用途。比如我以前接手过一个没人能维护的老 Delphi 项目甲方连源码都丢了只有生产环境的 exe我们就是用 IDR 把核心模块逆向出来重新整理成可维护的代码这件事对我个人来说是救项目不是侵权。但不能否认反编译也可能被用来破解商业软件、窃取别人代码。所以我的态度是你用来学习、用来分析自己拥有授权的程序随便折腾但如果你打算拿别人的成果去牟利或者搞破坏那就等着收律师函吧。技术是无罪的人得给自己划红线。另外也想给新人一句实在话DELPHI 反编译工具的成熟度虽然比很多语言高但“还原源码”和“还原逻辑”是两回事。IDR 给到你的是一张地图真正的分析还是要靠汇编功底、对 VCL 框架的熟悉以及足够的耐心。工具只是起点不是终点。本文还有配套的精品资源点击获取