mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
6183 字
31 分钟
当反编译遇上多智能体:我为什么要设计一个全程序级源码还原系统RE-MAS

一、背景:AI 反编译已经走到哪了?#

2024 年以来,LLM 在二进制反编译领域取得了一系列突破。如果你还停留在”Ghidra 输出的伪代码勉强能看”的印象,那可能需要更新认知了。

1.1 LLM4Decompile:第一个开源反编译大模型#

LLM4Decompile(EMNLP 2024)是第一个专门为反编译训练的开源 LLM 系列,参数规模从 1.3B 到 33B。它提供了两种模式:

  • End 模式:直接从汇编代码生成 C 源码
  • Ref 模式:接收 Ghidra 的伪代码输出,精炼为更高质量的 C 代码

HumanEval-Decompile benchmark 上,LLM4D 的 re-executability(反编译结果能否重新编译并正确执行)比 Ghidra + GPT-4o 高出 100%以上。V2 版本(6.7B-Ref)在该指标上达到约 52.7%,9B 模型更是达到了 64.9%。

1.2 SK²Decompile:骨架与皮肤的分离#

SK²Decompile(2025,已提交 ICLR 2026)提出了一个优雅的解耦思路——将反编译分为两个独立阶段:

  1. Skeleton(骨架恢复):将二进制翻译为中间表示,保留控制流和数据结构,但把所有标识符替换为通用占位符
  2. Skin(表皮命名):为占位符生成有语义的标识符名称

两个阶段分别用强化学习训练,Skeleton 模型被奖励产出语法正确的结构,Skin 模型被奖励语义相似度。在 HumanEval 上 re-executability 比 GPT-4-mini 高 21.6%。

1.3 DecLLM:让反编译结果能编译#

DecLLM(ISSTA 2025)关注的是另一个维度——可再编译性(recompilability)。它的核心思路是迭代修复:

Ghidra 伪代码 → LLM 修复 → 尝试编译 → 收集错误 → 再修复 → ...

用 GPT-4 驱动这个循环,约 70% 的原本不可编译的 Ghidra 输出可以被修复为可编译版本。这对 CodeQL 等需要可编译代码的漏洞分析工具非常有价值。

1.4 ReCopilot:二进制分析领域特化模型#

ReCopilot(2025.05,奇安信研究院)走的是领域特化路线——通过 CPT(继续预训练)→ SFT(有监督微调)→ DPO(直接偏好优化)三阶段训练一个专门的二进制分析模型。它支持反编译、函数名恢复、变量类型推断、结构体恢复等多个任务,在函数名恢复上比通用 LLM 高 13%

值得注意的是,ReCopilot 已经引入了 data flow(数据流)和 call graph(调用图) 作为额外上下文来增强跨函数感知能力。但论文也明确指出:“建立超长思维链推理存在显著挑战”

1.5 其他值得关注的工作#

项目来源关键贡献
ReF Decompile2025跳转地址重标记 + 函数调用类型推断,HumanEval 61.43%
ReSymCCS 2024 杰出论文LLM + Prolog 算法恢复变量和结构体符号
REx862025基于 Qwen2.5-Coder-7B 的本地化 x86 逆向模型
TYGRUSENIX Security 2024GNN 做 stripped binary 的类型推断,76.6% 准确率
AgentRE-Bench2025首个逆向工程 Agent 标准化 benchmark

看起来成果很多?但如果你仔细看,会发现一个所有这些工作共享的根本局限


二、核心局限:函数是一座孤岛#

2.1 所有现有方案都是函数级的#

把上面提到的所有工作放在一起,你会发现一个惊人的事实:

它们全部都只能处理单个函数。

  • LLM4Decompile:输入是一个函数的汇编,输出是一个函数的 C 代码,max 4096 tokens
  • SK²Decompile:Skeleton 和 Skin 都在单函数范围内操作
  • DecLLM:修复循环只关心”这一个函数能不能编译通过”
  • ReF Decompile:同样的函数级端到端
  • ReCopilot:虽然引入了调用图上下文,但核心推理仍是逐函数进行

