AOB 注入脚本与断言

AOB 注入脚本与断言

AOB 常被用来定位 AA 脚本的注入点;它仍需要单独检查匹配数量和被覆盖字节。本章展示如何将定位、断言、原代码保存和关闭路径连起来。

定位和校验是两步

在 CE 自带 Tutorial 第 7 关先找到写入目标数值的指令,并在模块内用扫描界面确认特征只有一个目标匹配。32 位实例可能叫 Tutorial-i386.exe,64 位实例可能叫 Tutorial-x86_64.exe;应以实际模块列表为准。确定目标指令相对于特征起点的字节偏移。然后记录完整覆盖区原始字节和每条指令长度。若特征从前一条指令开始,注入点并不是扫描结果本身;即使偏移计算正确,也要在反汇编器确认落在指令起点。

下面只演示定位与断言的结构,模式和字节是虚构教学示例,不能直接用于某个进程:

[ENABLE]
aobscanmodule(pattern,Example.exe,8B 45 ?? 89 42 18)
define(hook,pattern+3)
assert(hook,89 42 18)
registersymbol(pattern)

[DISABLE]
unregistersymbol(pattern)

此示例没有修改代码,也没有分配或注入逻辑。pattern+3 表示跳过三个字节;hook 只是供脚本使用的文本定义,注册的是扫描得到的 pattern 符号。assert 检查从注入点起的预期字节,不是唯一性检查。实际断言应覆盖经过验证的相关原始字节,并符合最终覆盖长度。

先用自分配数据练习完整启停

以下两条地址表脚本配合使用,只修改 CE 在 Tutorial 进程中分配的教学数据,不修改 Tutorial 原有程序指令。先附加自带的 Tutorial-i386.exe,把第一段保存为独立表项并启用;它分配空间并写入八个已知字节:

[ENABLE]
alloc(ceLesson,100)
registersymbol(ceLesson)
ceLesson:
  db DE AD BE EF 11 22 33 44

[DISABLE]
unregistersymbol(ceLesson)
dealloc(ceLesson)

在内存浏览器跳转到 ceLesson,确认八字节。然后将下列代码保存为第二个表项并启用,它只在这一分配区内扫描、核对并替换后四个字节。示例默认整个分配区中模式只有一次;启用前应使用扫描界面检查该区间的全部结果。

[ENABLE]
aobscanregion(lessonHit,ceLesson,ceLesson+100,DE AD BE EF 11 22 33 44)
assert(lessonHit+4,11 22 33 44)
registersymbol(lessonHit)
lessonHit+4:
  db 55 66 77 88

[DISABLE]
lessonHit+4:
  db 11 22 33 44
unregistersymbol(lessonHit)

启用后查看 ceLesson,应显示 DE AD BE EF 55 66 77 88;关闭第二项后应恢复为 DE AD BE EF 11 22 33 44,最后才关闭第一项释放内存。脚本是否运行成功取决于实际 CE 版本和练习进程的分配权限;此处给出可演练的方法,不代表已经在你的目标程序实测。若断言失败或结果不唯一,停止并检查,不要继续写入。

准备实际注入

确认唯一之后,根据实际跳转机器码长度选择覆盖区,完整重放被覆盖指令,重新计算位置相关指令的目标地址。若原指令依赖寄存器或标志,新代码必须保持对应状态;若同一代码会处理多个对象,还需要先确定可区分对象的可靠条件。不能假定所有 x64 跳转都是五字节。

在 AA 模板中加入真实 alloc、跳转、返回和关闭逻辑时,原始字节必须来自当前版本并准确恢复。关闭时先恢复,再注销、释放;若线程仍在执行新分配区,释放存在竞态,需要安全停用设计。仅仅使用 AOB 不会解决线程同步问题。

验证清单

启动两次 Tutorial 并重新回到第 7 关,重新确认模式命中数、目标功能和断言;记录启用前机器码、启用后跳转以及关闭后机器码。任何版本更新或匹配数量变化都需要重新分析。断言失败时保留现场并检查模块、偏移和字节,不要删掉断言来强行启用。

参考资料