讲师:XMDS
整理:小莫
所需工具:
- vs code
- cmake
使用库
为什么用 AOB ?
AOB 是 反汇编 byte, 在IDA 中可使用快捷键 Alt+B
来搜索 AOB.
同一个游戏 不同的版本有不同的内存地址, 但是版本迭代肯定是基于稳定版的第一个版本更新的
所以会有重复代码, 通过查找汇编的byte码获得内存地址, 这样无论哪个游戏版本都通用.
一般查函数地址这样不管游戏怎么更新 都能查到, 就算这个函数下次更新 游戏改变了代码, 可以使用模糊查找,用 ??
填充, 只要有几个共性就行.
实现原理是, 获取程序的首地址 一个字节一个字节的查 去比较.
如果程序很大, 你只想查可执行代码段.text, 变量段.data之类的,那么解析下pe文件或者elf文件,把首地址以段的首地址查就行了,
创建项目
首先, 创建CMakeLists.txt
文件,写入以下内容
1 | # CMakeLists |
目录结构:
1 | MyHook/ |
在 dllmain.hpp
文件中引入我们可能需要的库
1 |
然后在 MyHook.h
中引入 #include "dllmain.hpp"
,
在 MyHook.cpp
中 引入 #include "MyHook.h"
开始hook
比如说, 我们要hook这个函数:
1 | .text:0000000142071FD0 ; __int64 __fastcall loadFile_step2(__int64, __int64, int) |
使用 pattern 获取地址
1 | auto pattern = hook::pattern("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F1 44 89 41 08"); |
创建 25FF jmp 方法
1 |
|
备份原地址 并 分配内存写入权限
我们备份至少需要 14 个字节, 通过IDA 中发现, 函数的前14个字节是:
1 | 48 89 5C 24 08 |
但这样的话,会导致第三行后面的 18
被截断,从而导致mov [rsp+arg_10], rsi
指令不完整;
所以,我们这里需要备份15个字节,
使用 memcpy 方法进行备份, 这样写:
1 | size_t back_size = 15; |
设置跳转指令 / 复制原函数
使用 MakeAbsJMP
方法设置跳转指令
第一参数是从哪里跳的地址
第二个参数跳到哪里
1 |
|
创建hook函数
1 | void *loadFile_step2_fun(void *a, wchar_t *b, int c) |
完整示例
1 |
|
封装hook
接下来,我们来对hook进行简单的封装,以方便后续的调用:
1 | // XMHook.hpp |
调用
1 |
|