唯一性、稳定性与跨启动验证

唯一性、稳定性与跨启动验证

AOB 在一次扫描中只出现一次,并不自动证明它能跨启动、跨版本使用。本章建立可重复的核验流程,帮助区分匹配数量、位置与指令语义。

从全部结果开始

构造特征后使用 CE 扫描界面或 Lua 的 AOBScan 列出所有匹配。记录扫描范围、内存保护条件、模式、结果数量及地址所属模块。没有命中说明当前条件下未找到,并不直接证明程序没有此代码;两个以上命中意味着仅靠当前模式不能唯一决定目标。AA 的 aobScanModule 取首个匹配,不会替你证明唯一。

打开候选位置的反汇编,确认特征中的哪一个字节是目标指令开头,逐条比较操作数和邻近控制流。在 CE 自带 Tutorial 第 5 或第 7 关触发对应数值变化,观察断点和对象地址,确认命中具有目标行为。碰巧相同的机器码可能出现在不同函数或数据段,字节一致不等于用途一致。

增加区分信息

结果过多时,可先限制到正确模块,再在前后加入稳定的指令字节;变化的地址或位移按原因选择通配符。每次调整后重新扫描全部候选,不以第一个结果为终点。不要为了获得一个结果而加入只在某次启动成立的地址字节,也不要为了跨版本把所有有意义的字节都通配。

在多个干净启动中重新附加 Tutorial 并进入相同关卡,记录目标是否始终存在、匹配数是否一致、命中位置是否仍为相同语义。若 Tutorial 有多个版本或分别测试 32 位和 64 位,应分别比较字节、指令与行为;一个版本的结果不能证明其他版本。还要考虑功能加载前与加载后的差别,以及运行时生成代码的生命周期。

检查与记录

确认唯一后,修改代码之前仍需使用 assert 等方式检查覆盖处实际原字节,并确认完整指令长度和跳转编码。断言通过只说明该位置的预期字节匹配,不证明特征唯一,也不证明后续逻辑正确。条件任一不满足就停止。

验收报告应写明被测程序版本、位数、扫描范围、特征、命中数、目标位置和启动次数,以及启用、关闭后的行为。若某次结果多于一个或未能验证另一个版本,将其明确标记为不支持或未验证。

一个具体的计数方法:在 CE 主窗口选择“Array of byte”类型,输入完整特征并进行首次扫描,等待扫描结束后读取结果总数;逐一打开候选检查模块归属。若只有一项但它位于错误模块,仍不能作为正确目标。更改扫描条件后需新建扫描,避免沿用旧候选集合。也可使用本专题的 Lua AOBScan 例子遍历完整列表,再筛选属于目标模块的地址。

参考资料