这意味着什么?

2.2 一个真实的例子#

假设你有一个网络服务器程序被编译为 stripped binary(所有符号信息被剥除)。程序里有这样的调用关系:

// 真实源码(你要恢复的目标)
struct connection_t {
int fd;
char *buffer;
size_t buf_size;
struct sockaddr_in peer_addr;
};
// 函数 A:创建连接
struct connection_t* create_connection(int port, const char *host) {
struct connection_t *conn = malloc(sizeof(struct connection_t));
conn->fd = socket(AF_INET, SOCK_STREAM, 0);
conn->peer_addr.sin_port = htons(port);
conn->peer_addr.sin_addr.s_addr = inet_addr(host);
connect(conn->fd, (struct sockaddr*)&conn->peer_addr, sizeof(conn->peer_addr));
conn->buffer = malloc(4096);
conn->buf_size = 4096;
return conn;
}
// 函数 B:发送数据(依赖函数 A 创建的 connection_t)
int send_data(struct connection_t *conn, const char *data, size_t len) {
if (len > conn->buf_size) {
conn->buffer = realloc(conn->buffer, len);
conn->buf_size = len;
}
memcpy(conn->buffer, data, len);
return send(conn->fd, conn->buffer, len, 0);
}

现在用现有的函数级工具反编译。每个函数被独立处理

函数 A 的反编译结果(不知道 B 的存在):

// LLM4D 的输出——它不知道 struct connection_t 长什么样
void* sub_401234(int param_1, char *param_2) {
void *v1 = malloc(32); // 不知道是 struct connection_t
*(int*)v1 = socket(2, 1, 0);
// ... 一堆指针偏移操作 ...
return v1;
}

函数 B 的反编译结果(不知道 A 的存在):

// 独立反编译——同一个 struct 完全不同的理解
int sub_401500(long param_1, char *param_2, int param_3) {
if (param_3 > *(int*)(param_1 + 16)) { // buf_size 偏移猜测
// ...
}
return send(*(int*)param_1, *(char**)(param_1 + 8), param_3, 0);
}

看到问题了吗?

  1. struct connection_t 消失了:函数 A 和 B 都在操作同一个 struct,但各自用 void*long 加偏移量来理解它,没有任何人把它们统一起来
  2. 函数签名不一致:A 返回 void*,B 接收 long——实际是同一个类型
  3. 语义断裂:A 创建的连接是给 B 用的,但反编译时两个函数互相不知道对方的存在
  4. 组合后无法编译:即使每个函数单独”看起来对”,放到一个项目里各种类型冲突

这就是函数级反编译的根本局限——每个函数都是一座信息孤岛。

2.3 量化这个问题#

这不只是个理论问题。我整理了一下从函数级反编译到”完整可编译项目”之间的鸿沟:

需要解决的问题现有方案的覆盖缺口
单个函数的控制流恢复LLM4D, SK² 覆盖
单个函数的变量命名SK² Skin, ReCopilot 覆盖
跨函数的类型一致性无方案覆盖完全空白
全局变量的统一声明无方案覆盖完全空白
结构体定义的跨函数恢复ReSym 有初步尝试大部分空白
头文件依赖恢复无方案覆盖完全空白
项目级编译验证DecLLM 仅单函数项目级空白
函数间的调用签名一致性无方案覆盖完全空白
编译配置推断(Makefile)无方案覆盖完全空白

2.4 上下文窗口不是银弹#

你可能会想:“等 LLM 的上下文窗口足够大,把整个二进制的反汇编一次性塞进去不就行了?”

不行。原因有三:

1. 规模不现实。一个 1MB 的 stripped binary 反汇编后的文本量轻松超过 数百万行。即使 200K token 的模型也远远不够。

2. 注意力稀释。即使物理上塞得下,LLM 在超长上下文中的注意力分配是高度不均匀的——中间部分的信息几乎被忽略(这就是著名的 “Lost in the Middle” 问题)。

