AI 自动化逆向(二十)闭环验证:怎么证明 AI 的结论说的是正在跑的程序
本文是「AI 自动化逆向」系列第 20 篇。上一篇:让 AI 长周期跑一个项目:上下文与文档怎么组织;下一篇预告:同义反复的度量:AI 最容易糊弄你的地方。
前言
上一篇把文档体系撑了起来。这一篇回答一个更根本的质询,它悬在每一页静态结论的头上:
AI 写了几百页结论——它们说的是磁盘上那个文件,还是"正在跑的那个程序"?
这不是哲学问题,是工程问题。静态和运行之间隔着一整个"装载"黑盒:重定位、换构建、各种保护层。翻译表说自己映射的是运行时地址——凭什么?
(同前几篇:文中"AI"指执行分析的模型,"我"指设定目标、审结果的人;内容均已脱敏。)
一、"说的是正在跑的程序"要靠什么站出来作证
静态结论如果只和"磁盘上的字节"对得上,可能错在三种地方:
- 表本身就错:地址身份不对——它映射的偏移从一开始就是错的;
- 表对,但那段代码从没被执行:静态世界里存在一个函数,不等于运行时真的走过它;
- 跑的根本是另一个构建:文件是 A 构建、进程里是 B 构建,"同一份程序"这个默认前提就塌了。
三种病对应三种证词。项目里最后凑齐的是一套闭环验证:让静态结论对运行中的程序做出可逐字节检验的预测,再让它去兑现。三层闭环,一层比一层硬。
二、过程:三层闭环
闭环 1:调用点计数——把"地址身份"变成两侧的对账(只读、全量)
第一层是个漂亮的交叉验证,而且一个字节都不用写:
若某个函数"运行态地址 = 文件态地址 + 偏移",那么每一条指向它的直接调用都必须在装载时被重新编码。于是——两侧对"指向它的调用"的清点,必须相等。
这个清点强在哪?两个计数取自两段完全不同的字节流(文件里的一个区、运行内存里的另一个区),而"运行态地址"本身来自第三条独立的测量(不是这两个计数算出来的)。所以三个来源两两独立——偏移若错,运行侧的计数会直接指向别处,掉到零。
结果:107 个可翻译函数里,102 个计数完全相等;把"文件侧也要有调用"作为强检验档,94.5% 通过。更妙的是那 5 个不匹配:它们全部落在**早就标着"待查"**的行里——而且和"运行构建比文件构建多了几百字节(同一工程的另一个构建)"完全相容。不匹配没有动摇模型,反而给"这是另一个构建"提供了旁证。
为什么这一层比"抓现行"式的验证更有力:一次覆盖全部;证明的恰好是表唯一宣称的东西(地址身份);全程只读。
闭环 2:注入式打点——把"确实执行"变成命中(写操作、全还原)
第二层解决"表对但没被执行":让它当场跑一次给你看。
方法是把选中函数的入口改成跳到一个观察桩:桩里累加一个计数器、把调用者的返回地址记进一个滚动环——然后外部只读轮询。写操作遵守上一篇的全部纪律:原字节先存好、结束时无条件写回、逐处核验。
结果:一个函数在观察窗里拿到22 次命中、抓到2 个调用者——两轮独立复现,完全一致。(顺带看到了路径形态:命中成对出现、间隔约 1 秒、成对之间约 25 秒——一条"周期性"路径的指纹。)
这一层里有个值得单独标出的动作:布点前,同一条前提在运行态又验了一次——正是这第二次校验,抓到一个"文件侧形态与运行侧不符"的条目(后来查清:它的入口多了一层"准备桩",第 13 篇讲过)。如果只在文件侧验过就直接照抄,就会改到一个语义不同的入口。
闭环 3:返回地址反查——让动态对静态做一个"会被打脸的预测"
第三层最干脆,也是全篇的题眼。
一条返回地址 R,在物理上意味着:R 减 5 个字节处,必须恰好有一条"调用"指令,而且它的目标必须正是那个函数。——这不是叙述,这是一个可以被逐字节检验的预测:预测得越具体,被打脸的成本越低。差一个字节,就是 MISMATCH。
兑现情况:两个返回地址翻回去,两条调用指令全部 MATCH、零 MISMATCH;而且这两个调用点,本来就在静态扫描出的七百多个调用点的集合里——动态抓到的,和静态列出的,是同一批。
这就是"闭环"两个字的实际含义:动态做出预测,静态逐字节兑付。两头对上的那一刻,"这个结论说的是正在跑的程序"就不再是一句自辩。
三、判据与验证:四条
1. "跑的是不是同一个构建"是要测的命题,不是默认前提。静态结论的每一页,都该能回答"我说的是哪个镜像"。
2. 交叉验证的几条路必须真正独立。两个计数 + 一个独立测量的地址——三条血统查过,对账才算数(第 14 篇那把尺子,在这里量的是证据链)。
3. 要动态做的是"预测",不是"见闻"。"我看到它跑了"只是见闻;“我预测 R-5 处有一条目标为 X 的调用,你去看”——这才是可被机器证伪的样板。
4. 同一条前提,每个镜像各验一次。文件侧验过,运行侧再验——第二次校验不是重复劳动,它是抓到反常的唯一机会。
(还有一条隐含的:观测手段的"侵入性"和"证据强度"不成正比。三只闭环里最硬、覆盖率最全的那层,是纯只读的。)
四、结论
"在跑的程序"和"文件里的程序"是两个东西。闭环验证的实质,是让静态结论在运行态兑现、让动态观测在静态里落位——两头各自独立,却必须严丝合缝。
一条通用的借鉴:给每条结论设计一个"会被打脸的预测",然后看它敢不敢去兑现。兑现成功,结论升级;对不上,差的那个字节会告诉你错在哪一层。这比任何"我认为它是这样"的叙述都便宜、都硬。
五、边界声明
- 本文只讨论AI 自动化逆向中的判据设计与审核方法,不涉及任何具体产品、厂商或服务的分析结论。
- 文中所有地址、偏移、常量、字段名一律为占位符或示意值,
不代表任何真实目标中的取值;示例代码为说明判据而编写,不构成可运行的针对特定目标的工具。 - 文中提到的比例与数字均来自作者项目内的测量记录,仅用于说明方法失效的方式。
- 请勿将本文内容用于未授权的用途。
六、收尾
闭环讲的是"证明它对"。下一篇讲它的反面:一个"永远对"的度量——改完也不会红的断言、按构造就不可能失败的检查——也就是 AI 最容易糊弄你的那一手:同义反复。
下一篇计划聊:同义反复的度量:AI 最容易糊弄你的地方。
转载请注明出处:
https://lizhiyong.blog.csdn.net/article/details/169068923