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跳到你自己的函数
然后直接就能使用了
示例:
// 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的模块导入比头文件包含更好用
能建立“包”工程