Passer au contenu principal
S

ida-pro-mcp-enhanced

sumcam-l/ida-pro-mcp-enhanced

IDA Pro MCP bridge for DeepSeek Harness: connects the local ida-pro-mcp broker into ctx.tools as native mcp__ida__* tools (decompile, xrefs, survey, rename, ...)

Installer

dsh plugin --profile web add github:sumcam-l/ida-pro-mcp-enhanced

README

IDA Pro MCP

增强版作者:QiuChenly · GitHub @QiuChenly

基于上游 mrexodia/ida-pro-mcp 深度改造,新增 Broker 纯路由架构与客户端侧 SQLite 静态缓存接管层。

一套面向 IDA Pro 的 MCP(Model Context Protocol) 服务端,让大模型以结构化工具调用的方式读写 IDA IDB,用于逆向工程、二进制分析、Hook 开发等场景。

英文原版文档请参阅 README.en.md。本 README 描述的是在上游之上增强过的 Broker 架构与 SQLite 静态缓存接管层。

示例视频与 prompt:见 mcp-reversing-dataset。


快速开始

# 1. 安装(装在 IDA 使用的那个 Python 环境里)
pip install https://github.com/Sumcam-L/ida-pro-mcp-enhanced/releases/latest/download/ida_pro_mcp_enhanced-2.0.7-py3-none-any.whl

# 2. 装 IDA 插件(loader + ida_mcp + broker 三件套)+ 打印客户端配置
ida-mcp-setup

# 3. 重启 IDA,打开一个数据库,插件会自动连上 broker

也可以从 Releases 页面 下载 wheel 后本地安装。PyPI 上的 ida-pro-mcp 是上游 mrexodia 的包(1.4.0,无 broker 架构),不要用它。

装完会打印可直接粘贴的 MCP 客户端配置。推荐用 launcher 那一版:

{
  "mcpServers": {
    "ida-pro-mcp": {
      "command": "<your-python>",
      "args": ["-m", "ida_pro_mcp_enhanced.launcher"]
    }
  }
}

为什么推荐 launcher:它按需拉起共享 broker,多个 MCP 客户端(DSH、Cursor、Claude Desktop…)共用同一个 broker 和同一批 IDA 实例。若直接用 ida-pro-mcp(server.py),每个客户端会各拉一个 broker,IDA 实例无法共享。

提供的命令

命令作用
ida-mcp-setup装 IDA 插件并打印客户端配置;--check 体检、--uninstall 卸载
ida-mcp-launcher以 stdio MCP 服务器运行(客户端 spawn 它);status / stop 查状态、停 broker
ida-pro-mcp直接运行 server;--config 打印配置、--broker 起 broker、--install 装插件
idalib-mcpidalib 无头模式

环境变量

全部可选,不设置就用默认值:

变量默认说明
IDA_MCP_PYTHON当前解释器launcher 拉起子进程用的 python
IDA_MCP_BROKER_URLhttp://127.0.0.1:13337broker 地址(端口由此推导)
IDA_MCP_STATE_DIR优先复用 opencode 的 state 目录,否则 %APPDATA%\ida-pro-mcp\state多客户端共享 broker 的关键
IDA_MCP_LOG_DIR同上,...\logsbroker 日志位置
IDA_MCP_TOOL_TIMEOUT_SEC60单次工具调用等待上限
IDA_MCP_SURVEY_MAX_FUNCS50000超过则 survey_binary 直接拒答(避免卡死大库)

关于包名

PyPI 上的 ida-pro-mcp 属于原作者 mrexodia(只到 1.4.0,没有 broker 架构和 launcher),本发行版无法使用该名字。三个名字的关系:

名称发布位置
发行包ida-pro-mcp-enhancedGitHub Releases(wheel)
Python 模块ida_pro_mcp_enhanced—
DSH 插件dsh-ida-mcpnpm

模块名与上游刻意不同,避免两个包在 site-packages 里互相覆盖文件。如果你之前装过上游的 ida-pro-mcp,建议先 pip uninstall ida-pro-mcp 再装本包。

配套的 DSH 插件

如果你用 DeepSeek Harness,装这个插件就能把 IDA 工具注册成原生工具:

dsh plugin install dsh-ida-mcp

插件会自动找到 PATH 上的 python 并拉起 ida_pro_mcp_enhanced.launcher。如果你的 IDA 用的是特定解释器(32 位 IDA 常见),设置 IDA_MCP_PYTHON 环境变量指定。