3. ReCopilot 的教训。ReCopilot 已经尝试把调用图和数据流塞进 prompt,但论文自己承认”超长思维链推理是主要瓶颈”。单模型在需要持续追踪数百个函数间依赖关系时,推理链会崩溃。

2.5 一张图总结现状#

处理粒度
函数级 ◄──────────► 全程序级
│ │
LLM4Decompile ────┤ │
SK²Decompile ─────┤ │
ReF Decompile ────┤ │
DecLLM ───────────┤ │
ReCopilot ────────┼──┐ │
│ │ │
│ (有限的跨函数) │
│ │
│ ❓这里是空白
│ │
单模型/管道 ◄──────────► 多智能体协作

所有现有工作都挤在左下角(函数级 + 单模型/管道)。右上角(全程序级 + 多智能体协作)是一片空白。


三、为什么多智能体是对的架构#

发现了问题,为什么我认为多智能体(Multi-Agent System)是正确的解决方向?

3.1 本质论证:任务分解#

“二进制 → 可编译项目”这个任务实际上包含了性质完全不同的子任务

子任务性质最适合的模型
ASM → C 翻译模式匹配 + 代码生成特化小模型(LLM4D 6.7B)
符号恢复(命名)语义推理 + 世界知识通用大模型(GPT-4/Claude)
类型系统统一约束求解 + 冲突裁决图算法 + LLM 辅助
编译修复错误诊断 + 代码修改代码专家模型
语义验证符号执行 + 等价性检查程序分析工具(angr)

用一个模型做所有事情,就像让一个外科医生同时做手术、做化验、读 CT、开处方——理论上可能,但远不如专业团队协作高效。

3.2 解决上下文窗口问题#

多智能体的杀手级优势在于将知识外化

单模型方案:所有信息必须塞进一个上下文窗口

[一个巨大的 prompt]
├── 函数 1 的反汇编 (2K tokens)
├── 函数 2 的反汇编 (3K tokens)
├── ...
├── 函数 200 的反汇编 (1.5K tokens)
├── 调用关系说明 (5K tokens)
├── 全局变量列表 (2K tokens)
├── 已知类型定义 (3K tokens)
└── 任务指令 (1K tokens)
= 远远超出上下文限制

多智能体方案:知识存储在外部图数据库,每个 Agent 按需查询

Agent A 处理函数 1 时的 prompt:
├── 函数 1 的 Ghidra 伪代码 (0.5K tokens)
├── [从 neo4j 查询] 函数 1 调用的 3 个函数的签名 (0.3K tokens)
├── [从 neo4j 查询] 函数 1 使用的 2 个全局变量的类型 (0.1K tokens)
├── [从 neo4j 查询] 相关的 1 个 struct 定义 (0.2K tokens)
└── 任务指令 (0.5K tokens)
= 仅 1.6K tokens,精准且充分

每个 Agent 只需要局部上下文,但可以通过共享知识库利用全局信息。这是单模型方案做不到的。

3.3 验证闭环天然适配#

在多 Agent 架构中,“生成者”和”验证者”是天然分离的:

反编译 Agent:我觉得这个函数返回 int
↓ 写入知识库
验证 Agent:编译器说调用者把返回值赋给了 char*,类型冲突
↓ 反馈
修复 Agent:根据调用上下文,应该返回 char*,修复

这种对抗性设计(一个生成,另一个验证)比单模型的”自己检查自己”更可靠。DecLLM 已经证明了迭代修复循环的价值(70% 的不可编译代码被修复),但它只在单函数级别做。多 Agent 架构可以将这个闭环扩展到项目级别

3.4 模型经济学#

一个被忽视的论点:成本

如果用 GPT-4 直接反编译一个 200 函数的程序:

  • 每个函数需要大量上下文 → 每个调用 ~10K tokens
  • 200 函数 × 10K = 2M tokens
  • 多轮修复 × 3 = 6M tokens
  • GPT-4 价格 ~3060/Mtokens30-60/M tokens → **180-360**

