本节摘要:AI 逆向的头号工程风险是幻觉:模型自信地给你一个不存在的函数、一个进制换错的地址、一条图上根本没有的调用关系。本节先把幻觉钉成三种可命名的形态——编造 API、错误进制、虚构交叉引用,各配症状样例与识别口诀;然后给出防御架构,与开源社区 reverify 项目(约 1.3k stars,2026-10 社区口径)的理念同构:AI 提出假设、确定性工具验证;再配一张「断言类型对验证器」的菜单表,让每类断言都有对应的机器判据;随后把第 08 章的闭环推广为「生成证据链的机器」,落地成四列模板——假设、验证命令、输出、结论——并用 crackme 案例填三行示范(含一行「已证伪」);最后给出团队纪律与幻觉率度量法。核心纪律一句话:没有命令输出的结论不进报告。
逆向场景的大模型幻觉不是随机的胡言乱语,而是集中在三类(样例为示意):
三形态的共同点:都发生在「模型从阅读走向断言」的瞬间。所以防御的共同解法也是一句话:把断言从模型嘴里拿走,交给工具。
三形态的危害权重并不相同,防御投入也应有先后:编造 API 最常见但最易查(导入表一翻便知),先给它上验证器性价比最高;错误进制最隐蔽(差一个量级也能看走眼),必须靠闸门自动化;虚构交叉引用危害最大(直接带偏分析方向),值得在流程里单列 xref 复核项。按「频率乘危害」排优先级,是资源有限团队的正确姿势。
# defense_arch.txt —— 反幻觉防御架构:假设经路由到验证器,结论入链 ┌──────────────┐ │ LLM(阅读者) │ 产出:假设清单 │ 提假设不下结论│ (函数职责/数据流/调用关系/数值) └──────┬───────┘ │ 结构化假设 ▼ ┌──────────────┐ │ 验证器分发 │ 按断言类型路由 └──────┬───────┘ ┌───────────┼───────────┬─────────────┐ ▼ ▼ ▼ ▼ 反汇编/导入表 CPG 查询 符号执行 调试器 (地址与API) (xref 与流) (路径可行性) (运行时行为) └───────────┴───────────┴─────────────┘ ▼ ┌──────────────┐ │ 证据链(四列) │ 假设/验证命令/输出/结论 └──────────────┘
这个架构与开源项目 reverify 的理念同构:反幻觉不靠更好的模型,靠把「下结论」这件事从生成式组件手里剥离,交给确定性组件(以该项目文档为准)。第 8.2 节的 angr 闭环是它在「行为断言」上的实例;本节把它推广到全部断言类型。
架构里最容易被忽视的是「分发」一环:假设进来先归类(这是地址断言、调用断言、数据流断言、数值断言还是行为断言?),再选验证器。归类本身就是一道防线——它强迫流程(或人)显式思考「这条断言的可证伪形式是什么」。
| 断言类型 | 典型幻觉 | 确定性验证器 | 验证形态 |
|---|---|---|---|
| 地址与函数存在 | 编造 API、地址错位 | Ghidra/radare2 反汇编 | 列出符号与导入表比对 |
| 调用关系 | 虚构交叉引用 | Joern CPG(第 7 章) | caller 与 callee 查询输出 |
| 数据流可达 | 「输入可能流到」 | CodeQL/semgrep 污点(第 6 章) | 污点路径查询结果 |
| 数值与进制 | 错误进制 | int_convert 统一转换(第 11.2 节) | 程序化换算比对 |
| 运行时行为 | 「执行后会」 | angr(第 8 章)与 pwndbg(8.3 节) | VERIFIED 或寄存器对照 |
| 命名建议 | 名字好看但错位 | 行为验证加人工确认(第 9.2 节) | 转正流程记录 |
菜单的用法是「先路由再验证」:拿到模型断言先归类,再选验证器,禁止跳过归类直接采信。表中每行的工具本书都已练过——这正是全书工具链在工程层的合流点。空的单元格不存在:没有验证器的断言类型,就不该出现在报告里。
三形态的验证命令各给一条「最小验证」示例(对象为 8.1 节自编 crackme):
| 形态 | 模型断言(示例) | 最小验证命令 | 判读 |
|---|---|---|---|
| 编造 API | 程序调用了 read_flag | 反汇编工具列导入表 | 表里没有即证伪 |
| 错误进制 | win 在 0x401196,即 4015862 | int_convert 的 same 比对 | False 即证伪 |
| 虚构 xref | check 被 handle_login 调用 | Joern 的 caller 查询 | 空列表即证伪 |
证据链是防御架构的落地文件,每案一份、git 管理、随报告归档:
# evidence_template.md —— 证据链四列模板(每案一份) | 假设 | 验证命令 | 输出(摘要) | 结论 | |---|---|---|---| | check 为口令校验,成功输出 Access granted | python gen_solve.py(第 8.2 节渲染) | VERIFIED b'AI4RE_2026' | 已证:口令为该串,求解器背书 | | key 常量位于数据段 0x404020 | radare2 命令 pxs 或 Ghidra 查看 | 字符串 AI4RE_2026 位于该地址 | 已证:地址无误 | | (示例)check 被 handle_login 调用 | Joern:target.caller.name.l | 返回空列表 | 已证伪:不存在该调用,模型断言撤回 |
四列纪律:假设列保留模型原话(便于审计与复盘);验证命令列必须可复制重跑(附工具版本);输出列摘要要含关键结果串(如 VERIFIED 标记、查询返回行数);结论列只有三种取值——已证、已证伪、待验证,没有「大概成立」。第三行示范同样重要:证伪也是结论,撤回模型断言并留痕,比悄悄删掉更有价值——它既是本案的更正,也是幻觉率度量的原料。
证据链的文件组织(每案一目录,git 管理):
# evidence_layout.txt —— 证据链目录约定 case-20261016-crackme/ evidence.md 四列表(主链) outputs/ 验证命令的完整输出附件 gen_solve.py 当轮渲染的脚本快照 notes.md 人工备注(不改结论,只记背景)
两个反模式点名:把证据链写成「结论加感想」的散文(评审无法复核);把输出附件省略只留摘要(回放时对不上数)。目录约定看起来琐碎,但它决定了半年后这条链还能不能被重新走一遍。
还有一个常见追问值得正面回答:链会不会太慢、拖垮分析节奏?不会——链只约束「写进报告的结论」,探索期的中间假设随手记在草稿区即可,结案前再择要入链。快是探索的自由,慢是结论的代价,两者分区管理,互不拖累。
链与闭环的分工再划一次界:第 8.2 节的闭环负责「生产」结论(假设到验证到回填的自动化),本节的链负责「保存与审计」结论(四列表与附件的规范化)。一个管流水线,一个管账本——账本记得好,流水线翻车时可追溯;流水线跑得好,账本自动长。两者在 SOP 第八步(第 11.3 节)合流。
至此可以给出全书的「信任栈」:指令层信任来自隔离环境(沙箱书第 02 章),断言层信任来自确定性工具(第 06 到 08 章),结论层信任来自证据链(本节)——三层齐备,AI 逆向的产出才配得上「工程」二字。
证据链要长在团队流程里才算数,三条纪律:
三条纪律的推进顺序也有讲究:先立「评审只看链」(一周即可生效,改评审规则就行),再立「抽样回放」(需要一个月的数据积累),最后上「幻觉率分桶」(需要十余案的样本量)——一步到位的理想方案往往死在落地半路,渐进的三步走才是团队真实可执行的路径。
这套度量把「模型靠不靠谱」从争论变成数字,与第 10.2 节的评测精神一脉相承。一个健康的闭环流程跑起来后,幻觉率应当随提示词与验证器的迭代逐月下降——曲线本身就是团队成熟度的仪表盘。
度量的最小实现不必上平台,一张表就够:每案结案时在团队总表追加一行(日期、断言总数、已证数、已证伪数、按形态分桶计数),月会看趋势、季会看拐点。数据积累三个月后你会自然提出正确的问题——不是「模型行不行」,而是「哪类断言还缺验证器」。
证据链解决了「结论可信」,下一个决策是「工具选谁」:免费开源自建到底差商业工具多少,商业方案贵在哪、值不值——11.2 节把这笔账摆上桌算清楚。