r2pipe2 协议 RFC 解读:radare2 下一代 JSON 管道通信协议的设计草案
2026/9/20 23:50:24 网站建设 项目流程

r2pipe2 协议 RFC 解读:radare2 下一代 JSON 管道通信协议的设计草案

【免费下载链接】radare2UNIX-like reverse engineering framework and command-line toolset项目地址: https://gitcode.com/gh_mirrors/ra/radare2

radare2 的 r2pipe 机制(r2pipe1)通过管道、环境变量文件描述符或 HTTP 通道,让外部程序向 radare2 实例发送命令并取回输出。doc/r2pipe2.md是维护者 pancake 撰写的一份 RFC 草案,提出以 JSON 为载体的下一代协议 r2pipe2,以解决阻塞式执行、stderr/日志不可捕获、无返回码、难以扩展元数据等既有限制。本文以该草案为核心,逐条解读其需求、握手与命令执行设计,并结合仓库中 r2pipe1 的实际实现源码进行对照,帮助读者理解这套协议演进的动机、报文格式与迁移思路。

背景:r2pipe1 的现状与局限

在进入草案之前,先明确 r2pipe1 在仓库中的真实形态,这有助于理解 r2pipe2 为什么要重新设计。r2pipe1 的核心实现位于 libr/socket/r2pipe.c,对外 API 声明在 libr/include/r_socket.h(其中保留了r2p_cmdr2p_openr2p_close等旧名宏以兼容 yara-r2 等历史调用方)。

其通信模型建立在fork + 匿名管道之上:r2pipe_open创建两组管道(input[2]output[2]),通过R2PIPE_IN/R2PIPE_OUT两个环境变量把文件描述符编号传给子进程,然后子进程把 stdin/stdout 重定向到这两个 fd 上执行目标命令:

env ("R2PIPE_IN", r2p->input[0]); env ("R2PIPE_OUT", r2p->output[1]); ... dup2 (r2p->input[0], 0); dup2 (r2p->output[1], 1); rc = r_sandbox_system (cmd, 1);

(见 libr/socket/r2pipe.c)。发送命令时r2pipe_write会在命令尾部追加换行符\n,读取时r2pipe_read逐字节阻塞读入直到遇到 NUL 字节或管道结束(libr/socket/r2pipe.c)。这种"发送一行、阻塞等待、读到 NUL 结束"的模式正是草案中所说的"well known communication channels"。

与此配套的还有几个关键设施:

  • 链接模式:radare2 可被直接以r2p名字调用,读取R2PIPE_IN/R2PIPE_OUT环境变量并逐条执行参数命令(binr/radare2/radare2.c),用法如r2 -c '!*r2p x'
  • IO 插件r2pipe://URI 插件把管道另一端当成一个可读写 seek 的 IO 设备,其__system已经用PJ(radare2 的 JSON 构造器)发送{"op":"system","cmd":...}之类的 JSON 报文(libr/io/p/io_r2pipe.c);
  • 测试客户端:libr/io/p/io_r2pipe-test.js 演示了 Node.js 侧如何从R2PIPE_IN/R2PIPE_OUT读取 JSON 请求并以\x00结尾写回响应;
  • HTTP 模式r2pipe_openhttp://https://r2web://前缀会走r_socket_http_post通道(libr/socket/r2pipe.c),配合 doc/r2pipe.html 所示的 Web 前端r2.cmd()回调用法。

在这些机制上,草案明确指出当前协议(r2pipe1)的痛点:

  • 命令执行是阻塞式的,无法并发发起多条命令;
  • stderr 消息无法捕获,诊断信息会丢失或混入 stdout;
  • 日志无法捕获,内部 logging 与命令输出混杂;
  • 没有与命令绑定的返回码,调用方难以判断成功失败;
  • 协议不可扩展元数据,任何附加信息都没有标准位置安放。

设计目标:五条硬性需求

r2pipe2 草案开门见山地列出新协议必须满足的需求,这也是评估后续设计的验收标准:

  1. 非阻塞命令执行(non-blocking command execution);
  2. 捕获 stderr 消息
  3. 捕获日志(logging);
  4. 关联返回码(return code associated);
  5. 可扩展元数据(extensible with metadata)。