多智能体方案:

  • 反编译用 LLM4D-Ref 6.7B(本地部署,成本几乎为零
  • 只有符号恢复和修复用 GPT-4(~50K tokens)
  • 总计 API 成本 → $3-5

两个数量级的成本差异。

3.5 可扩展性#

明天如果需要支持 ARM 架构?或者 RISC-V?

  • 单模型方案:需要重新训练整个模型
  • 多 Agent 方案:只需替换/增加一个”ARM 反编译 Agent”,其余架构(关系恢复、验证修复、知识库)完全不变

四、RE-MAS:我的系统设计#

基于以上分析,我设计了 RE-MASReverse Engineering Multi-Agent System),一个面向全程序可再编译反编译的多智能体系统。

4.1 设计哲学#

三个核心原则:

  • 分而治之:将超复杂任务分解为 4 个专业子任务
  • 知识共享:所有 Agent 通过中心化的图数据库交换信息,而非直接通信
  • 迭代收敛:验证-修复闭环驱动结果逐步逼近可编译状态

4.2 整体架构#

┌─────────────────────────────────────────┐
│ Orchestrator (编排器) │
│ LangGraph StateGraph + 确定性状态机 │
└────┬────────┬──────────┬────────────┬───┘
│ │ │ │
┌────▼───┐┌───▼────┐┌────▼─────┐┌────▼─────┐
│Phase 0 ││Phase 1 ││Phase 2 ││Phase 3 │
│预处理 ││反编译 ││关系恢复 ││验证修复 │
│Agent ││Agent ││Agent ││Agent │
│ ││ ││ ││ │
│Ghidra ││LLM4D ││GPT-4 / ││GCC + │
│headless││-Ref ││Claude ││angr + │
│+ 分析 ││6.7B ││+ neo4j ││LLM │
└───┬────┘└───┬────┘└────┬─────┘└────┬─────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────┐
│ 共享知识库 │
│ neo4j (代码属性图 CPG) │
│ + SQLite (元数据与状态追踪) │
│ + 文件系统 (源码/头文件/编译产物) │
└─────────────────────────────────────────┘

4.3 Phase 0:预处理 Agent#

用途:把原始二进制文件”拆开”,建立初始知识库。

工具Ghidra headless analyzer

做什么

  1. 加载 ELF 二进制,自动分析
  2. 识别所有函数及其边界
  3. 提取静态调用图(谁调用了谁)
  4. 为每个函数生成 Ghidra 伪代码
  5. 识别全局变量、字符串常量、导入函数
  6. 将所有信息写入 neo4j(函数节点 + 调用关系边)和 SQLite(函数状态表)

关键设计——函数优先级排序:

优先级策略:修改逆拓扑排序(叶函数优先)
为什么?叶函数(不调用其他用户函数的函数)反编译时不依赖任何其他函数的信息,
结果最独立可靠。先反编译它们,就可以把它们的签名信息存入知识库,
供后续反编译其调用者时使用。
Batch 1: 叶函数 → 独立反编译,签名写入 CPG
Batch 2: 只调用 Batch 1 的函数 → 利用 Batch 1 的签名作为上下文
Batch 3: 调用 Batch 1+2 的函数 → 上下文更丰富
...
最后: main() → 拥有最完整的上下文

这类似于编译器做的事——先处理被依赖的,再处理依赖者。

4.4 Phase 1:反编译 Agent#

用途:将每个函数的 Ghidra 伪代码精炼为高质量 C 源码。

核心模型LLM4Decompile-Ref 6.7B V2(本地 GPU 部署)

关键创新——CPG 上下文增强

在发给 LLM4D 的 prompt 中,不只包含当前函数的 Ghidra 伪代码,还会从 neo4j 查询并注入:

  • 当前函数调用的所有已知被调用函数的签名(因为叶函数已经先反编译完了)
  • 当前函数使用的全局变量的类型信息
  • 当前函数访问的已知结构体定义
