Lua AOBScan 与结果释放

Lua AOBScan 与结果释放

CE 的 Lua AOBScan 可以取得所有匹配地址,适合做结果数量检查和交互式诊断。本章演示只读取扫描结果的基本写法,以及返回对象的释放。

先看函数返回值

启动并附加 CE 自带的 Tutorial,在第 5 或第 7 关通过内存浏览器记录一段实际字节,然后打开 CE 的 Lua 窗口。AOBScan 可根据字节模式扫描当前进程,返回包含匹配地址的 StringList;没有结果时必须考虑返回值为空。该函数支持可选保护标志和对齐参数,不同选择会改变扫描范围与结果数量。返回列表是 CE 对象,用完要调用 destroy()。

下面只读取并打印结果,不写入内存;字节模式是假设示意,不能当作当前 Tutorial 实测值。练习时将字符串替换为刚从 Tutorial 中记录、检查过的特征:

local hits = AOBScan('48 8B 05 ?? ?? ?? ??')
if hits == nil then
  print('没有匹配结果')
else
  local ok, err = pcall(function()
    print('匹配数:' .. hits.Count)
    for i = 0, hits.Count - 1 do
      print(hits[i])
    end
  end)
  hits.destroy()
  if not ok then print('读取结果失败:' .. tostring(err)) end
end

这里在读取过程中使用 pcall,使循环报错时仍会运行释放步骤;不要在列表释放后继续使用它。扫描返回的文本地址也不能在进程重启后当作有效地址保存。

判断结果

零结果时先确认进程、模式、内存是否已经加载以及扫描条件;多个结果时查看每个地址的模块和上下文。只有一个结果时,仍需检查机器码、反汇编和实际行为,尤其注意默认扫描范围可能包含数据区。获取数量不等于验证目标语义。

需要模块内唯一性时,可以结合对地址所属模块的检查,或采用与当前 CE 版本相符的模块扫描能力;先读对应版本 API 文档,不要将全进程结果数量直接当成模块内数量。扫描本身可能耗时,循环或计时器中反复扫描会降低响应,应按需执行并回收对象。

练习验收:使用真实观察到的字节特征运行一次,记录完整结果数量并核对候选指令;再故意修改一个固定字节确认无结果分支也能正常结束。

还可以用没有通配符的短序列测试多结果分支,观察列表从索引零开始逐项输出。不要把示例打印出的地址解释为可信注入位置:复制地址到内存浏览器后,应进一步核对当前模块、附近指令和目标功能。脚本中若改动了模式、保护条件或对齐设置,结果计数的含义也随之改变,记录时必须一并保存这些条件。

若扫描耗时很长,先检查搜索范围和结果数量,再考虑是否需要缩小到有明确依据的区域。每次重新扫描都是新的观察,不能把旧列表的地址与新进程中的对象直接对应。

参考资料