AI LLM大模型逆向环境搭建radare2 + r2mcp + r2ghidra
需求
一般现在流行的LLM大模型逆向分析环境为IDA + MCP或者Ghidra + MCP环境,需要在PC端安装IDA或Ghidra客户端软件,通过MCP Server与本地的IDA或Ghidra交互。
有没有一种直接上传可执行文件,本地只需要一个AI客户端就能进行AI逆向分析的环境?
经过一段时间的研究,理论上比较完美的就是使用IDA Pro的Linux版本,结合MCP Server实现。但Linux版本的IDA Pro没有找到破解版,又不愿意花钱,放弃。
后来看到radare2逆向分析软件,支持Linux平台,支持命令行进行操作,于是拿radare2开刀。
Radare2简介
Radare2(简称 r2)是一个开源的逆向工程框架,用于分析、调试、破解和修改二进制文件。它功能强大,跨平台支持(Windows、Linux、macOS 等),广泛应用于软件逆向、漏洞研究和恶意软件分析等领域。
主要特点
-
模块化设计:Radare2 采用插件化架构,支持多种文件格式(如 ELF、PE、Mach-O)、架构(如 x86、ARM、MIPS)和分析功能。
-
多功能工具集:
-
反汇编:支持多种指令集,生成可读的汇编代码。
-
调试:内置调试器,支持本地和远程调试。
-
二进制分析:自动识别函数、字符串、交叉引用等。
-
脚本支持:支持多种脚本语言(如 Python、Lua、JavaScript)自动化分析。
-
可视化:提供 ASCII 艺术风格的图形界面(如函数调用图)。
-
-
命令行驱动:核心是命令行工具,适合脚本化操作,同时有图形界面(如 Cutter)。
-
轻量高效:资源占用低,适合嵌入式设备分析。
radare2逆向分析工具的使用方法,感兴趣的可自行搜索或者问AI。
基本使用方法
- 打开一个可执行文件
r2 /root/test.exe
- 分析可执行文件
- 列出函数
- 反编译一个函数
Radare2 MCP Server简介
r2mcp是一个支持radare2的mcp服务器程序,用于与AI助手结合实现LLM逆向分析。
主要特点
- 目前仅支持stdin/stdout通信模型
- 提供基本的工具功能
- 无缝结合radare2进行逆向分析
- 将Radare2与AI助手直接集成
- 文档探索和检查
使用方法
r2mcp的安装使用文档参见Github上的ReadMe文档。
由于r2mcp仅支持MCP协议中stdio通信模型, 并不支持SSE或StreamableHTTP模型,并且我们希望所有的分析软件都安装在Linux系统中。因此需要额外的工具进行中继或代理。这里介绍两种代理工具 mcpo 和 mcp-proxy。
mcpo是一种OpenAPI-compatible模式下的mcp代理工具,通过HTTP协议通信。
mcp-proxy是一种将stdio通信模型转换为SSE或StreamableHTTP通信模型的工具。
通过这2个工具中其中一个,就可以实现在AI客户端远程使用Linux上的逆向分析软件radare2。
mcpo配置与使用
启动mcpo的命令如下
mcpo -- r2pm -r /usr/local/bin/r2mcp
其中mcpo是代理工具,r2pm是radare2的包管理工具,r2mcp是radare2的mcp服务器程序。命令执行成功后,会列出r2mcp server支持所有功能,以及mcpo代理监听的服务器地址和端口号,可以通过chrome等浏览器远程访问mcpo服务,如下图所示:
同时,可以通过浏览器访问执行r2mcp提供的功能,如openFile、listFunctions、decompileFunction等操作对可执行文件进行手动的分析调试。
上面虽然实现手动的使用radare2进行逆向分析,要实现与AI的结合,需要一个支持OpenAPI-compatible接口的AI助手客户端,这里使用opeb-webui + ollama来实现这一功能。
mcp-proxy配置与使用
mcp-proxy安装成功后,使用下面命令启动MCP代理
mcp-proxy --host 0.0.0.0 --port 8088 -- r2pm -r /usr/local/bin/r2mcp
这次使用vscode + cline来作为AI客户端进行逆向分析
在cline中增加mcp配置如下
{ "mcpServers": {
"radare2": {
"timeout": 60,
"type": "stdio",
"command": "mcp-proxy",
"args": [
"http://10.0.0.100:8088/sse"
] }
}
运行效果如下
r2ghidra配置与使用
由于radare2自动的反编译工具pdc不是很好,这里增加使用ghidra反编译器pdg来进行逆向分析,r2ghidra的安装也很简单,按照使用说明介绍安装即可
安装完成后,使用pdc与pdg的反编译对比
pdc反编译
pdg反编译
使用pdg反编译的函数更接近C语言风格,方便分析查看。
当使用r2mcp进行反编译时,发现并没有pdg命令,原因是r2mcp默认没有加载r2ghidra插件,需要修改r2mcp代码加载该插件
static bool load_plugins(void) {if (!r_core) {R_LOG_ERROR ("Load core_ghidra.so failed, r_core == NULL.");return false;}// 设置调试模式以查看加载错误(当cfg.debug==true时会导致反编译结果错误)// 输出警告:When cfg.debug is set, I refuse to create a fake stack// r_config_set(r_core->config, "cfg.debug", "true");// 指定插件路径(替换为实际路径)const char *plugin_path = "/root/.local/share/radare2/plugins/core_ghidra.so";// 加载 core_ghidra.so 插件int ret = r_lib_open(r_core->lib, plugin_path);if( ret == -1 ) {R_LOG_ERROR ("Load core_ghidra.so failed.");return false;}R_LOG_INFO ("Load core_ghidra.so OK!");return true;
}static void r2_settings(RCore *core) {r_config_lock (core->config, false);r_config_set_i (core->config, "scr.color", 0);r_config_set_b (core->config, "scr.utf8", false);r_config_set_b (core->config, "scr.interactive", false);r_config_set_b (core->config, "emu.str", true);r_config_set_b (core->config, "asm.bytes", false);r_config_set_b (core->config, "anal.strings", true);r_config_set_b (core->config, "asm.lines", false);r_config_set_b (core->config, "anal.hasnext", true); // TODO: optionalr_config_set_b (core->config, "asm.lines.fcn", false);r_config_set_b (core->config, "asm.cmt.right", false);r_config_set_b (core->config, "scr.html", false);r_config_set_b (core->config, "scr.prompt", false);r_config_set_b (core->config, "scr.echo", false);r_config_set_b (core->config, "scr.flush", true);r_config_set_b (core->config, "scr.null", false);r_config_set_b (core->config, "scr.pipecolor", false);r_config_set_b (core->config, "scr.utf8", false);r_config_set_i (core->config, "scr.limit", 16768);r_config_set_i (core->config, "bin.baddr", 0x140000000);r_config_set_b (core->config, "r2ghidra.casts", false); // 启用类型转换r_config_set_b (core->config, "r2ghidra.cmt.cpp", true); // 使用 C++ 风格注释r_config_set_i (core->config, "r2ghidra.cmt.indent", 4);r_config_set_i (core->config, "r2ghidra.indent", 4); // 设置缩进为 4 个空格r_config_set_i (core->config, "r2ghidra.linelen", 120);r_config_set_i (core->config, "r2ghidra.maximplref", 2);r_config_set_i (core->config, "r2ghidra.roprop", 0);r_config_set_i (core->config, "r2ghidra.timeout", 0);r_config_set_b (core->config, "r2ghidra.vars", false);r_config_set_b (core->config, "r2ghidra.rawptr", true);r_config_set_b (core->config, "r2ghidra.verbose", false); // 启用详细警告r_config_set (core->config, "r2ghidra.sleighhome", "/root/.local/share/radare2/plugins/r2ghidra_sleigh"); // 设置 Sleigh 文件路径r_config_set (core->config, "r2ghidra.lang", ""); // 设置处理器语言
}
可以通过在浏览器中访问上面mcpo提供的web服务,手动执行查看是否r2ghidra插件安装成功
当返回结果中存在pdg时,说明r2ghidra反编译插件加载成功。这里的runCommand命令在r2mcp源码中已经存在,只是被宏注释掉了,删除宏注释重新编译r2mcp即可。
最终分析的结果如下,相对接近真实代码逻辑。
这里使用的LLM模型为本地部署的ollama + 千问的大模型,如果使用全量的大模型,分析效果更佳。