Skip to content

Hook

首先,用link2012的注入项目: https://github.com/thelink2012/injector

这项目一直是GTA系列的hook核心
但能用于任何x86程序
injector.hpp文件最后还有GTA除5以外的游戏版本判断

新的gta4汉化也使用了这个项目
AG大佬经常用这个项目给别的游戏写插件

这个是最成熟的最轻量级的

头文件 injector.hpp

或者直接 hooking.hpp

injector::MakeCALL 替换call指令的分支

injector::MakeJMP 或者直接在函数头部设置jmp跳到你自己的函数

然后直接就能使用了

示例:

cpp
// text: 00666666 call sub_123456

injector::MakeCALL(0x666666, my_func,  vp)

my_func就是你自己的函数 它的函数和原来的sub_123456一样

内存读写 替换call函数 内联hook 更改汇编指令 asm裸函数内联等hook 注入都能简单实现

所有x86/64 hook的原理都是inline hook
就是替换一个函数的开头的指令改成jmp指令跳到你自己的函数里
在你自己的函数结束后在跳回来
但是这种方式会更改所有调用这个函数的分支
如果你要单独改某个分支调用
就用call替换
有短距离call和长距离call两种
短距离有内存范围限制
长距离多占用1个字节 但没有范围限制
对于指令处使用短距离
你随便找个空闲内存 先跳到这个内存
在这个内存里在写一个jmp或者长距离call指令跳到你自己的函数
实现中间跳板原理
就实现了hook

Hook的本质?

hook本质是向某个进程的位置注入你自己的代码

或者用来取进程某个位置的数据 检测进程运行

汇编

汇编语言确实抽象

主要原因是大部分指令集没有除法指令

实现除法都是用乘法

加上各种移位 取反等指令
单个看还好
一堆嵌套就很恶心

汇编的学习
了解基础指令是干啥的

然后了解堆栈 入栈和出栈
在明白PC寄存器
就差不多了

至于什么浮点数指令
请无视它们
千万别接触

解决vs编译时报错方法

加个宏定义

#define _CRT_SECURE_NO_WARNINGS

或者直接忽略错误

#pragma warning(disable:4996)

两种宏都行

这个是因为c标准更新的问题

游戏插件项目我们只需要一个轻量级hook
太大了 执行文件就很大
虽然这个效率可以忽略不计
但它们的hook项目提供的API本身就不是那么简单

utf-8中文字符会报常量中不能有换行符 的那个错误 也可以用这个方法忽略吗?

尝试 #pragma warning(disable: 2001) 或者  #pragma execution_character_set("utf-8")

建议是用premake5生成vs解决方案

Premake 项目地址:https://premake.github.io/

c++的坑太多了
原因还是因为编译器更新和c/c++标准更新
c++太注重细节 导致很多方面都有一堆关键字和特殊写法格式
这最后导致人们不愿意使用c++的根本原因

c++20挺不错的
建议更新语言标准为c++20
c++20的模块导入比头文件包含更好用
能建立“包”工程