首页 / 接入指南

接入指南

从零开始接入 BinDetective:一条 POST 请求、一个 session_id,即可完成从样本装载到伪代码输出的完整链路。

概览

BinDetective 二进制侦探是面向 AI 时代的轻量化、高并发、多架构二进制反编译与识别引擎, 采用 C++ 开发。它原生支持多款处理器架构,兼容 PE、ELF、Mach-O 三大主流可执行文件格式, 可完成自动化反编译;同时兜底识别十余种常见非二进制文件,自动判别大小端与位数, 覆盖 x86、ARM、AArch64 等主流架构,对部分小众架构可完成名称识别,提升二进制样本的快速分析与适配能力。

架构覆盖与 Sleigh 规范一致: 引擎完整对接 Sleigh 指令集描述语言, 因此 Sleigh 规范覆盖的全部处理器架构均被支持——x86(16/32/64)、ARM / AArch64、MIPS、PowerPC、SPARC、 RISC-V、LoongArch、SuperH、68000、V850、TriCore、Xtensa、PA-RISC、PIC、AVR、MSP430、8051、6502、Z80、 JVM、Dalvik、eBPF 等处理器族均在其列,大小端与位数变体一并覆盖。 要确认当前部署实际可用的架构清单,请直接调用 ListLanguages(direct), 其返回的语言 ID 列表即为服务端真实支持的处理器定义。

引擎通过 HTTP POST 对 AI Agent 与后端服务暴露能力。 设计上刻意收敛了协议表面积:只有一个端点、一种方法、一种编码,所有差异都体现在请求体里。

这套结构的直接收益是:Agent 侧不需要为每个能力维护路由表或 SDK 版本,只需一份接口清单与一份参数顺序,即可在无 SDK 的情况下完成调用。

引擎内核与流水线

引擎共计实现 120 余项能力,依托并完整对接 Sleigh 指令集描述语言, 在其基础之上搭载全套自研核心算法,从文件装载到反编译后端的每一段都由自研模块承担。 分析结果逐级增强后送入反编译后端,所有环节可控、可观测、可逐层调参。

  • 装载与前端:PE / ELF / Mach-O 文件加载、函数边界扫描、函数序言识别。
  • 结构与控制流:控制流恢复、跳转表与间接跳转消解、栈帧与 ABI 分析。
  • 类型与中间表示:类型管理与推导、p-code 构造、符号与调试信息注入。
  • 运行支撑:任务调度、会话隔离、缓存、异常处理。

三类调用面

  • 会话装载与管理(direct,4 项):Open 装载二进制并返回 session_id,SessionCreate / SessionList / SessionClose 负责空会话的创建、枚举与释放;它们本身不写会话状态,因此不要求携带 session(Open 成功后会由客户端自动绑定)。
  • 会话接口(session,133 项):绑定到某个 session_id 的分析能力,如下按功能分组全部列出(点击任意接口名查看签名、参数与调用示例)。
  • 无状态分析(direct,11 项):字节流级别的即时分析,如 DisasmBytes、DecompileHex、IdentifyArchitecture、Crc32、AssembleRoundTrip。可任意水平扩展,不占用会话资源。
  • 服务信息与控制面(direct,3 项):ListLanguages、GenerateOpenAPI、HealthStats,用于能力枚举、契约导出与运行状态观测。

文档即源码: 本站在构建时对 bin_detective_client.py 做静态解析(python extract_ifaces.py), 把 151 个接口逐一映射到真实方法,提取其完整签名、参数默认值、docstring 与所在行号, 同时读取源码里的 SUPPORTED_INTERFACES / INTERFACE_MODES / INTERFACE_CALL_INFO 三张注册表, 因此接口文档中看到的每一个参数名、默认值与 mode 标记,都能在源码里逐字对应。

快速开始

1. 准备环境