### Context:
// Known callee signatures:
int parse_header(const char *buf, size_t len);
void free_connection(struct conn_t *conn);
// Known global variables:
extern int g_verbose_level;
extern struct config_t *g_config;
// Known struct:
struct conn_t { int fd; char *buffer; size_t buf_size; };
### Ghidra Pseudo-Code:
undefined8 FUN_00401234(long param_1, int param_2) { ... }
### Refined C Code:

这样,即使是 6.7B 的小模型,也能利用全局信息做出更好的判断——因为它不需要自己”猜”被调用函数的签名,知识库已经告诉它了。

每个反编译结果还会被评估一个置信度分数(综合语法有效性、类型一致性、调用签名匹配度、模型 log probability),低置信度的函数会被标记为后续修复的优先目标。

4.5 Phase 2:关系恢复 Agent#

用途:将一堆独立的函数级反编译结果整合为一个完整的项目。

核心模型:GPT-4 / Claude(需要强语义推理能力)

这是整个系统中最核心、最有创新性的环节。它需要完成 5 个子任务:

子任务 1:类型系统统一

同一个 struct 在不同函数中可能被理解为不同的东西。例如函数 A 看到 void* 加偏移操作,函数 B 看到 struct foo*。需要:

  • 收集所有函数中出现的类型信息
  • 通过图上的约束传播合并等价类型
  • 冲突时交给 LLM 裁决(给出两个函数的完整代码和调用上下文,让 LLM 判断哪个更正确)

子任务 2:符号恢复(函数名、变量名)

分三层逐步推理:

  • 第一层(确定性):导出符号表有名字的直接用;调用 printfmalloc 等标准库函数可推断参数名
  • 第二层(模式匹配):函数里调 socket + bind + listen + accept → 命名为 setup_server
  • 第三层(LLM 深度推理):把函数代码 + 调用图上下文发给 GPT-4,推断语义化的名字

子任务 3:模块划分

用 neo4j 内置的 Louvain 社区检测算法 在调用图上做聚类。紧密调用的函数被划分到同一个 .c 文件中。main() 单独一个文件,被多个模块调用的工具函数放到 utils.c

子任务 4:头文件生成

  • types.h:所有自定义结构体和类型定义(按依赖顺序排列)
  • globals.h:全局变量的 extern 声明
  • prototypes.h:非 static 函数的原型声明
  • 标准库 #include:维护一张 ~500 条的库函数 → 头文件映射表printf → <stdio.h>socket → <sys/socket.h> 等)

子任务 5:项目组装

将以上所有结果组装为完整项目:多个 .c 文件 + 头文件 + 自动生成的 Makefile

4.6 Phase 3:验证修复 Agent#

用途:发现并修复反编译结果中的错误,形成迭代闭环。

工具:GCC(编译验证)+ angr(符号执行语义验证)+ LLM(智能修复)

四层验证体系,从快到慢、从粗到细:

Level 1: 语法验证 (tree-sitter, < 1秒)
✓ → Level 2
✗ → 规则修复(缺分号、括号不匹配等,无需 LLM)
Level 2: 编译验证 (GCC, < 10秒)
✓ → Level 3
✗ → 结构化错误解析 → 分类(5类错误) → 对应修复策略
Level 3: 语义验证 (angr 符号执行, 分钟级)
✓ → 完成
✗ → LLM 深度推理修复
Level 4: 行为验证 (编译+运行对比, 可选)
对比反编译程序和原始二进制在相同输入下的输出

编译错误被分为 5 类,每类有不同的修复策略:

类型示例修复方式
E1 语法错误缺分号、括号不匹配规则修复,不用 LLM
E2 类型错误指针/整数混用查 CPG 该变量在其他函数中的类型,取更一致的
E3 声明缺失函数/类型/变量未声明检查是否遗漏头文件或原型声明
E4 链接错误undefined reference检查函数是否遗漏反编译
E5 语义不一致调用参数数量不匹配拉取 caller+callee 完整代码,LLM 综合裁决

