Parallel IDA Pro 二进制分析结合 AI 驱动的函数命名、Neo4j 知识图谱以及 phantomrt 仿真/挂钩/模糊测试引擎,用于跨 PE、ELF 和 NSO 格式的自动化逆向工程。
幽灵般穿梭于二进制文件之间。
一款本地化的、AI赋能的反逆向工程助手:并行的IDA Pro分析、AI函数命名、一款不再难用的终端、一个Neo4j知识图谱,记录它曾推断出的所有信息,以及一个MCP服务器,让Claude能够直接搜索并串联该图谱。
而现在——借助 phantomrt ——它不再只是阅读墙壁。它穿墙而过:模拟、挂钩并模糊测试它所命名的函数,并将实际发生的情况写回图谱。
✓ 00 ✓ 01 ✓ 02 ✓ 03 ▸ 04 · 05 · 06 · 07 ✓ 08 ✓ 09 ✓ 10 ✓ 11 ✓ 12 ✓ 13 ▸ 14 · 15
14/16 shards │ 141,203 functions found ████████████████████████████░░░░ 89% ~4s remaining
---
## 它是什么
IDA Pro的自动分析是单线程的。对于一个34 MB的il2cpp DLL,这需要*几分钟*。spectrIDA将二进制文件分割成N个分片,通过idalib并行运行,合并成一个`.i64`文件,然后让一个微调的8B模型**为每个函数命名**——所有这些都来自一个终端用户界面,具有赛博朋克主题和恰到好处的讽刺感。
这就是第1章,它独立存在:纯粹的速度,如果你不想要,就不需要AI。
第2章将输出转化为超越会话生命周期的东西——一个Neo4j图,MCP客户端(Claude、[pi](https://pi.dev)或任何支持MCP的工具)可以真正在其中工作,而不是你一次一个函数地将反编译输出复制粘贴到聊天窗口中:```
Binary ─▶ Parallel IDA Analysis ─▶ Demangle ─▶ AI Naming ─▶ Neo4j Graph ─▶ MCP Server ─▶ Claude
(N idalib shards) (free, real) (stripped (persists, (search/chain/
leftovers forever, rename, live)
only) across sessions)
第3章(phantomrt)添加了静态工具从未拥有的另一半:它实际运行代码。模拟一个没有操作系统的函数(适用于你甚至无法启动的二进制文件,例如Switch的.nso),或者挂钩到实时进程,或对其进行模糊测试——并将判断结果(crashes / needs live state / clean)标记到与函数名称相同的图节点上。
它不是Ghidra。它能快速完成一件烦人的事(慢速分析+命名),而且使用起来确实很有趣。199次下载说明一切。
无云端。无遥测。完全在你的机器上运行。
| 任务 | 时间 |
|---|---|
| Among Us DLL — 单线程IDA | ~4 hours |
| Among Us DLL — spectrIDA(16个工作线程) | 67 seconds |
| 153,649函数二进制文件 — 完整命名过程 | overnight |
| 二进制文件概览(这个程序是干什么的?) | ~30 seconds |
测量所用硬件: AMD Ryzen 7 5800X3D(8核/16线程),32 GB RAM,RTX 4070 12 GB。不同的硬件会影响并行分析数据(更多核心、更多分片,更快);命名数据主要受GPU限制。Among Us的4小时/67秒数据是在第2章之前测得的,并非每次发布都独立重新验证——如果你想针对自己的机器和二进制文件获取数据,请自行运行spectrida analyze,结果会因分片密度和二进制文件大小而异。
实际上在第2章开发期间重新验证的数据,相同硬件:
| 二进制文件 | 函数数 | 任务 | 时间 / 结果 |
|---|---|---|---|
| test_small.dll (PE) | 189 | 并行分析,4个工作线程,CLI | 6.4s |
| test_small.dll (PE) | 164 | 完整MCP流水线(分析 + 反混淆 + 图写入) | 9.8s |
| main.nso — Mario Odyssey (NSO), 16 workers | 28,038 种子函数 | 并行分片扫描阶段 | 54.5s |
| main.nso — Mario Odyssey (NSO), 16 workers | 74,790 总函数数 | + 合并/完整分析阶段 | 143.1s |
| main.nso — Mario Odyssey (NSO), 16 workers | 74,790 总函数数 | 端到端实际时间 | 197.6s |
| main.nso — Mario Odyssey (NSO) | 74,790 | 仅通过反混淆解析(Itanium ABI,免费,无AI) | 67,300 (90.0%) |
那一行NSO数据实际上相当于之前Among Us的“4小时→67秒”说法,在本版本中基于一个74,790函数的Switch二进制文件重新测量,未涉及AI命名(仅反混淆——populate=False)。并行阶段(16核,~55秒)进行初始分片发现;合并阶段(~143秒)设计为单线程——一个IDA数据库,一个写入器——所以如果你在该阶段查看任务管理器,看到15个核心在休眠,那不是bug报告,那是物理限制。
获取一个真实的数字本身就是一出小恐怖故事。第一个版本的NSO支持运行正常,退出代码0,但骄傲地返回了727个函数,而该二进制文件大约有75,000个函数——不是崩溃,只是惊人地、自信地错误,这某种程度上更糟糕。结果发现IDA没有原生NSO加载器,因此文件静默地作为纯x86("metapc")加载,尽管Switch自发布以来就是ARM64架构。每个分片都对着纯AArch64指令运行x86序言扫描器,并将意外匹配到的任何内容称为"函数"。单独修复架构毫无作用,因为该二进制文件在内存中仍然是LZ4压缩的——所以扫描的内容中有一半,客气地说,是噪声。即使正确解压并标记为AArch64,每个分片也只在其小小的二进制切片内寻找调用目标,遗漏了所有跨越分片边界的调用——在这种大小的二进制文件中,大部分调用都是跨边界的。三个bug,一个数字,而且没有一个有抛出异常的体面。(我们还尝试通过跳过IDA的栈帧分析来缩减合并阶段——获得了漂亮的加速,但数据库导致Hex-Rays礼貌地拒绝反编译一半内容。那很快就被回退了。保留了更小、更安全的FLIRT签名跳过,这带来了约3%的微不足道的改进,且没有破坏任何东西,到这一步感觉这已经是一个值得保留的性格特征。)
关于命名准确性: 它并非Ghidra级别的真实答案,而是一个8B模型根据伪代码进行猜测。通用的辅助函数/获取器通常效果不错;深度游戏特定的逻辑则更像抛硬币。对任何错误结果进行重命名——这就是为什么rename_function会直接持久化回图中。
.i64。可通过标志、配置或环境变量配置工作线程数。.so/Linux)支持;添加新格式只需一个文件,无需更改核心。spectrida formats列出已注册的格式。参见添加新的二进制格式。N。看它思考。名称出现。B对列表中所有sub_*函数进行命名。离开。回来。O或运行spectrida overview file.i64。模型读取120个采样函数名称,告诉你该二进制文件的功能、子系统以及与安全相关的内容。30秒内正确识别了一个153k函数的IL2CPP运行时。C显示调用者和被调用者。模型在命名时使用这些作为上下文——被Player$$TakeDamage调用的函数比孤立命名的效果更好。D切换Hex-Rays伪代码显示。.idc脚本或符号文件。.idc脚本可一键将AI生成的名称应用回任何IDA安装中。from spectrida.api import open_i64。通过脚本、笔记本或Claude Code驱动所有功能,无需接触TUI。spectrida install mcp直接连接到Claude Code和/或pi,无需手动编辑JSON。然后Claude可以搜索/读取/遍历基于Neo4j的函数图(名称、伪代码、反汇编、调用者/被调用者),并且可以独立启动对新二进制文件的全新分析——analyze_binary通过一次工具调用运行整个流水线(并行分析→反混淆→AI命名→图),作为后台任务由它轮询。支持PE和NSO。见下文第2章。spectrida --demo)— 在零配置下尝试所有功能。无需IDA,无需Ollama。pip install spectrida
要求:**IDA Pro 9.x** 配合 idalib · **Python 3.10+** · **Ollama**```bash
# install Ollama (Windows)
winget install Ollama.Ollama
# pull the model (8.7 GB — go get coffee)
ollama pull hf.co/gdfhhjk/spectrida-re-gguf:latest
# first run — detects your IDA install and sets everything up
spectrida onboard
# or just try the demo right now
spectrida --demo
spectrida analyze GameAssembly.dll spectrida analyze GameAssembly.dll --workers 8 # custom worker count
spectrida open file.i64
spectrida overview file.i64 spectrida overview file.i64 --addr 0x10001000 --addr 0x10353fd0 # include specific functions
spectrida export file.i64 -f idc # IDA script — apply names to any install spectrida export file.i64 -f json # full dump with addresses + sizes spectrida export file.i64 -f csv # spreadsheet spectrida export file.i64 -f symbols # addr name pairs spectrida export file.i64 --named-only # skip sub_* functions
spectrida serve
spectrida onboard
## TUI 快捷键
| 快捷键 | 操作 |
|--------|------|
| `N` | 函数命名选取 — AI 实时流式输出结果 |
| `R` | 重命名 — 预填充 AI 建议的名称 |
| `D` | 切换反编译伪代码(Hex-Rays) |
| `C` | 调用链 — 调用者与被调用者 |
| `B` | 批量命名当前列表中的所有 `sub_*` 函数 |
| `O` | 概览 — AI 对整个二进制文件的摘要 |
| `/` | 模糊搜索 |
| `?` | 帮助 |
| `Q` | 退出 |
---
## 编程 API
无需 TUI — 可从脚本、Claude Code、Jupyter 笔记本等任意方式驱动 spectrIDA:```python
import asyncio
from spectrida.api import open_i64
async def main():
async with open_i64("GameAssembly.i64") as db:
# list all 153k functions
funcs = await db.list_functions()
# name one function — returns name + reasoning + confidence
result = await db.name_function(0x10001000)
print(result["new_name"]) # init_atexit_handler
print(result["reasoning"]) # allocates array of 3 fn ptrs, calls _atexit...
# batch name everything (with live progress)
async def on_progress(done, total, r):
print(f" {done}/{total} {r['old_name']} -> {r['new_name']}")
await db.batch_name(limit=500, rename=True, progress_cb=on_progress)
# ask what the binary does
overview = await db.overview()
print(overview)
# export to IDA script
await db.export("names.idc", fmt="idc", named_only=True)
asyncio.run(main())
hf.co/gdfhhjk/spectrida-re-gguf — 基于 Qwen3-8B 为逆向工程微调的模型。
训练数据:
jtsylve/ida-mcp 的工具调用轨迹——使用 idalib 的无头 IDA训练方法: 神经元定向 SFT + GRPO。仅调整与逆向工程相关的神经元——基础 Qwen3 知识保持不变,只是在其上添加了非常特定的技能。
本地通过 Ollama 运行。GGUF 格式——可在 CPU、GPU 或两者上运行。
你正在进行逆向工程。你有一个包含 150,000 个函数的二进制文件。也许有 2,000 个函数从元数据中获得了名称。其余 148,000 个是 sub_XXXXXXXX。你想找到网络代码。你无法通过 grep 找到它,因为没有任何东西有名称。
一个人类逆向工程师如果速度够快,每小时可以命名大约 50-100 个函数。按照这个速度,150k 个函数需要 3 年。