Skip to main content
Glama
Claude-Reverser

IDA-instances-MCP

IDA-instances-MCP

基于 ida-proxy-mcp 的自定义构建:一个 MCP 服务器,让 MCP 客户端可以驱动 IDA Pro——经过稳定性加固改造,旨在支持多个无头 idalib 实例(即 Ida-Instances 方案)。

这是 mrexodia 的 ida-proxy-mcp(MIT)的一个 fork。所有上游原版功劳归为 Duncan Ogilvie 及各位贡献者;本仓库负责维护下述自定义改动。

What's custom

在上游 v2.0.0 的基础上进行稳定性加固:

领域

改动

数据安全

数据库部分清理具备所有权感知:从不删除其他活跃运行中的实例所持有的 .id0/.id1/.id2/.nam/.til 文件,并在无法确定所有权时安全带load

保存可靠性

idb_save 以 600 秒预算运行(先前是 60 秒);idb_close 在保存失败后拒绝杀掉 worker,而不是继续静默丢弃更改

并发安全

Supervisor 锁不再覆盖 worker 启动(约 120 秒)、健康探测(每会话约 2.5 秒)或过期 worker 终止——一次较慢的打开不会拖垮所有会话

健壮性

通过 stdio 接收的畸形 JSON-RPC 现在会返回 -32700/-32600,而不是导致代理崩溃

超时设置

代理超时从 30 秒提升到 900 秒,并可通过 IDA_MCP_PROXY_TIMEOUT 配置;服务端还在运行的长反编译不会再在客户端表现为“失败”

网络层

worker 端口的 TOCTOU 问题现在会重试;SSE 写入和销毁流程由锁保护;从 IDA 主线程移出 CORS 策略的读取

资源限制

IDB 中的 trace 日志上限为 IDA_MCP_TRACE_MAX_MB,默认 64 MB,超长参数/结果会被截断;刷新失败队列也有上限

身份验证

每个 HTTP 请求都需要实例 API 密钥;密钥通过 GET /key 只签发一次,之后立即失效;密钥保存在磁盘上,重启和中断后仍然有效

托管端点

GET /health(无需认证的就绪探针)、GET /sessions(打开的数据库 + 最后访问时间)、POST /upload(直接上传二进制并带大小限制)

空闲回收

超过 IDA_MCP_IDLE_TIMEOUT 分钟未访问的会话会被自动关闭(先执行保存)

优雅停机

收到 SIGTERM/SIGINT 后,退出前先保存所有已打开的数据库——不会再因服务更新而丢失工作

自更新

启动时检查 GitHub Releases;交互式会话提供一键自动更新

托管默认值

无头 supervisor 默认监听 0.0.0.0:9999;GUI 插件同样绑定 0.0.0.0,并且现在也要求相同的 API 密钥

Related MCP server: idalib-mcp-headless

系统要求

  • Linux、macOS 或 Windows

  • Python 3.11+(在 IDA 中使用 idapyswitch 来匹配版本)

  • IDA Pro 8.3+(建议 9.x)。不支持 IDA Free

  • uv

  • 一个 MCP 客户端(Claude Code、Cursor、Codex、Opencode、VS Code 等)

配置

为 uv 环境启用 idalib:

# linux (server deployment)
uv run "/opt/idapro-9.x/idalib/python/py-activate-idalib.py"
# macos
uv run "/Applications/IDA Professional 9.x.app/Contents/MacOS/idalib/python/py-activate-idalib.py"
# windows
uv run "C:\Program Files\IDA Professional 9.x\idalib\python\py-activate-idalib.py"

无头运行模式还需要将 IDA 安装目录放到 IDADIR 环境变量中。

运行无头 supervisor(托管模式)

uv run idalib-mcp                # serves http://0.0.0.0:9999/mcp (new default)

启动时会生成(或从磁盘加载)一个 API 密钥,任何未携带该密钥的请求都会得到 401 Unauthorized——没有例外。

在拥有该安全密钥的机器上,只取一次密钥:

curl http://your-host:9999/key
# {"key": "3f2b..."}   <- save it; this endpoint is now burned until restart
  • 密钥持久化保存在 ~/.idapro/mcp/api_key(文件权限 0600)中,重启后依然有效;GET /key 仅在每次服务启动时签发一次

  • 可用 KMPE_API_KEY 覆盖默认值(或通过 IDA_MCP_API_KEY_FILE 修改存储位置)

  • 其他所有端点都会在每次调用中要求此密钥:

Authorization: Bearer <key>
# or equivalently
X-API-Key: <key>

· 密钥绝不会被写入日志。

托管端点

端点

认证

用途

GET /health

无

就绪探针:{"status":"ok","uptime":N,"sessions":N}——建议用轮询代替 sleep

GET /sessions

密钥

查看已打开数据库及最后访问时间

POST /upload?filename=NAME

密钥