引擎默认监听 127.0.0.1:8000,鉴权头为 X-Auth-Token。客户端在未显式传入 token 时,按以下顺序取值:

  1. 环境变量 BINDETECTIVE_TOKEN
  2. 内置默认 Key DEFAULT_API_KEY
提示: 服务端与客户端需部署在同一台机器(或同一内网),因为 Open 接收的是服务端本地路径,样本文件需对引擎进程可见。

2. 安装客户端库

客户端库通过 pip 安装,随库附带的 bin_detective_client.py 即本站接口文档的解析源头:

3. 建立客户端

4. 装载样本

调用 Open 装载二进制文件。引擎会自动判定格式(PE / ELF / Mach-O)、CPU 架构、字节序与位数,并在成功返回时把 session_id 自动绑定到当前客户端。

5. 得出第一份伪代码

取函数列表里的第一个地址,交给 Decompile 得到 C 代码:

注意: 会话域接口必须显式携带 session,引擎不提供隐式的“当前会话”回退。 直接调用底层 call() 而未传 session 时,服务端会返回 E_SESSION_REQUIRED。

传输层约定

以下三条约定不是建议,而是引擎稳定运行的前提,尤其在与 mongoose 类轻量 HTTP 服务端通信时。

请求格式

为什么必须使用 Connection: close

引擎对重接口(尤其是 Open 与首次 Decompile)在 keep-alive 长连接下可能出现不响应或挂起。 官方客户端因此改用 raw-socket + Connection: close 的直连方式,并在读取响应时按 Content-Length 读满 body 即返回, 不等 EOF —— 服务端对 close 未必立即断开,等待 EOF 会白白耗到超时。

自研客户端时: 每个请求新建连接、带 Connection: close、读完 Content-Length 声明的长度即关闭。 这三步是稳定的关键,比复用连接池更重要。

响应信封

所有接口返回同一结构,便于统一处理:

status 仅取 success / error;code 在成功时为 null,失败时为字符串错误码; 业务数据一律放在 result 中,即使失败也可能带有部分上下文(如错误原因 result.error)。

参数规范

params 是一个按位置排列的字符串数组,而不是对象。这带来两个必须遵守的规则:

  • 顺序即语义:不同接口同一位置的含义不同,调用前请核对接口详情页的参数表。
  • 尾部空串自动裁剪:None 会被转为空串并从尾部裁掉,因此 call("X", ["a", None]) 与 call("X", ["a"]) 等价。但中间的空串不会被裁掉,需要占位时请显式传 ""。

地址的写法

地址类参数(address / func_addr / at / base)按字符串下发,int 与 "0x…" 两种写法服务端都能接受,客户端仅在 validate_hex_address() 中把它们规范化:

地址串中的空白字符与转义空白标记(\t、\r、\n、\v、\f)在 validate_hex_address() 与 _addr() 中会被自动移除,避免长地址在传输或复制过程中被截断;_addr() 遇到无法解析的地址会抛 ValueError,而各接口方法本身只做最小化的字符串转换(str(base) 等),不会主动校验地址。

语言 ID

形如 x86:LE:64:default:gcc,由「处理器 : 字节序 : 位数 : 变体 : 编译器」构成。Open 与字节流类接口的 language 参数可省略(自动识别)或显式指定(强制覆盖)。枚举全部可用 ID 请调用 ListLanguages。

返回模式:str 与 json

客户端 Config(response=…) 支持两种模式,避免调用方重复解析:

会话管理

会话是引擎的核心隔离单元:每个会话持有独立的镜像、分析结果、重命名、注释、补丁与覆写状态。多个会话可以并行存在,互不干扰。

生命周期

关闭会话时的陷阱

服务端解析“目标会话”的优先级为:请求 session 字段 > params[0] > 当前会话。若客户端已绑定了 config.session,直接把目标 ID 放进 params[0] 会被当前的 session 字段覆盖,从而误关其它会话。官方客户端为此把目标 ID 显式写进 session 字段:

状态持久化

SessionSave 可把种子、标号、equates、补丁等状态导出为 JSON(path 为空则内联返回),SessionLoad 从文件或内联 JSON 恢复,前提是已装载同一镜像。适合长任务断点续跑与结果归档。

direct 与 session 的区别

引擎的接口注册表对每个接口声明了 mode。这是调用前最需要确认的一件事:

call() 的 mode 参数可选,用于与服务端注册表做双重校验; 不传时服务端按注册表行为处理 —— 会话域缺 session 即返回 E_SESSION_REQUIRED。 在 接口文档 中,每个接口名前的 D / S 标记即对应上述两类。

推荐分析流水线

面向上千个样本批量处理时,建议按下面的顺序组织调用,兼顾质量与开销:

每一步都可以单独取用 —— 比如只做架构识别(IdentifyArchitecture,direct),无需装载完整镜像即可完成样本归类。

错误码

失败响应的 code 字段是唯一稳定的判定依据,请勿依赖 result.error 的文案内容。

错误码层级含义与处理建议
E_SERVER_UNAVAILABLE客户端TCP 探测失败,引擎进程未启动或端口不通。检查服务是否在 8000 端口监听。
E_CONN_REFUSED传输连接被拒绝。目标地址 / 端口错误,或防火墙拦截。
E_TIMEOUT传输请求超时。重接口(Open、AnalyzeAll、BatchDecompile)建议单独调大 timeout。
E_REQUEST_FAILED传输其它传输层异常,result.error 含具体原因。
E_SESSION_REQUIRED业务会话域接口未提供 session_id。先调用 Open 或 SessionCreate。
E_READONLY业务只读模式下尝试写操作,如 PatchBytes 在只读会话中被拒。
建议: 客户端已内置 check_server_available 装饰器,调用前做一次带 TTL 缓存的 TCP 探测(默认 probe_ttl=10s), 引擎宕机时快速失败而不阻塞 —— 这一点在 Agent 循环调用中尤其重要。

自描述与 OpenAPI

引擎可自我描述,无需手工维护契约文档:

  • GET / → 返回 plugin_info:版本、接口总数、会话 TTL、interface_modes 与支持的语言列表。客户端对应 server_info()(返回原始字符串)与 server_info_json()(返回 dict)。
  • GenerateOpenAPI(direct)→ 实时生成 OpenAPI 契约,可直接导入 Postman / Swagger UI。客户端 generate_openapi() 默认返回 JSON 字符串,落盘前无需再序列化。
  • HealthStats(direct)→ 运行期统计:请求数、耗时、错误数,用于容量观测。
注意: 除 server_info_json() 外,其余方法在默认 response="str" 下都返回 JSON 字符串;要直接取字段请用 parse_response() 解析,或在构造客户端时传 Config(response="json")。

最佳实践

1. 会话按任务而非按请求创建

分析一个样本的多个函数应当在同一个会话内完成 —— 反编译结果、类型推导与交叉引用是相互增强的。为每个函数新建会话会显著降低输出质量。

2. 批量场景用批量接口

需要多个函数的伪代码时,用 BatchDecompile / BatchSession 传入地址 JSON 数组,比逐条 Decompile 减少往返开销。

3. 先修正,再反编译

遇到间接跳转误判时,OverrideAdd、OverrideFlow、OverrideProto 能显著改善后续输出;符号缺失时,PdbLoad / DwarfLoad / FidbMatch 注入种子与签名会带来质量跃升。

4. 用仿真验证假设

Emulate / EmulateEx / EmulateWatch 可对函数做字节级仿真与单步观察,用于验证解密算法、解包逻辑等关键路径,而无需真正执行样本。

5. 始终处理空结果

剥离符号的样本上,类型表、导出表、字符串表可能为空。业务代码应把“空”与“失败”区分开:前者是 status=success 但 result 为空集合,后者才是 status=error。