整个修复过程是迭代的,最多进行 5 轮全局迭代。如果连续 2 轮没有修复任何新错误,判定为收敛并停止。

4.7 共享知识库#

这是将四个 Agent 粘合在一起的关键基础设施:

neo4j 代码属性图(CPG)——存储结构化的程序知识:

节点类型:
(:Function) — 函数,含地址、名字、签名、置信度
(:Variable) — 变量,含名字、类型、作用域
(:Struct) — 结构体,含字段定义
(:Type) — 类型信息
(:SourceFile)— 源文件
关系类型:
CALLS — 函数调用关系
HAS_VARIABLE — 函数拥有变量
HAS_TYPE — 变量的类型
READS_GLOBAL — 函数读取全局变量
WRITES_GLOBAL— 函数写入全局变量
INCLUDES — 文件包含关系

为什么用图数据库而不是关系数据库? 因为逆向工程中最频繁的查询模式是”从这个函数出发,沿着调用链找到所有相关函数和共享的全局变量”——这正是图查询的天然优势。比如:

// 获取函数 F 的完整上下文:调用者+被调用者+共享全局变量+相关结构体
MATCH (f:Function {address: 0x401234})
OPTIONAL MATCH (caller)-[:CALLS]->(f)
OPTIONAL MATCH (f)-[:CALLS]->(callee)
OPTIONAL MATCH (f)-[:READS_GLOBAL|WRITES_GLOBAL]->(gv:Variable)
OPTIONAL MATCH (f)-[:ACCESSES_STRUCT]->(s:Struct)
RETURN f, collect(DISTINCT caller), collect(DISTINCT callee),
collect(DISTINCT gv), collect(DISTINCT s)

这个查询在关系数据库中需要多次 JOIN,在 neo4j 中是自然的一跳遍历。

SQLite 元数据库——追踪每个函数的反编译状态、修复历史、置信度分数等轻量元数据。选 SQLite 是因为零配置、单文件部署。

4.8 Orchestrator:确定性状态机#

Orchestrator 不调用 LLM。它是一个用 LangGraph 实现的确定性状态图,负责:

  • 控制 Phase 0 → 1 → 2 → 3 的流转
  • Phase 3 发现需要重新反编译某些函数时,回退到 Phase 1
  • Phase 3 发现类型系统需要调整时,回退到 Phase 2
  • 追踪进度、资源消耗
  • 判断何时终止(编译成功 / 迭代上限 / 收敛 / 预算用尽)
Phase 0 → Phase 1 → Phase 2 → Phase 3
↑ ↑ │
│ │ ├── 编译通过 → 完成
│ │ ├── 类型问题 → 回退 Phase 2
│ └────────┤
│ └── 函数需重做 → 回退 Phase 1
└─────────────────┘

Agent 之间不直接通信。所有信息交换通过知识库完成(黑板模型):Agent A 写入知识库 → Orchestrator 检测状态变化 → 触发 Agent B 读取知识库。这保证了解耦、可追溯、可恢复。


五、与现有工作的关键差异#

维度LLM4D / SK² / ReFDecLLMReCopilotCTF AgentsRE-MAS
处理粒度函数函数函数(+有限跨函数)题目全程序
跨函数信息有限(受token限制)CPG图查询
验证闭环有(单函数)有(项目级)
信息持久化简单memory图数据库
输出产物单个C函数可编译单函数分析建议CTF flag可编译项目
训练需求大量训练零(用GPT-4)三阶段训练部分零

核心差异只有一句话:它们都在函数级做单模型推理,我在项目级做多 Agent 协作。


六、局限性与诚实的评估#

我不想假装这个方案没有问题。以下是我目前看到的主要风险和局限:

6.1 全程序编译可能真的很难#

头文件依赖恢复是个悬而未决的难题。标准库函数可以用映射表覆盖(约 500 条规则覆盖 90% 场景),但第三方库依赖几乎无法自动恢复。如果原始程序链接了 libcurlopenssl 之类的库,目前没有好的自动推断方法。