原始请求体二进制上传,流式保存到 IDA_MCP_UPLOAD_DIR;返回一个可传给 idb_open 的路径

# provisioning flow
while ! curl -sf http://10.0.0.4:9999/health >/dev/null; do sleep 1; done
KEY=$(curl -s http://10.0.0.4:9999/key | jq -r .key)
curl -H "Authorization: Bearer $KEY" --data-binary @sample.elf \
     "http://10.0.0.4:9999/upload?filename=sample.elf"

常用命令:

uv run idalib-mcp --host 127.0.0.1 --port 9999   # override bind address
uv run idalib-mcp --max-workers 8                # concurrent databases (default 4, 0 = unlimited)
uv run idalib-mcp --unsafe                       # enable destructive/debugger tools (DANGEROUS)
uv run idalib-mcp --profile tools.txt            # restrict worker tools to a profile file
uv run idalib-mcp --stdio                        # stdio transport instead of HTTP
uv run idalib-mcp path/to/binary                 # open a binary at startup

会话生命周期工具:idb_open、idb_list、idb_close——每个会话打开一个数据库;每个会话有自己的独立 worker 进程。

运行 GUI 代理组件(交互式 IDA)

在 IDA 中启动插件(Edit -> Plugins -> MCP,或 Ctrl+Alt+M),然后:

uv run ida-pro-mcp                                   # stdio proxy, auto-discovers IDA
uv run ida-pro-mcp --transport http://127.0.0.1:9999 # serve HTTP instead

连接 MCP 客户端

通用 JSON 配置(HTTP 传输):

{
  "mcpServers": {
    "ida-instances": {
      "url": "http://your-host:9999/mcp",
      "headers": {
        "Authorization": "Bearer <key-from-/key>"
      }
    }
  }
}

Claude Code:

claude mcp add --transport http ida-instances http://your-host:9999/mcp \
  --header "Authorization: Bearer <key-from-/key>"

对于通过 stdio 运行的 GUI 代理,请执行 uv run ida-proxy-mcp --config,并把 JSON 粘贴到你的客户端。

配置(环境变量)

变量

默认值

含义

IDA_MCP_OPEN_TIMEOUT

1800

idb_open/open + auto-analysis 总的可用秒数(超过后回收;0 = 不限制)

IDA_MCP_WORKER_CALL_TIMEOUT

900

每次转发工具调用的兜底超时

IDA_MCP_PROXY_TIMEOUT

900

GUI 代理 → IDA 上游超时(0 = 不限制)

IDA_MCP_TRACE_MAX_MB

64

存储在 IDB 中的 trace 日志上限(MB)

IDA_MCP_MAX_WORKERS

4

默认的 --max-workers

IDA_MCP_HEALTH_TCP_TIMEOUT / IDA_MCP_HEALTH_RPC_TIMEOUT

2.0 / 10.0

健康探针的预算时间

IDA_MCP_IDLE_TIMEOUT

60

会话闲置超过该分钟数后自动关闭(0 = 关闭该功能)

IDA_MCP_MAX_UPLOAD_MB

100

POST /upload 请求体大小上限

IDA_MCP_UPLOAD_DIR

~/.idapro/mcp/uploads

上传文件的保存目录

IDA_MCP_API_KEY / IDA_MCP_API_KEY_FILE

– / ~/.idapro/mcp/api_key

注入或重定向实例 API 密钥的位置

IDA_MCP_SHUTDOWN_SAVE_TIMEOUT / IDA_MCP_SHUTDOWN_SAVE_BUDGET

30 / 120

每个数据库 / 总体的 SIGTERM 保存预算

IDA_MCP_NO_UPDATE_CHECK

未设置

设为 1 以禁用 GitHub Release 检查

安全说明: API 密钥会保护两个服务(supervisor 和 GUI 插件)的每个 HTTP 端点,且 GUI 插件可以通过 py_eval 执行任意代码,所以即使在回环地址上同样要求密钥。它是构成 bearer token(即“持令牌即可访问”)——一旦有人获得该密钥,他就可以完整操作该实例;如果它要离开你的可信网络,请再套一层 TLS 反向代理。浏览器访问 . http://... 时也可以把 key 放在 URL 中,形式为 ?key=<key>(主要用于 /config.html 这类页面)。

测试

IDADIR=/path/to/ida uv run ida-mcp-test tests/crackme03.elf -q
IDADIR=/path/to/ida uv run ida-mcp-test tests/typed_fixture.elf -q
IDADIR=/path/to/ida uv run ida-mcp-test tests/crackme03.elf -c api_analysis   # one category
IDADIR=/path/to/ida uv run coverage run -m ida_pro_mcp.test tests/crackme03.elf -q

License

MIT 许可——继承上游 ida-proxy-mcp。上游产品名称(IDA Pro、Hex-Rays)均为 Hex-Rays SA 的商标;本项目需要你持有自己的 IDA Pro 许可证。

Related MCP Connectors

Related MCP Servers