详见 packages/dsh-ida-mcp。

卸载

ida-mcp-setup --uninstall        # 先移除 IDA 插件
pip uninstall ida-pro-mcp-enhanced   # 再移除 Python 包

一、本发行版修了什么(vs. QiuChenly 增强版)

如果你只是想在 IDA 里顺畅用 MCP,下面这三条是最实际的差别:

问题上游表现本发行版
search_text 搜不存在的 token~235 秒,随后 broker 超时丢弃请求,IDA 主线程仍在跑~15 秒,带时间预算返回 partial 游标
search_text 搜常见符号~70 秒~15 秒
survey_binary 扫十万函数级大库主线程卡几十分钟,且无法取消< 1 秒直接拒答,并建议改用窄工具
工具超时sys.setprofile 抛异常 → traceback 构建期无限递归,100% CPU(旧版);PyThreadState_SetAsyncExc → 主线程锁死,之后所有调用永久阻塞(另一旧版)超时只让调用方放弃等待,主线程安全跑完
安装需手工处理 site-packages 与插件目录两份副本pip install + ida-mcp-setup 一条命令

这些改动的来龙去脉见 PATCHES.md。


二、架构亮点(继承自 QiuChenly 增强版)

  • Broker 进程纯路由:独立监听 127.0.0.1:13337,IDA 实例与所有 MCP 客户端都只和它交互;多 Cursor 窗口、多 IDA 同时挂载不再抢端口。
  • 客户端侧 SQLite 静态缓存(xxx.idb.mcp.sqlite):IDA 插件在 IDA idle 时由守护线程把字符串、函数、全局、导入、交叉引用全量落地到 IDB 旁的 SQLite 文件。
  • 缓存接管 tools/call:find_regex / entity_query / list_funcs / list_globals / imports / refresh_cache / cache_status 共 7 个工具在 IDA 插件进程内部被 直接用本地 SQLite 响应,完全不占用 IDA 主线程。
  • 严格类型协议:全部新增 API 的请求/返回走 TypedDict(FindRegexArgs / FindRegexResult / ToolSchema / McpToolCallResult 等),消除"字段是否存在"之类的不确定性。
  • Broker 注入虚拟工具:refresh_cache 与 cache_status 作为虚拟 ToolSchema 追加到 tools/list 结果中,模型可以直接看到并调用,但它们并不在 Broker 执行,最终仍被路由到指定 IDA 实例。
  • idalib 无头模式:通过 idalib-mcp 运行纯 headless 服务,支持 --isolated-contexts 做严格的每连接上下文隔离。

三、环境要求

  • Python 3.11+(建议使用 idapyswitch 切换到最新 Python)
  • IDA Pro 8.3+(推荐 9.0+),不支持 IDA Free
  • 支持任意标准 MCP 客户端:Cursor / Claude / Claude Code / Codex / VS Code / Gemini CLI / Cline 等

四、安装

从 wheel 安装(推荐)

pip install ida-pro-mcp-enhanced
ida-mcp-setup

ida-mcp-setup 会做三件事:把 ida_mcp.py(loader)、ida_mcp/(75 个工具实现)、broker/(缓存守护线程与接管层)铺到 IDA 插件目录,打印各 MCP 客户端的可粘贴配置,并用 --check 可随时体检。

从源码安装