回退策略:如果全程序编译不可达,可以退而求其次——模块级可编译(每个 .c 文件单独编译通过),或者带 stub 的可编译版本(困难函数只保留签名不保留实现)。

6.2 混淆不在范围内#

这个系统只针对干净逆向(无混淆的正常编译产物)。对于 OLLVM 控制流平坦化、VMP 虚拟化保护等混淆技术,目前 LLM 的处理能力非常有限——2025 年最新研究(arxiv 2505.19887)显示组合混淆下所有 SOTA LLM 普遍失败。混淆是 future work。

6.3 评估基准的缺失#

现有的 benchmark(HumanEval-Decompile、ExeBench)都是函数级的。全程序级反编译目前没有标准化的评估基准,需要自建。我计划选取 8 个开源 C 项目(从 GNU coreutils 的 cat 到 Lua 解释器),编译为 stripped binary 后反编译还原,与原始源码对比。

6.4 Token 消耗#

虽然反编译用本地模型几乎零成本,但关系恢复 Agent 调用 GPT-4 的开销与项目规模成正比。对于 200+ 函数的大型项目,API 成本可能达到 $30-50。不过这比让一个逆向工程师花一周时间手动还原便宜得多。


七、下一步计划#

  1. 实现 MVP(2周):Phase 0 + Phase 1 管道跑通,在 HumanEval-Decompile 上验证不低于 LLM4D 基线
  2. 全管道验证(4周):四个 Phase 完整跑通,在 GNU cat 上实现端到端编译通过
  3. 完整评估(8周):全部 benchmark + baseline 对比 + 消融实验
  4. 论文撰写(12周):面向 ISSTA/ASE 等软件工程顶会投稿

项目代码将在 GitHub 上开源:chaojixinren/REAgent


参考资料与链接#

核心论文#

论文会议/状态链接
LLM4DecompileEMNLP 2024arxiv / GitHub / HuggingFace
SK²Decompilesubmitted to ICLR 2026arxiv / GitHub / OpenReview
DecLLMISSTA 2025会议页面
ReCopilotarxiv 2025.05arxiv / GitHub
ReSymCCS 2024 杰出论文论文 / GitHub
ReF Decompilearxiv 2025arxiv
REx86arxiv 2025arxiv
TYGRUSENIX Security 2024会议页面
LLM 去混淆评估框架arxiv 2025.05arxiv
LLM + 符号执行语义恢复arxiv 2025.11arxiv
RECoRD (多Agent关系恢复)ICML 2025OpenReview

工具与框架#

工具用途链接
Ghidra传统反编译器 (NSA 开源)官网 / GitHub
IDA Pro MCPIDA Pro 的 MCP 集成GitHub
x64dbg MCPx64dbg 的 MCP 集成GitHub
angr符号执行引擎官网 / 文档
Joern代码属性图 (CPG) 框架官网 / 文档
neo4j图数据库官网
LangGraphAgent 编排框架GitHub
tree-sitter增量解析器官网
CodeBLEU代码评估指标PyPI / GitHub

Agent 参考项目#

项目方向链接
BUUCTF_AgentCTF 解题 AgentGitHub
AgentRE-Bench逆向工程 Agent Benchmark官网
OGhidraLLM + Ghidra 集成GitHub
BinAssistMCPBinary Ninja MCP 集成GitHub

相关视频#

标题链接
D@wnEdg3 - Cruiser: CTF Agent实现探索Bilibili
长亭外 - Superposition: Auto-Pentest Agent Meets CTF ChallengeBilibili

本文是 RE-MAS 项目的研究笔记。项目处于设计阶段,欢迎交流讨论。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

当反编译遇上多智能体:我为什么要设计一个全程序级源码还原系统RE-MAS
https://chaojixin.ren/posts/关于二进制分析在agent上的运用探索/
作者
超級の新人
发布于
2026-03-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00