本节摘要:r2ai 是 radare2 官方的 LLM 插件(约 490 stars,MIT,社区口径 2026-10),装进 r2 会话只需
r2pm -Uci r2ai一条命令。本节先接通模型后端:本地 Ollama 或云端(OpenAI / Anthropic 等)任选,配置各一条命令,后端选择的第一原则是样本敏感度。然后逐个上手四个预设角色:explain 让模型解释当前函数(读的是你屏幕上的同一个函数)、autoname 自动命名(写回 r2 会话,含批量用法,需复核导出)、vulns 做漏洞模式巡查(仅限授权对象,产出是线索不是结论)、decompile 辅助把反汇编重写成近似 C(可读性换正确性)。每个角色给会话示例与产出形态,最后一张对照表总结输入、输出与复核要求,外加一张常见坑表。会话与参数为写法示意,以 r2ai 官方 README 为准。
# bash —— 安装 r2ai 并配置模型后端(写法示意,以 r2ai 官方 README 为准) r2pm -Uci r2ai # 更新包索引并安装插件 r2 -A bin/demo_stripped [0x00401090]> r2ai -m ollama/qwen2.5-coder # 本地后端(模型名示意) # 云端后端改为相应模型名并按官方文档配好密钥环境变量 [0x00401090]> r2ai hello # 连通性自检:模型能回话即通
| 后端 | 配置要点 | 适用 |
|---|---|---|
| Ollama 本地 | 本机起服务,模型名直接引用 | 敏感样本、离线环境 |
| OpenAI / Anthropic 云端 | 密钥进环境变量 | 公开 CTF 与自编译样本,要质量 |
| 自定义端点 | 兼容 OpenAI 接口的内部网关 | 团队统一出口 |
后端选择的第一原则在装之前就要想清楚:样本内容会进提示词。 自编译程序与公开 CTF 样本随便选;涉及敏感内容一律本地(第 0.2 节铁律,4.2 节展开取舍表)。
模型档位的实用建议:解释与巡查类任务(explain、vulns)对模型要求中等,本地中档模型够用;autoname 与 decompile 对「读得准」要求高,值得用你能拿到的最强模型。同一会话里也可以按任务切后端——先用强模型命名,再用便宜模型解释,成本与质量两头兼顾。
r2ai 的角色机制本质是预设的系统提示词加输出约定:切角色不需要换模型,一条命令的事。角色之外的一切普通对话仍然可用——角色是「戴帽子的提问」,不是功能的边界。
最常用的角色。它把当前光标所在函数的反汇编与上下文交给模型,换回一段解释:
# bash —— explain 角色会话(示意,输出有删节) [0x00401090]> s 0x00401189 # 定位到第 2.1 节认出的去混淆函数 [0x00401189]> r2ai -e role=explain [0x00401189]> r2ai 这个函数在做什么? 模型:循环逐字节取输入,与 0x5a 异或后写入输出缓冲,至遇 0 结束; 典型 XOR 去混淆。依据:循环体含 xor 指令,常量 0x5a,边界为 0。
复核动作固定两条:模型提到的常量(0x5a)在 pdf 输出里肉眼可查;提到的边界条件与跳转指令对得上。解释角色只读不写,是四个角色里最安全的起点。提问技巧:把「它在做什么」拆成「输入是什么、输出是什么、对每个字节做什么」三问,答案更贴证据。
autoname 对当前函数(或批量对无名函数)给出候选名并写回 r2 会话:
# bash —— autoname 角色会话(示意) [0x00401160]> r2ai -e role=autoname [0x00401160]> r2ai 给这个函数起个名 模型:建议 check_license_key(依据:解码后与参数 strcmp)。 已将会话内函数改名为 check_license_key。 [0x00401160]> afl # 复核:看会话里的名字列表
批量形态(示意):对会话里全部 fcn. 开头的无名函数跑一轮,aflj 导出改名结果,再进人工复核。
# bash —— 批量命名与导出(写法示意) [0x00401090]> r2ai -e role=autoname [0x00401090]> r2ai 给所有无名函数起名,保守命名,不确定的保留原名 [0x00401090]> aflj > /tmp/names.json # 导出供复核与回写
三个纪律:其一,autoname 的改名只在本会话生效,退出即失——要落盘就走导出 JSON 加回写(Ghidra 侧用第 3.3 节的 apply_names.py 思路);其二,名字采纳前对照反汇编核它的「依据」,错名字比没名字更害人;其三,批量自动命名后必须抽样复核——这与第 3.3 节命名建议的闸门完全同构,「保守命名、不确定的保留原名」这句指令能把误伤率压下去一截。
会话产物的管理也别偷懒:r2 会话里的名字、注释不会自己长存——结束前做一次「收割」:aflj 导出名字清单、关键结论抄进笔记(或第 4.3 节的报告 JSON)。养成这个习惯,r2ai 的会话才从「聊完就散」变成「理解累积」。
vulns 角色让模型按漏洞模式巡查当前函数或一段代码,产出「模式 + 位置 + 理由」的清单。 用之前先划边界:只对授权对象使用(自编译、CTF、开源),它给的是线索不是结论——每条线索都要人顺着引用链核实。对 demo_stripped 的 check 类函数,典型产出是「无边界检查的栈缓冲区」一类提示,是否成立要看调用约定与实际输入长度。
# bash —— vulns 与 decompile 角色会话(示意) [0x00401160]> r2ai -e role=vulns [0x00401160]> r2ai 巡查这个函数的潜在问题 模型:expected 缓冲区 32 字节,deobfuscate 的输入若超长可能越界写; 位置:写入循环;建议核对 DAT 的实际长度与写入边界。 [0x00401189]> r2ai -e role=decompile [0x00401189]> r2ai 重写成 C 模型:输出一段近似 C 的循环代码(结构对,变量类型为推断)。
decompile 角色让模型把反汇编重写成近似 C。 它的产出与 Ghidra 反编译器、r2 内置 pdc 是同族但不同源,三种伪代码来源摆在一起看:
| 来源 | 特点 | 用途定位 |
|---|---|---|
| Ghidra 反编译 | 结构稳、类型推断强 | 证据链首选 |
| r2 内置 pdc | 快、朴素 | 会话内快速核对 |
| r2ai decompile | 可读性常更好、正确性无保证 | 辅助人读,不进证据链 |
用法定位是「辅助人读」,不是「替代反编译器」;要进证据链的伪代码,用工具产出的那份。
| 角色 | 输入 | 产出 | 写回会话 | 复核要求 |
|---|---|---|---|---|
| explain | 当前函数反汇编与上下文 | 中文解释加依据 | 否 | 常量与跳转肉眼对 |
| autoname | 当前 / 批量无名函数 | 候选名加理由 | 是(会话内) | 逐个看依据;批量抽样 |
| vulns | 当前函数 | 模式加位置加理由 | 否 | 每条线索顺引用核实 |
| decompile | 当前函数反汇编 | 近似 C 代码 | 否 | 只作辅助阅读,不进证据链 |
| 常见坑 | 现象 | 解法 |
|---|---|---|
| 后端没配好 | r2ai 无响应或报模型错误 | 先跑 r2ai hello 自检 |
| 角色串台 | 输出格式不对 | 每次切角色显式 -e role= |
| 上下文太长 | 解释只覆盖函数前半 | 只喂目标函数,长函数分段 |
| 名字污染 | 批量改名错一片 | 「保守命名」指令 + 抽样 + 导出复核 |
| 会话没收割 | 退出后成果全丢 | 结束前 aflj 导出 + 结论入笔记 |
| 巡查当结论 | 把 vulns 清单直接写进报告 | 每条线索核实后才可升级(第 0.1 节三级分层) |
四个角色都是「单轮人机问答」——人发令、模型答。够快,但每一步都要人推。下一节松开手:ReAct 模式让模型自己决定发哪条 r2 命令。
手动挡用顺了,就会想要自动挡。下一节进入 ReAct 模式:模型自己思考、自己发命令、自己读结果,外加一个装着全部函数的本地 RAG 向量库。