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的模块导入比头文件包含更好用
能建立“包”工程