可以看到,这五条全部指向"把通道从纯字节流升级为结构化、可寻址的消息流"——只有报文自带命令标识、输出分类字段和元数据槽位,才能同时满足非阻塞、分流 stderr/日志、携带返回码与扩展信息。

总体方案:JSON 报文 + 复用既有通道

草案的提议非常务实:定义一套基于 JSON 的新协议,但继续使用既有的通信通道(管道、HTTP 等)来收发命令与输出。这样无需引入新的传输层,已有的连接建立、文件描述符传递、Web 部署方式都可以直接复用。

协议版本探测则通过首字节完成。r2pipe1 在连接建立后第一个字符是 NUL 字节(\x00,如 libr/io/p/io_r2pipe-test.js 中响应以\x00结尾所对应的历史约定);r2pipe2 规定第一个字节改为左花括号{(JSON 对象的起始符)。这样一来:

  • 旧的 r2pipe1 客户端可以识别到{而知道对面是 r2pipe2 实例;
  • 新客户端也能判断对面是否支持 r2pipe2,从而自动选择协议版本;
  • 向后兼容得以在协议层天然解决,无需额外的协商开关。

握手(Handshake):协议版本与对端信息

连接建立后,双方先进行一次握手,交换协议标识与对端信息。草案给出了客户端与服务端的完整示例。

客户端(>>>>>>>表示发往服务端方向)发送:

{ "protocol": "r2pipe", "version": "2.0" }

服务端(<<<<<<表示返回给客户端)应答:

{ "protocol": "r2pipe", "peer": { "name": "radare2", "version": "5.9.0" } }

握手报文结构解读:

字段位置含义
protocol顶层固定为"r2pipe",标识协议族
version顶层(请求)客户端声明的协议版本,示例为"2.0"
peer顶层(应答)对端(服务端)的标识对象
peer.name应答服务端程序名,示例为"radare2"
peer.version应答服务端版本号,示例为"5.9.0"

peer对象的设计为后续扩展留出了空间——服务端可以在此补充架构、能力列表(capabilities)等元数据,而不会破坏既有字段的解析。

运行命令:请求、响应与 seqid

握手完成后的命令交互采用"请求-响应"模式。客户端请求示例:

{ "command": "ij", "expect": "text/json", "seqid": 1 }

请求字段说明:

  • command:要执行的 radare2 命令字符串,示例为ij(输出 JSON 格式的文件信息);
  • expect:期望的输出类型,示例"text/json"表示希望以 JSON 文档而非字符串形式接收输出;
  • seqid序列号(sequence id),由客户端自增分配,用于把响应与请求一一对应。

草案特别强调:当客户端请求了 JSON 响应时,输出会被内嵌进返回文档(structured output),而不是以字符串整体返回——这是 r2pipe2 与 r2pipe1 在响应形态上的根本差异之一。

服务端响应示例:

{ "responses": [{ "seqid": 1, "command": "ij", "time": 3824, "logs": "", "stderr": "invalid file", "output": { "core": { "type": "Executable file", "file": "/bin/ls", "fd": 4, "size": 9488 }, "bin": { "arch": "arm", "baddr": 4294967296, "binsz": 88816, "bintype": "mach0", "bits": 64, "canary": true } } }] }

(原草案中"logs: ""缺一个引号、peer"version"前缺逗号,本文按 JSON 语法修正,语义不变。)

响应报文是一个数组容器responses,其中的每个元素代表一条命令的执行结果,字段设计恰好一一对应五项需求:

字段对应需求说明
seqid非阻塞执行与请求中的序列号对应,客户端据此在并发场景下匹配响应
command关联性回显触发该响应的命令原文
time元数据命令执行耗时(示例为毫秒级数值 3824)
logs捕获日志独立字段承载内部日志输出
stderr捕获 stderr独立字段承载标准错误输出(示例中为 "invalid file")
output结构化输出请求expect为 JSON 时内嵌结构化结果;示例展示了corebin两个子对象,对应ij命令输出的文件类型、路径、fd、大小以及架构、加载基址、二进制类型(mach0)、位宽(64)、canary 等分析信息

seqid 如何实现非阻塞

草案用一段话点明了seqid的核心价值:在后台运行命令时,客户端不必阻塞等待,可以连续发送多条命令,之后根据返回的seqid判断哪条响应属于哪条命令。由于响应是"请求-响应"对,理论上还可以实现乱序返回——慢命令晚回、快命令先回,各就各位地按seqid归队。相比 r2pipe1 中r2pipe_cmd一次写一行、阻塞读到 NUL 的同步模型(libr/socket/r2pipe.c),这是吞吐与并发的根本性改进。

对比 r2pipe1:从"字符串往返"到"文档往返"

把草案的请求/响应与 r2pipe1 的现有实现对照,差异非常直观:

  • 请求方向:r2pipe1 直接发送命令字符串(由r2pipe_write追加\n);r2pipe2 发送 JSON 对象,命令被包进command字段,并附带expectseqid等控制元数据;
  • 响应方向:r2pipe1 以 NUL 结尾的字符串整体返回,stderr/日志混在 stdout 中,无返回码;r2pipe2 以 JSON 文档返回,outputlogsstderrtime各归其位;
  • 出错处理:r2pipe1 中调用方只能靠r2pipe_read返回 NULL 感知失败(libr/socket/r2pipe.c);r2pipe2 中返回码可作为一个显式字段随响应下发,调用方按码判定。

值得一提的是,r2pipe1 生态中已经出现"用 JSON 包裹命令"的先例——IO 插件的__systemPJ构造{"op":"system","cmd":...}报文(libr/io/p/io_r2pipe.c),__read/__write也发送{"op":"read","address":...,"count":...}并解析resultdata字段。这说明社区早已在实践中验证了"JSON over pipe"的可行性,r2pipe2 草案正是把这种自发实践正式化、协议化,并补上seqidexpectlogsstderr、返回码等缺失维度。

兼容性与迁移路径

根据草案的表述,可以梳理出清晰的兼容策略:

  1. 首字节即版本信号:NUL 表示 r2pipe1、{表示 r2pipe2,两端通过读取首个字节即可分派到正确的解析器,协议可以并存;
  2. 传输层不变:fork+pipe、R2PIPE_IN/R2PIPE_OUT环境变量、HTTP/r2web POST 等通道继续沿用,只是报文内容从裸文本变为 JSON 文档;
  3. 响应容器化:所有响应统一放进responses数组,即便单条命令也返回数组(示例中只有一个元素),这为未来批量命令、流式/分帧输出预留了结构;
  4. 元数据可扩展peerresponses元素都允许追加新字段,老客户端忽略未知字段即可,新字段不需要变更协议版本号。

需要说明的是,doc/r2pipe2.md明确是RFC 草案(draft),并非已落地的实现:仓库中目前不存在protocol: "r2pipe"version: "2.0"握手逻辑的代码。文中的协议细节以草案为准,实现在未来版本中可能依据 RFC 反馈而调整。读者如果希望动手验证既有 r2pipe1 的报文形态,可参考 libr/io/p/io_r2pipe-test.js(Node.js 端读取R2PIPE_IN/R2PIPE_OUT的完整示例)与 binr/radare2/radare2.c(r2p链接模式入口)。

总结

doc/r2pipe2.md为 radare2 的进程间通信协议勾勒了一幅清晰的演进蓝图:以 JSON 为报文格式、复用既有管道与 HTTP 通道、用首字节{替代 NUL 完成版本探测、以seqid支撑非阻塞并发,并通过output/logs/stderr/time等字段分别承接结构化输出、日志、错误与执行元数据,同时为返回码与任意扩展信息预留位置。这一设计直接回应了 r2pipe1 在 libr/socket/r2pipe.c 中所体现的"一行命令 + 阻塞读 + NUL 结尾"模型的全部短板,也为 r2pipe 协议后续的工程化落地提供了可供评审与实现的基础。

【免费下载链接】radare2UNIX-like reverse engineering framework and command-line toolset项目地址: https://gitcode.com/gh_mirrors/ra/radare2

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询