git clone https://github.com/Sumcam-L/ida-pro-mcp-enhanced
cd ida-pro-mcp-enhanced
bash scripts/build.sh          # 产出 dist/*.whl
pip install dist/*.whl
ida-mcp-setup

开发模式(改代码即时生效):

cd ida-pro-mcp-enhanced && uv venv && uv pip install -e .

装完必须做的事

完全重启 IDA 和 MCP 客户端。某些客户端(如 Claude Desktop)在后台常驻,需要从托盘图标退出。IDA 插件菜单需要先加载一个二进制文件才会出现。

为什么插件目录和 Python 包都要装

这两处是两份独立副本,不是软链接:Python 包供 broker 与 stdio server 使用(提供 62 个工具的 schema 与路由),IDA 插件目录供 IDA 进程内的插件使用(真正调用 IDAPython API)。改一处而不装另一处,会出现「工具列表是对的、调用却报错」这类难查问题。ida-mcp-setup 一次装齐两边。


五、总体架构

下面这张图描述本增强版的所有运行时组件与数据流。

flowchart LR
    subgraph Clients[MCP 客户端]
        CurA[Cursor 窗口 A]
        CurB[Cursor 窗口 B]
        Claude[Claude / Codex / VS Code ...]
    end

    subgraph MCPProc[MCP 进程 - 每个客户端各一份]
        direction TB
        MA[ida-pro-mcp 进程 A - stdio]
        MB[ida-pro-mcp 进程 B - stdio]
        DispatchProxy[dispatch_proxy - tools/list 注入虚拟工具 / tools/call 走路由]
    end

    subgraph BrokerProc[Broker 进程 - 127.0.0.1:13337 - 唯一监听]
        Registry[IDA 实例注册表]
        Router[纯路由 HTTP + SSE]
    end

    subgraph IDAProc[IDA 插件进程]
        Plugin[ida_mcp 插件 - handle_mcp_request]
        CacheHandlers[cache_handlers - 本地拦截 7 个缓存工具]
        Daemon[sqlite_cache 守护线程 - idle 时刷新]
        DB[(xxx.idb.mcp.sqlite)]
        IDAAPI[IDA / Hex-Rays API]
    end

    CurA -- stdio --> MA
    CurB -- stdio --> MB
    Claude -. stdio .-> MA

    MA -- HTTP JSON-RPC --> Router
    MB -- HTTP JSON-RPC --> Router
    MA --> DispatchProxy
    MB --> DispatchProxy

    Router <-- HTTP 注册 + SSE 推送 --> Plugin

    Plugin -- 先命中? --> CacheHandlers
    CacheHandlers -- 只读 --> DB
    Plugin -- 未命中 --> IDAAPI
    Daemon -- 采集 --> IDAAPI
    Daemon -- 批量写入 --> DB

关键点:

  • MCP 进程不绑端口:每个客户端窗口自己启动一份 ida-pro-mcp(stdio),它们全部把请求通过 HTTP 丢给 Broker。
  • Broker 只做路由:它不读 IDB、不读 SQLite,完全不碰业务逻辑;只负责把 JSON-RPC 请求按 instance_id 扔给对应的 IDA 插件,并把 SSE 回写的响应拿回来。
  • SQLite 读写都在 IDA 进程内:写由守护线程负责(idle 触发),读由 handle_mcp_request 的拦截层负责(命中就查 DB,不再走 IDA API)。Broker 进程绝不 import sqlite_cache / sqlite_query。

六、一次 tools/call 的完整时序

sequenceDiagram
    autonumber
    participant LLM as 大模型 / MCP 客户端
    participant MCP as ida-pro-mcp 进程 (stdio)
    participant BRK as Broker 进程 127.0.0.1:13337
    participant IDA as IDA 插件 handle_mcp_request
    participant CACHE as cache_handlers + sqlite_query
    participant HR as IDA / Hex-Rays

    LLM->>MCP: tools/call find_regex(instance_id=...)

    Note over MCP: dispatch_proxy 判断工具名命中 IDA 白名单
    MCP->>BRK: HTTP JSON-RPC 转发
    Note over BRK: 按 instance_id 查注册表
    BRK-->>IDA: 通过 SSE 通道下发请求

    IDA->>CACHE: is_cache_tool(req)?
    alt 命中缓存拦截名单
        CACHE->>CACHE: 打开 .mcp.sqlite (只读) 并检查 meta.status
        alt status == ready
            CACHE->>CACHE: SQL + REGEXP 查询
            CACHE-->>IDA: TypedDict 结构化结果
        else status != ready 或 DB 缺失
            CACHE-->>IDA: JSON-RPC error -32001 缓存未就绪,稍后重试或 refresh_cache
        end
    else 未命中 (普通 IDA 工具)
        IDA->>HR: 走 ida_mcp 正常 dispatch
        HR-->>IDA: 结果
    end

    IDA-->>BRK: JSON-RPC response
    BRK-->>MCP: HTTP 响应
    MCP-->>LLM: tools/call 结果

缓存未就绪时不会回退到实时 IDA API,而是直接向模型报错并提示稍后重试或先调用 refresh_cache。这是一种有意的硬性语义:避免在大模型未知状态下拿到"半新半旧"数据造成误判。


七、SQLite 缓存守护线程生命周期

stateDiagram-v2
    [*] --> 未连接
    未连接 --> 已连接: IDA 注册到 Broker
    已连接 --> 首次写入: 守护线程检测 auto_is_ok() + hex-rays 初始化完成
    首次写入 --> 写入中: status=building
    写入中 --> 就绪: 全量写入完成 status=ready
    就绪 --> 写入中: IDB 保存 / refresh_cache 触发 / 30 分钟兜底轮询
    写入中 --> 错误: 采集或写入异常
    错误 --> 写入中: 下一次 idle 自动重试
    就绪 --> [*]: IDA 关闭 / 断开
    写入中 --> [*]: IDA 关闭 / 断开
  • 缓存文件名固定为 <idb 路径>.mcp.sqlite,随 IDB 一起落盘。
  • meta 表记录 status(building / ready)、last_updated 等。
  • 使用 WAL 模式,允许写入进行中仍被只读 file:...?mode=ro 连接查询(读到旧快照)。
  • cache_status 查询不抛错:文件缺失时返回 {exists: false, status: "missing"}。
  • 重新索引触发时机(三种,任一满足即触发,触发后等待 IDA idle 再执行全量重建):
    1. IDB 保存:IDA 每次保存数据库(Ctrl+S 或自动保存)时,IDB_Hooks.savebase 回调立即唤醒守护线程,确保重命名、新增函数等变更实时同步。
    2. 主动调用 refresh_cache:MCP 客户端显式触发,绕过所有检查直接重建。
    3. 30 分钟兜底轮询:定时唤醒时检查 IDB 文件 mtime,若与上次重建时一致则跳过,避免无意义的全量扫描。

八、使用方式(Broker 模式)

多窗口 Cursor、多个 IDA 实例并用时,请务必先启动 Broker,再启动客户端。

# 1. 先启动 Broker(保持一个终端常开)
uv run ida-pro-mcp --broker
# 或自定义端口
uv run ida-pro-mcp --broker --port 13337

# 2. 启动 Cursor/Claude/VS Code 等,它们会通过 stdio 启动
#    自己的 ida-pro-mcp 进程,并向上面的 Broker 发请求

# 3. 打开 IDA、加载二进制,按 Ctrl+Alt+M 连接到 Broker

远程访问

当 MCP 客户端(Cursor / Claude)运行在另一台机器上时,--broker 直接绑定 0.0.0.0,一个端口同时处理 IDA 插件和远程 MCP 客户端:

uv run ida-pro-mcp --broker --port 13337

在远程机器的 MCP 客户端配置中:

{
  "mcpServers": {
    "ida-pro-mcp": {
      "url": "http://<IDA机器的IP>:13337/mcp"
    }
  }
}

IDB 打开后,在 IDA 中按 Ctrl+Alt+M,连接地址填 http://<机器IP>:13337。

安全提示:远程模式下 CORS 会自动放宽为 *。建议仅在可信网络中暴露端口,或配合 VPN/SSH 隧道使用。

多实例模式

同时分析多个二进制:打开多个 IDA,分别按 Ctrl+Alt+M 连上 Broker。

工具说明
instance_list()列出所有已连接 IDA 实例(instance_id, name, binary_path, idb_path, base_addr)
instance_info(instance_id)获取指定实例的详细信息

本增强版不再提供"当前活动实例"的隐式状态,也没有 instance_switch / instance_current。每次调用业务工具(如 decompile、xrefs_to、find_regex 等)时都必须在 arguments 里显式带 instance_id,由 Broker 精确路由到目标 IDA。这样做是为了避免多个 MCP 客户端共享同一个 Broker 时相互踩隐式状态。


九、命令行参数

参数说明
--install安装 IDA 插件 + 各 MCP 客户端配置
--uninstall卸载 IDA 插件 + 各 MCP 客户端配置
--unsafe启用调试器等不安全工具(dbg_*)
--broker启动 Broker HTTP 服务器(0.0.0.0),同时提供 MCP 协议端点和 IDA 注册端点
--broker-url URL当前 MCP 进程要连的 Broker 地址,默认 http://127.0.0.1:13337
--port PORTBroker 监听端口,默认 13337
--config打印当前 MCP 配置

Broker 地址也可由环境变量指定:

IDA_MCP_BROKER_URL=http://127.0.0.1:13337 ida-pro-mcp

启用调试器工具

{
  "mcpServers": {
    "ida-pro-mcp": {
      "command": "uv",
      "args": ["run", "ida-pro-mcp", "--unsafe"]
    }
  }
}

十、缓存相关工具

工具语义错误行为
find_regex(instance_id, pattern, limit?, offset?, include_xrefs?)正则搜索字符串表,含 xrefsstatus != ready 时抛 -32001
entity_query(instance_id, kind, name_pattern?, segment?, ...)统一实体查询,kind ∈ strings / functions / globals / imports同上
list_funcs(instance_id, name_pattern?, ..., include_xrefs?)函数列表,可带 xrefs同上
list_globals(instance_id, name_pattern?, ...)全局变量列表同上
imports(instance_id, name_pattern?, module_pattern?, ...)导入表列表同上
refresh_cache(instance_id)唤醒目标 IDA 的缓存守护线程,立即返回 {triggered, idb_path}永不抛错
cache_status(instance_id)查询缓存文件是否存在、status、各表计数文件不存在时返回 {exists: false, status: "missing"}

错误码约定:

  • -32001:缓存未就绪 / 文件缺失
  • -32000:未提供 instance_id 或没有活动 IDA 实例
  • -32602:参数错误(如 entity_query.kind 非法)
  • -32603:SQLite 查询内部异常

十一、非缓存工具总览

以下工具仍走 IDA API 正常 dispatch,由插件进程通过 @idasync 在 IDA 主线程执行。

下列工具均为代码中真实注册的工具名(以仓库 api_*.py 中的 @tool 定义为准),若有出入请以源码为准。

核心查询

  • lookup_funcs(queries) 按地址或名称获取函数
  • int_convert(inputs) 十进制 / 十六进制 / 字节 / ASCII / 二进制互转
  • decompile(addr) / disasm(addr) 反编译 / 反汇编
  • xrefs_to(addrs) / xref_query(queries) / xrefs_to_field(queries) 交叉引用
  • callees(addrs) 被调用函数
  • func_profile(queries) 快速获取函数画像(prolog / 返回 / 基本块摘要等)

修改

  • set_comments(items) 反汇编与伪代码视图同时写注释
  • patch_asm(items) 汇编级补丁
  • declare_type(decls) 在 IDB 本地类型库声明 C 类型
  • define_func(items) / define_code(items) / undefine(items) 函数 / 代码定义控制

内存读取

  • get_bytes(addrs) / get_int(queries) / get_string(addrs) / get_global_value(queries)

栈帧

  • stack_frame(addrs) / declare_stack(items) / delete_stack(items)

结构体

  • read_struct(queries) / search_structs(filter)

高级分析

  • py_eval(code) 在 IDA 上下文执行任意 Python
  • analyze_function(addr, ...) 单函数深入分析(反编译 + 汇编 + xrefs + 调用关系 + 基本块 + 常量 + 字符串)
  • analyze_batch(queries) 批量版 analyze_function
  • analyze_component(...) 以入口为根的组件级分析(调用树 + 数据流摘要)
  • diff_before_after(...) 前后快照差异分析
  • trace_data_flow(...) 数据流追踪

模式搜索

  • find_bytes(patterns) 字节模式搜索(支持 48 8B ?? ??)
  • insn_query(queries) 按助记符 / 操作数语义的指令序列查询
  • find(type, targets) 立即值 / 字符串 / 数据与代码引用统一搜索

控制流 / 类型 / 导出 / 图

  • basic_blocks(addrs)
  • set_type(edits) / infer_types(addrs)
  • export_funcs(addrs, format) 导出为 json / c_header / prototypes
  • callgraph(roots, max_depth)

批量

  • rename(batch) 函数 / 全局 / 局部 / 栈变量统一批量改名
  • patch(patches) 批量字节修补
  • put_int(items) 批量写整数

调试器(需 --unsafe)

  • 控制:dbg_start / dbg_exit / dbg_continue / dbg_run_to / dbg_step_into / dbg_step_over
  • 断点:dbg_bps / dbg_add_bp / dbg_delete_bp / dbg_toggle_bp
  • 寄存器:dbg_regs / dbg_regs_all / dbg_gpregs / dbg_regs_named / dbg_regs_remote / dbg_gpregs_remote / dbg_regs_named_remote
  • 栈 / 内存:dbg_stacktrace / dbg_read / dbg_write

十二、MCP 资源(只读状态)

按 MCP 规范暴露的 ida:// 资源:

  • ida://idb/metadata IDB 元数据(路径、架构、基址、哈希)
  • ida://idb/segments 段与权限
  • ida://idb/entrypoints 入口点(main / TLS 回调等)
  • ida://cursor 当前光标 + 所在函数
  • ida://selection 当前选区
  • ida://types 本地类型
  • ida://structs 所有结构 / 联合
  • ida://struct/{name} 结构字段
  • ida://import/{name} 按名查导入
  • ida://export/{name} 按名查导出
  • ida://xrefs/from/{addr} 从地址出发的交叉引用

十三、SSE 传输与无头 idalib

本增强版的 ida-pro-mcp 主入口默认通过 stdio 连接 MCP 客户端,Broker 模式 (--broker) 则直接提供 HTTP 端点(默认 0.0.0.0:13337),单端口承载全部功能:

uv run ida-pro-mcp --broker

该端口同时提供:

  • /mcp — Streamable HTTP(MCP 客户端连接)
  • /sse — MCP SSE 传输
  • /register, /events 等 — IDA 插件注册与 SSE 通道

无头模式由 idalib-mcp 提供(需安装 idalib)。可以启动时指定一个二进制:

uv run idalib-mcp --host 127.0.0.1 --port 8745 path/to/executable

也可以不带初始文件启动,之后用 idalib_open(...) / idalib_close(...) 动态打开和关闭数据库:

uv run idalib-mcp --host 127.0.0.1 --port 8745

stdio 客户端可使用:

uv run idalib-mcp --stdio

idalib-mcp 是一个 supervisor:每个打开的数据库由独立 idalib worker 进程承载。若请求的 IDB 已经在运行插件的 GUI IDA 中打开,idalib-mcp 会优先路由到该 GUI 实例;GUI 实例消失后,下次请求会在可行时回退到无头 worker。需要让回退看到 GUI 中的改动时,请先保存 IDB。

工具可通过当前 MCP 上下文绑定的数据库执行,也可以显式传 database 参数指定 session ID、文件名或输入路径:

uv run idalib-mcp --stdio --max-workers 4
idalib_open("/path/to/binary_a.exe", session_id="binary_a")
idalib_open("/path/to/library.dll", session_id="library")

decompile("main", database="binary_a")
xrefs_to("ImportantExport", database="library")

需要严格的每传输上下文隔离时启用 --isolated-contexts:

uv run idalib-mcp --isolated-contexts --host 127.0.0.1 --port 8745 path/to/executable

--isolated-contexts 的语义:

  • 每个传输上下文(/mcp 的 Mcp-Session-Id、/sse 的 session、stdio 的 stdio:default)都有自己独立的 session 绑定。
  • 未绑定上下文调用 IDB 依赖工具会直接失败,避免跨 Agent 误操作。
  • 多 Agent 想共享同一 session 时,可以传 database=... 或通过 idalib_switch(session_id) 主动加入。

上下文管理工具:

  • idalib_open(input_path, ...) 打开并绑定
  • idalib_switch(session_id) 切换绑定
  • idalib_current() 查当前绑定
  • idalib_unbind() 解绑
  • idalib_list() 列表,带 is_active / is_current_context / bound_contexts / backend / pid

worker 控制:

  • --max-workers N:最大同时打开的数据库 worker 数(0 表示无限制,默认 4)
  • IDA_MCP_MAX_WORKERS:--max-workers 的环境变量默认值

十四、提示工程建议

大模型在进制转换、数学计算、混淆代码上容易出错。务必:

  • 明确要求使用 int_convert 工具做进制转换,不要让模型手算。
  • 必要时配合 math-mcp 做复杂运算。
  • 混淆代码先做预处理再交给 LLM:字符串解密、导入哈希、控制流平坦化、代码加密、反反编译技巧。
  • 用 Lumina 或 FLIRT 把开源库、C++ STL 先解掉。

一个适用于 crackme 场景的最小提示:

你的任务是在 IDA Pro 中分析一个 crackme。你可以使用 MCP 工具获取信息。总体策略:

- 先用 decompile / disasm 审阅反编译与汇编
- 对可疑代码加注释,然后把变量、参数、函数重命名为具有描述性的名字
- 必要时修正类型(尤其是指针、数组)
- 绝对不要自己做进制转换,一律用 int_convert
- 不要暴力破解,只从反汇编和简单 python 脚本中推导结论
- 分析完成后写一份 report.md,最后把找到的密码交给用户确认

十五、常见问题

Q:IDA 插件连接失败 / instance_list 空?

  1. 先单独启动 Broker:uv run ida-pro-mcp --broker(保持运行)
  2. 再启动 Cursor / Claude / VS Code 等
  3. 在 IDA 里按 Ctrl+Alt+M 连接
  4. 如端口冲突:ida-pro-mcp --broker --port 13338,并确保 IDA 插件与 MCP 客户端的 broker-url 一致

Q:调用 find_regex / list_funcs 等返回 -32001?

说明本地 .mcp.sqlite 还没写好,属于正常初始化期。可以:

  • 调用 cache_status(instance_id=...) 查看 status 与各表计数。
  • 调用 refresh_cache(instance_id=...) 主动唤醒缓存守护线程。
  • 稍等片刻后重试。

Q:缓存文件在哪?能删吗?

就在 IDB 旁边:<idb 路径>.mcp.sqlite(和 .mcp.sqlite-wal / -shm 同目录)。随时可删;下次 IDA idle 时会重建。

Q:uv pip install -e . 提示 "Failed to clone files; falling back to full copy"?

这只是 uv 的 warning(reflink 跨卷失败),构建其实成功。本项目 pyproject.toml 已内置 [tool.uv] link-mode = "copy" 消除该提示。

Q:支持 IDA Free 吗?

不支持,IDA Free 没有插件 API。

Q:按 G 键跳转失败?

请更新到最新版本后重启 IDA:

uv pip install -e .

十六、开发

核心实现位置:

  • src/ida_pro_mcp/server.py 主 MCP 服务端入口(stdio / broker 双模式分发)
  • src/ida_pro_mcp/idalib_server.py idalib 无头服务端
  • src/ida_pro_mcp/ida_mcp.py IDA 插件入口与 handle_mcp_request
  • src/ida_pro_mcp/ida_mcp/api_*.py 所有业务工具与资源(纯 IDA 侧)
  • src/ida_pro_mcp/broker/server.py Broker HTTP + 注册表 + SSE
  • src/ida_pro_mcp/broker/manager.py dispatch_proxy 路由 + 虚拟工具注入
  • src/ida_pro_mcp/broker/sqlite_cache.py 插件侧 idle 守护 + 写入
  • src/ida_pro_mcp/broker/sqlite_query.py 插件侧只读查询(强类型)
  • src/ida_pro_mcp/broker/cache_handlers.py tools/call 的本地缓存拦截
  • src/ida_pro_mcp/broker/cache_types.py 全部协议 TypedDict(JsonRpcRequest / Response / Error / ToolSchema / *Args / *Result)

新增工具只需:

  1. 在对应的 api_*.py 里写一个 @tool + @idasync 函数,带完整 Python 类型注解;
  2. 用 Annotated[...] 写参数说明,函数 docstring 就是暴露给模型的 tool description;
  3. MCP 服务端会自动扫描 api_*.py 并注册,无需手动改 schema。

运行测试:

uv run ida-mcp-test tests/crackme03.elf -q
uv run ida-mcp-test tests/typed_fixture.elf -q

MCP inspector 调试:

uv run mcp dev src/ida_pro_mcp/server.py

覆盖率:

uv run coverage erase
uv run coverage run -m ida_pro_mcp.test tests/crackme03.elf -q
uv run coverage run --append -m ida_pro_mcp.test tests/typed_fixture.elf -q
uv run coverage report --show-missing

十七、与其它 IDA MCP 的差异

市面上已有数个 IDA Pro MCP 实现,本仓库在上游 mrexodia/ida-pro-mcp 的基础上重点做了两件事:

  • 把 Broker 做成纯路由,解决多客户端并发问题;
  • 在客户端侧引入 SQLite 静态缓存,把高频只读查询从 IDA 主线程移走,让大模型在大规模分析场景下不再因 IDA API 往返而被拖慢。

其他实现(便于对比选型):

欢迎 PR 补充。


十八、许可证

见 LICENSE。


署名

本项目在 QiuChenly 的增强版基础上,把原先散落在 site-packages 与 IDA 插件目录的两份不同步副本合并为单一源码树,修复了超时机制导致主线程锁死等问题,并打包成可直接 pip install 的发行版。

如在论文、博客或工具中使用,请同时署名三层作者。完整归属与第三方文档说明见 NOTICE。

Plugins associés