本节摘要:让大模型读反编译输出,最早是「顺手用通用模型」的民间实践,随后学术界给出了系统验证(DeGPT,NDSS 2024),工业与开源界则造出了专用模型。本节先把通用模型的真实水位摆正:读伪代码、解释逻辑、提假设,它已经不错——这正是第 08 章闭环成立的前提;再进入 LLM4Decompile:首个反编译专用开源大模型系列,1.3B 到 33B 多档规格(约 7.1k stars,MIT 许可证,EMNLP 2024,2026-10 社区口径),End 模式直接从汇编生成 C 代码,Ref 模式拿 Ghidra 伪代码加汇编做精修,官方宣称可执行率超过 GPT-4o 与 Ghidra 百分点以上——注意这是官方口径,引用时原样转述;然后拆解评测指标怎么看,梳理 DeGPT 到 LLM4Decompile 的学术脉络;最后给选型建议:什么时候通用够用,什么时候必须专用。研究对象均为自编译样本与公开数据集。
先把事实摆正:今天的通用大模型读 Ghidra 伪代码,能力已经不错。让它解释一段函数在做什么、标出可疑的比较逻辑、按第 8.2 节的模板提出校验假设——这些「阅读理解」任务上,通用模型的性价比很高:不用部署、随问随答、上下文还可以混入字符串表与导入表。
边界同样清晰:通用模型的输出是「解释」,不是「重建」。你问它伪代码什么意思,它答得好;你让它把汇编反推成可编译的 C 源码,它常给出「形似而不可用」的代码——变量类型对不上、控制流还原错误、甚至编造不存在的标准函数(第 11.1 节的幻觉三形态之一)。
| 任务 | 通用模型表现 | 原因 |
|---|---|---|
| 解释伪代码逻辑 | 好 | 阅读理解是通用强项 |
| 标出可疑分支 | 好 | 模式识别,答错也无代价 |
| 提校验假设(8.2 节) | 好 | 有求解器兜底 |
| 反推可编译 C 源码 | 不稳定 | 需要指令级精确映射,通用训练目标不覆盖 |
| 批量一致输出 | 弱 | 会话间风格与质量漂移 |
一句话:通用模型是优秀的读者,不是可靠的作者。
LLM4Decompile(约 7.1k stars,MIT 许可证,EMNLP 2024,2026-10 社区口径)是首个反编译专用开源大模型系列,规格从 1.3B 到 33B——小档笔记本可跑,大档对标闭源模型。专用体现在三处:训练数据是「汇编与对应源码」的配对语料;任务目标就是反编译本身;评测指标围绕可重编译与可执行设计,而不是聊天质量。
两种工作模式覆盖两类场景:
| 模式 | 输入 | 输出 | 适用 |
|---|---|---|---|
| End 直接反编译 | 汇编指令 | C 源码 | 没有反编译器、或想统一批处理 |
| Ref 精修 | 汇编加 Ghidra 伪代码 | 精修后的 C | 已有 Ghidra 输出,要提升可读与可执行性 |
规格与场景的粗略对应(以官方仓库的模型卡为准):
| 档位区间 | 显存量级 | 典型场景 | 局限 |
|---|---|---|---|
| 1.3B 到 6.7B | 消费级显卡 | 本地批量命名辅助、低延迟流水线 | 重建质量有限 |
| 9B 到 33B | 工作站或多卡 | 高质量重建、PoC 辅助 | 部署与推理成本高 |
Ref 模式的定位尤其务实:不重造反编译器,而是把 Ghidra 当初稿、模型当润色器——这正是通用模型顺手做但不稳定的场景,专用模型把它变成了可复现的流水线环节。使用方式是标准的开源权重加载(transformers 生态),多档规格按显存选配,具体命令以官方仓库为准。规格选择的粗略直觉:1.3B 与 6.7B 档适合嵌入式设备与大批量低延迟场景;9B 到 33B 档适合需要更高重建质量的离线任务。
# load_ref.py —— 加载 LLM4Decompile Ref 档权重的写法示意(命令以官方仓库为准) from transformers import AutoTokenizer, AutoModelForCausalLM MODEL = "LLM4Decompile/LLM4Decompile-Ref-9b" # 档位按显存选 tokenizer = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(MODEL, trust_remote_code=True) def refine(asm: str, pseudo: str) -> str: """Ref 模式:汇编加 Ghidra 伪代码进,精修 C 出""" prompt = f"这是汇编:{asm} 这是反编译器输出:{pseudo} 请生成对应 C 源码:" inputs = tokenizer(prompt, return_tensors="pt") out = model.generate(**inputs, max_new_tokens=1024) return tokenizer.decode(out[0], skip_special_tokens=True)
提示词形态以官方仓库文档为准(Ref 模式对输入格式有明确约定),这里只示意「汇编与伪代码同时喂入」的结构。本机跑不动大档时,先在公开演示环境体验,再决定部署哪一档。
LLM4Decompile 官方宣称其可执行率超过 GPT-4o 与 Ghidra 百分点以上(官方口径)。引用这类数字要带三个自觉:
自测方法比引用更有说服力:拿自己的十个函数(编译后 strip),分别喂给候选模型与 Ghidra,数一数「能编译、能复现行为」的各占几个——十分钟的实验胜过一百行的宣传语,这也是第 10.2 节「自建小评测集」思想在模型选型上的应用。
自测的打分表直接照抄:
| 维度 | 记什么 | 及格线(自定) |
|---|---|---|
| 可编译数 | 十个里能过编译的 | 看任务要求 |
| 行为复现数 | 编译产物输出与原程序一致 | 看任务要求 |
| 可读性 | 三个变量名是否语义化 | 两名以上合理 |
| 一致性 | 跑两遍输出是否稳定 | 完全一致或差异可解释 |
打分表的「一致性」最常被漏掉:同一个函数两次生成差异巨大,说明该模型进流水线前还得加固定采样参数——这属于部署知识,论文里不会替你写。
专用化不是凭空出现的。DeGPT(NDSS 2024)是「用大模型优化反编译器输出」的早期学术代表:把 Ghidra 伪代码交给通用大模型重写,实验显示可读性与变量命名显著改善——它证明了「反编译输出值得也经得起模型精修」这个命题。
LLM4Decompile 沿此方向再进两层:从「精修」扩到「直接反编译」(End 模式),从「调通用模型」进到「训专用模型」——把任务知识烧进权重,换来离线、稳定、可控成本。脉络记忆法:DeGPT 验证方向,LLM4Decompile 工程化定型。给方向验证者的启示同样重要:DeGPT 用的只是当时的通用模型——说明「先验证方向、再谈专用化」的顺序值得效仿,今天你手里任何新想法也可以先用通用模型探路。
# lineage.txt —— 从民间实践到专用家族 民间实践:顺手拿通用模型读伪代码(有效但不可复现) │ DeGPT(NDSS 2024):系统验证「模型精修反编译输出」可行 │ LLM4Decompile(EMNLP 2024):End 加 Ref 两模式 + 专用权重 │ 后续方向:与反编译器深度耦合的流水线(Ref 模式的工业化延伸)
选型判断走到落地,还有三个高频问题先答在这里:
| 问题 | 短答 | 依据 |
|---|---|---|
| 专用模型能替代 Ghidra 吗 | 不能,两者是初稿与润色的关系 | Ref 模式设计本身就是证据 |
| 本地小档够用吗 | 读伪代码与命名建议够,重建高质量要中大档 | 9.1 节任务表与官方规格说明 |
| 输出能直接进证据链吗 | 不能,须过编译与行为验证 | 第 11.1 节纪律对任何模型输出一视同仁 |
最后一个判断题留给读者:随着通用模型继续变强,专用模型的价值会集中在哪?本章的答案是两个字——可执行与本地化。这个判断是否长期成立,以你的实测为准。
模型把伪代码变得可读,但分析成果不能停留在对话记录里。下一节处理逆向最日常的资产——名字:LLM 如何建议命名、人如何确认、binsync 如何让这些名字跨反编译器流动并接受 git 的审计。