如何编写hook
序:如何使用hook
可以使用AG大佬的 https://github.com/ThirteenAG/Ultimate-ASI-Loader 项目
将下载的dll重命名为对应的文件名,可让游戏加载游戏目录中的ASI文件
适配任何 x64/x86游戏 免去注入器
事件sdk
hook通常可以用来开发sdk中的事件系统,说英文就是Event,在某个游戏事件发生时 执行指定的功能。
比如你要在游戏hud渲染时
渲染自己插件的贴图
如果直接写
在游戏主界面或者打开游戏就渲染你的贴图就不是你想要的效果
如果设置等待 那么效率会被影响
还会被其他线程影响
最好的办法 开发sdk的通常会封装事件函数
比如在sdk封装里提前hook游戏的hud渲染函数
hud事件函数就做好了
使用者直接使用这个函数注入自己的代码
每次游戏运行自己的hud渲染函数
会运行你的代码 实现在指定事件运行某个代码
然后事件封装里做成容器 使用vetcor list类型封装每个来自于插件的新函数
这样大家使用相同事件函数注入代码
就不会冲突
在链表里会依次执行这些函数
一个事件sdk就是这么实现的
公用CEvent事件
void hud::draw()
假设游戏使用这个函数渲染hud界面
A插件hook了这个函数 渲染自己的贴图
B插件也hook了这个函数
但没法保证使用的hook项目对同一个函数注入的兼容性
手动兼容很麻烦
那么假设有一个开发者做就一个sdk用于开发 或者做就一个公用库文件(dll和lib都行)
那么可以封装一个链表容器
只hook注入一次
所有来自于插件中的函数被放到容器里
每次运行这个函数依次取出容器里的函数运行
这样实现了兼容
hook最大的用处 就是事件系统
本身我们hook游戏的函数或者某个地址处的代码
就是实现改写和增加新功能
那么很难保证会不会有人对同一个地址反复hook
不利于兼容
写一个公用CEvent事件源更好
事件源可以增加很多事件
比如
- hud渲染
- 人物模型渲染
- 菜单主界面渲染
- 游戏读条界面
- 人物死亡事件
- …
这样的封装 能让编写者省事
而编写插件我们需要在某个时机实现自己的代码运行
就可以直接使用事件源完成
最终简单的脚本编写者可以脱离复杂的底层汇编
GTA系列几个游戏的sdk都是这么实现的
例子
最简单的例子就是
你写的dll在打开exe 游戏刚进去就已经在运行了
那么你不想它在这个时候运行
比如你操作了人物改写血量
可人物还没 创建呢 因为游戏刚打开
假设你能通过一些逆向工具
找到游戏在读条加载后进入的瞬间运行的人物渲染函数
hook这个函数 运行自己的代码
在对人物进行操作就解决了
ce脚本的实现 通常会改写固定的血量全局变量或者对汇编代码进行修改
以防止人物还没创建就去运行修改血量的问题