delphi-mcp
Recovers symbols from Delphi binaries across Delphi 2 through 13 Florence, 32/64-bit, by routing between classic, modern, and legacy analysis engines. Provides tools for version/architecture detection, full symbol analysis, class/method/field/unit/interface queries, triage, string and import behavior intelligence, DFM form-to-event mapping, xref call graph queries, rename plan generation, and export of symbols for IDA workflows.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@delphi-mcptriage sample.exe and show me the Delphi version plus sensitive imports"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
delphi-mcp
Delphi 逆向符号恢复 MCP 服务:把多个 Delphi 反编译引擎统一到一个 MCP 接口后面,为 AI agent 提供静态符号知识,并与 IDA MCP(ida-mcp)协同工作。
在真实恶意样本上验证:Delphi 2 ~ 13 Florence 全版本、32/64 位,纯 Python,零编译依赖。
想了解"做了什么、为什么能做、二进制变成了什么"——见 docs/TECHNICAL.md。 想知道"能干什么、输出长什么样、怎么用"——见 docs/USAGE.md(使用手册,含真实输出样例)。 性能演进与卡死复盘——见 docs/PERFORMANCE.md。 文件职责速查——见 docs/FILES.md。
为什么
老 Delphi 样本(尤其恶意软件)在 IDA/Ghidra 里函数名全是 sub_xxxx,分析极度依赖符号恢复。现有工具要么只有 GUI(IDR)、要么绑定特定平台(DelphiReSym 依赖 Ghidra)、要么恢复能力弱。delphi-mcp 把它们的分析能力抽取为统一的、可脚本化的、给 agent 用的服务。
Related MCP server: RE-MCP Server
特性
三引擎自动路由:按 Delphi 版本选择最合适的分析引擎,输出统一的符号模型
12 个 MCP 工具:从版本判定到符号查询、行为情报、模型生命周期、IDA 协同
纯 Python 引擎:
classic/modern两个引擎无编译依赖(仅需pefile、numpy、capstone)IDR 知识库匹配:直接解析
kb*.bin(4 万+ RTL/VCL 函数字节模式),命名虚表槽与调用目标行为情报:字符串×引用、敏感 API 指纹、DFM 表单→事件、XRef 调用图
为 agent 设计:stdout=JSON、结果按需分页、大产物落盘只回传路径、磁盘缓存
架构
delphi_detect ─── 版本 / 架构判定
│
┌─────────────────┼──────────────────┐
▼ ▼ ▼
Delphi 2..2007 Delphi 2009+ (idr-cli 强制)
classic 引擎 modern 引擎 legacy 引擎
(纯 Python) (纯 Python) (C++ 子进程)
RTTI+KB 匹配 VMT/MDT/RTTI syskb 19 步流水线
│ │ │
└─────────────────┴──────────────────┘
▼
统一符号模型 SymbolModel (JSON)
▼
query / strings / imports / forms / xrefs / renames / export
▼
ida-mcp 深挖(可选)三个引擎都产出同一套 SymbolModel(类/方法/参数/字段/单元/接口/变量),后端与 agent 无需关心用的是哪个引擎。
引擎职责
引擎 | 版本范围 | 实现 | 恢复内容 |
| Delphi 2~2007(老格式,负偏移 VMT) | 纯 Python | 类/RTTI、虚表槽(KB 命名)、动态消息方法、接口、字段、调用目标发现、单元 |
| Delphi 2009~13(新格式,正偏移 VMT) | 纯 Python(DelphiReSym 衍生) | 类/VMT/MDT、方法名+参数+返回类型、RTTI 命名空间 |
| Delphi 2~2007 | C++ | IDR 完整 19 步流水线(可选深度增强/兜底) |
安装
依赖(Python ≥ 3.11):
pip install mcp pefile numpy capstonelegacy 引擎需要 idr-cli.exe(可选,缺失时 classic 引擎仍然工作):
# 见 D:\Code\IDR\idr-cli,或设 IDR_CLI_EXEIDR 知识库(可选,启用 KB 匹配):从 IDR 安装目录取得 kb2.bin … kb2014.bin,放入 IDR_KB_DIR。
运行:
PYTHONPATH=src python -m delphi_mcp.serverMCP 工具
工具 | 作用 |
| 秒级判定版本/架构/引擎路由 |
| 全量分析 → 符号模型;按 section 分页(summary/classes/methods/units/forms/vars/full,默认 summary,避免大 JSON) |
| 查符号:类名子串 / 单地址 / 地址批量查表(pull,给 IDA 的地址回名) |
| 列出当前常驻内存的模型(类比 ida-mcp |
| 卸载该样本的缓存模型(释放内存),可选删 |
| 一键初筛:版本+规模+信号串(表驱动分类 persistence/creds_path/network/exec/mutex,去重;噪声默认隐藏)+ 敏感 API + DLL 导出 |
| 字符串(带 Delphi 头分类)+ 引用函数归因 |
| 导入表 + 行为分类(process/persist/net/crypto/evasion) |
| DFM 表单控件树 + 事件处理函数→地址 |
| 调用者/跳转者/数据读者(静态调用图查询) |
| 生成 |
| 导出 idc/lst/pas/idp |
与 IDA / ida-mcp 协同
核心资产是地址 → 符号名映射。两侧地址对齐:Delphi PE image_base 由 delphi_detect 输出(32-bit 通常 0x400000),与 ida-mcp survey_binary 的 base_address 核对即可(rebased 时用 delphi_renames(base=…))。
两种模式
批量灌入(plan):
delphi_renames(file, min_confidence="medium")→ 落盘.idc→ 在 IDA 里File > Script file执行一次。按需查表(pull,推荐):让 IDA 先看,遇到关注的地址再问 delphi——不把全量改名拉进上下文,也不会误灌低可信名。
pull 闭环(推荐流程)
1. IDA 定位 (ida-mcp) survey_binary / decompile / xrefs → 关注地址集合
2. 查表 delphi_query(file, addrs=[...]) → 每个地址的名字(含 kind/confidence)
模型未命中 → 回退 PE 导出表 (export:<name>)
3. 筛选 按 confidence 取舍 (high=MDT/RTTI, medium=KB虚表, low=调用图)
4. 出计划 delphi_renames(file, addrs=[...], min_confidence="medium")
→ 只含你选的地址:小 .idc + [{addr,name,confidence}](默认不动导出)
5. 回灌 IDA 执行小 .idc / 对 [{addr,name}] 逐条 ida_mcp_rename名字来源与可信度:high=编译器元数据(MDT/RTTI)、medium=KB 字节匹配(虚表槽)、low=调用图发现。min_confidence 只回灌高可信名;改名默认跳过 PE 导出(IDA 已命名),overwrite=true 才强制覆盖。
把改名应用到 IDA(当前无原生 batch rename)
.idc 落盘后两种落地方式:
IDA GUI:
File > Script file选该.idc(一次性;小.idc即 pull 模式产物)。ida-mcp 会话内:用
execute_python解析后set_name(用SN_NOWARN,不覆盖 IDA 已在名):
import re, ida_name
txt = open(r"...\sample.renames.idc", encoding="utf-8").read()
for a, n in re.findall(r'MakeNameEx\((0x[0-9A-Fa-f]+),\s*"(.*?)"', txt):
ida_name.set_name(int(a,16), n.replace('\\\\','\\').replace('\\"','"'), ida_name.SN_NOWARN)实测(GRenam,Delphi 2007)
delphi_renames(min_confidence="medium")→ 1522 条;IDA 应用 1510。3834 函数中 1185 个由
sub_变为真实符号;反编译uMain.TfrmMain.FormCreate可见ExtCtrls.TTimer.Create(...)。病毒自写函数无 Delphi 元数据 → 仍为
sub_:delphi 给“地图”,ida 给“地形”。
详见
docs/TECHNICAL.md§5.1。
配置
环境变量 | 默认 | 说明 |
|
| legacy 引擎二进制 |
|
|
|
| 空 | 设为 |
| 空 | 设为 |
| 空 | 设为 |
|
| 内存中常驻符号模型数上限(LRU 淘汰) |
|
| 设为 |
|
| idr-cli |
|
| 设为 |
| 空 |
|
opencode.json(stdio 本地,每会话各起一份进程):
"delphi-mcp": {
"type": "local",
"command": ["python", "-m", "delphi_mcp.server"],
"environment": { "PYTHONPATH": "D:\\Code\\IDR\\delphi-mcp\\src" },
"enabled": true
}常驻远程模式(推荐,避免“每会话一份 python”)
type: local 下 opencode 会按会话/窗口各起一份进程(多窗口 = 多份 python)。改成一个常驻服务 + remote 连接,所有会话共用一份(模型 LRU 也共享):
# 启动一次并保持运行(Windows 可用 scripts/serve-delphi-mcp.bat)
python -m delphi_mcp.serve
# 默认 127.0.0.1:8910 (SSE);可用环境变量调整:
# DELPHI_MCP_TRANSPORT=sse|streamable-http DELPHI_MCP_HOST DELPHI_MCP_PORT"delphi-mcp": { "type": "remote", "url": "http://127.0.0.1:8910/sse", "enabled": true }开机自启:用任务计划程序在登录时运行 scripts/serve-delphi-mcp.bat。SSE 与 streamable-http 两种传输都支持(后者路径为 /mcp)。
性能
实测(本机,含 KB 索引一次性构建):
样本 | 版本 | 类/方法 | 耗时 |
GRenam | 2006 | 109 / 3148 | 3.0s |
Rekram | 2006 | 144 / 3761 | 3.1s |
DanaBot | 10.2 | 300 / 973 | 3.5s |
Culebra | XE2-4 | 738 / 3864 | 4.2s |
libcef.dll | 2014 | 1854 / 12190 | 9.4s |
卡死问题与修复(开发笔记)
早期版本的 classic 引擎在较大样本(如 Culebra)上会假死(CPU 100%、长时间无输出)。根因是三处缺陷叠加:
主因:
build_anchor_index只构建单字节索引_anchor,从不构建两级索引_anchor2,且无幂等守卫——match_slot每次因_anchor2 is None触发全量 4.8 万条 KB 记录索引重建。Culebra 场景 7554 次匹配 × 4.8 万解析 ≈ 3.6 亿次操作。掩码 bug:匹配掩码用
1 << (k*8)(每字节只 1 bit)而非0xFF << (k*8),导致一级预筛恒假、虚表命名静默归零。低效扫描:类名回溯对每个类名做一次全
.textfind;索引构建用重型proc_info(解码函数名/参数)。
修复(见 prepare_matching / match_slot_fast):
单遍构建两级锚点索引 + 头 8 字节掩码 + 全长掩码,用
_proc_dump(仅解析 dump 段)替代重型解析match_slot_fast用 numpy 对候选桶做向量化头字节预筛,仅对幸存者做全长比对类名回溯改为单遍 numpy u32 扫描收集引用
IntfTable 解析延后到虚表命名之后(槽名查询命中缓存)
结果:Culebra 56s → 4.2s(13×),结果不变
注意:
cProfile对千万级 Python 调用有 10~50× 放大,用它剖析此类热点会放大"卡死"观感——用DELPHI_TRACE=1的分阶段计时更合适。
MCP 调用超时与修复(开发笔记)
早期版本首次调用 delphi_triage(或任何触发冷分析的 delphi_*)会在 MCP 客户端侧报 -32001: Request timed out。
根因:
classic引擎的 KB 匹配器(engines/kb.py的prepare_matching)懒加载numpy。FastMCP 把同步工具放到 anyio 工作线程执行、且此时事件循环已在运行——在该上下文里加载 numpy 的 C 扩展_multiarray_umath会死锁,工具永不返回,客户端超时。修复:在主线程、事件循环启动之前预加载 numpy(
delphi_mcp/__init__.py包导入时 +server.pymain()里兜底)。缺 numpy 时仍优雅降级(仅失去 KB 快速匹配)。
idr-cli 兜底耗时
classic 引擎若解析出 0 个类或抛异常,router 会在确认是 Delphi 二进制(Delphi 指纹:.itext 段 / .rsrc 的 TPF0 DFM / RTL 标记串)后,才回退到 legacy(C++ idr-cli)——这是正常兜底设计,不是 Python 瓶颈。子进程超时由 DELPHI_IDRCLI_TIMEOUT(默认 900s)限定;可用 DELPHI_IDRCLI_FALLBACK=0 完全关闭兜底。回退时 model.warnings 会带 classic parser yielded 0 classes; fell back to idr-cli (C++, X.Xs)。
非 Delphi 二进制的误报与快速返回
idr-cli 的快速版本判定对非 Delphi 二进制(MSVC/MinGW/Qt 等)可能误报 version=2。此时 detect 用 Delphi 指纹预检,若无任何 Delphi 标记则返回 engine=not-delphi、triage 直接回报 delphi:false、analyze 立即报错返回——不再触发 idr-cli 兜底(例:Qt 5.1.0 的 UninstallTool.exe 由 ~12s 降至 ~0.3s)。若样本确为加壳 Delphi(元数据被抹除),会被一并判为 not-delphi——加壳样本本就在能力边界之外。
能力边界
加壳样本需先脱壳(所有引擎相同)
字段类型名:用户自定义类型可解析,导入/外部类型为
None(typesTab 语义限制)老格式 MDT 不含参数/返回类型信息(
classic通过 KB 原型补全命中的函数)64 位:
modern引擎完整支持(符号 + RIP-relative 的字符串/导入引用归因,lea/mov/call [rip+disp32]、movabs);classic/legacy仅 32 位idr-cli 弱判定:对非 Delphi(MSVC/MinGW/Qt)可能误报
version=2。detect会做 Delphi 指纹预检,无可信标记则返回engine=not-delphi(快速返回,不跑分析)非 PE / 截断文件:
detect返回engine=not-pe,analyze给出明确错误
测试
cd tests
python smoke_all.py # 工具 × 双引擎 + MCP 协议层
python classic_test.py # 老格式语料
python verify_64bit.py # 64 位路径
python download_paper_corpus.py # 从 VT 拉取论文语料tests/regression_corpus.json 记录了回归用的本地样本、论文 hash 与拒绝模式清单。
目录结构
src/delphi_mcp/
├── server.py MCP 组装(12 工具注册)
├── router.py 版本判定 + 引擎路由
├── model.py SymbolModel 统一模型
├── shared.py 缓存 / 路径 / idc 写出
├── xref.py 统一交叉引用收集
├── intel.py 情报 API 再导出
├── strings_api.py 字符串提取 + 分类 + VA 归属
├── imports_api.py IAT 指纹 + 敏感 API 分类
├── dfm.py DFM 资源提取 + TPF0 二进制解析
├── engines/
│ ├── classic.py 老格式引擎(Delphi 2~2007)
│ ├── modern.py 新格式引擎(Delphi 2009+,DelphiReSym 衍生)
│ ├── legacy.py idr-cli 子进程封装
│ ├── kb.py IDR 知识库解析 + 匹配
│ ├── units.py 单元边界/初始化表
│ ├── pe_memory.py PE 文件内存视图
│ ├── vmt_scan.py VMT 扫描
│ ├── mdt.py MDT/方法/参数遍历
│ ├── rtti.py RTTI 对象遍历
│ └── fqn.py 模板感知 FQN 解析
└── tools/ MCP 工具模块(按域拆分)致谢
crypto2011/IDR — Interactive Delphi Reconstructor (MIT)。VMT 偏移表、FieldTable/MethodTable/DynamicTable/IntfTable 解析、单元/初始化表算法均移植自其源码。
ajsb85/idr-cli — IDR 的 VCL-free CLI 移植(知识库格式与匹配器参考)。
WenzWenzWenz/DelphiReSym — 新格式(VMT/MDT/RTTI)解析与论文《Towards Ghidra Reverse Engineering Tools for Delphi Executables》(BSD-3)。
modern引擎为其衍生作品。
License
MIT(本项目代码)。衍生组件见 LICENSE:modern 引擎为 DelphiReSym (BSD-3) 衍生作品,legacy 引擎运行时依赖 idr-cli (MIT)。
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only DERO blockchain MCP: 33 tools (12 composites) incl. TELA discovery + bundled docs.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Self-hosted MCP server: 26 deterministic dev, security, and EVM tools.
2,000+ MCP servers read at source level. Know what one does before you connect. Free, no key.
Related MCP Servers
- AlicenseAqualityCmaintenanceA multi-backend MCP server that exposes binary analysis capabilities from IDA Pro and Ghidra, allowing LLMs to directly drive reverse-engineering tools via natural language.11172Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA local, privacy-first MCP server that orchestrates Ghidra, Binary Ninja, x64dbg, and system tools to provide AI assistants with powerful binary analysis capabilities.Academic Free v1.1
- FlicenseNot gradedqualityCmaintenanceMCP server that exposes the complete Delphi 7 RTL/VCL index as tools for AI agents, enabling precise lookups for symbols, class members, unit interfaces, and source contexts to generate accurate legacy Delphi 7 code.-
- AlicenseNot gradedqualityBmaintenanceEnables AI-powered reverse engineering in IDA Pro by letting MCP clients inspect decompilation and disassembly, rename symbols, convert integers, and otherwise interact with the database through natural language.2MIT