关于Hook函数或偏移的查找以及杂项 - cngege/Mod GitHub Wiki
-
Hook函数 是否显示坐标
特征码:
48 83 EC ? 48 8B 49 ? 48 8B 01 FF 90 ? ? ? ? 48 85 C0 74 ? 48 8B 88函数结构
bool(void*, void*, void*)
使用方法: Hook函数,强制返回true即可强制显示坐标
特征码查找方法:- 先找到能够控制坐标显示的指针
- 搜索字节 0/1
- 然后找"谁访问了这个地址",取在非暂停页面持续调用的一项
^更新
特征码:
01 01 FF FF ? EC 7F 92 73 68 6F 77 63 6F 6F 72 64 69 6E 61 74 65 73 00 0F- 这个特征码和上面的特征码不一样 (必须执行一次
/gamerule showcoordinates false这个特征码才会出现) - 上面说找到能够控制坐标显示的指针 指针就在定位特征码之后的偏移4字节处,也就是? 的位置
- 该位置为 00 时不显示坐标,但查询showcoordinates规则依旧显示true
- 能够控制坐标显示的指针在重新进入存档的时候会失效,所以这个特征码旨在帮助开发者定位这个指针
-
饥饿值(暂时作废)
特征码:
4C 8B D1 44 0F B6 CA 49 BB ? ? ? ? ? ? ? ? 48 B8 ? ? ? ? ? ? ? ? 4C 33 C8 8B C2 4D 0F AF CB C1 E8 08 44 0F B6 C0 8B C2 4D 33 C8 C1 E8 10 4D 8B 42 08 4D 0F AF CB 0F B6 C8 4C 33 C9 8B C2 49 8B 4A 30 4D 0F AF CB 48 C1 E8 18 4C 33 C8 4D 0F AF CB 49 23 C9 48 C1 E1 04 49 03 4A 18 48 8B 41 08 49 3B C0 74 27 48 8B 09 3B 50 10 74 0E 48 3B C1 74 1A 48 8B 40 08 3B 50 10 75 F2 48 85 C0 49 0F 44 C0 49 3B C0 74 05 ? ? ? ? C3 48 8D 05 ? ? ? ? C3函数结构:
void*(void*, void*)
使用方法: 返回值 void* +84 为饥饿值 -
非Hook 非创造模式攻击长度修改
特征码:
84 C0 74 ? C7 45 ? ? ? ? ? 48 8D 85 ? ? ? ? 48 8D 4D ? 44 0F 2F 25 ? ? ? ? 48 0F 43 C1使用方法:
- 定位后往后找到第二个44 0F 2F 25 [指针位置] (第一个是创造模式的攻击长度修改)
- 指针位置为指向攻击长度值得指针偏移,从这个指针位置后得那个字节算起
- 如:
44 0F 2F 25 XX XX XX XX 76则从76所在的这个字节算偏移
特征码查找方法:
- 搜索单浮点 3.00000 ,直至10个以内 挨个修改为7 看看修改哪个攻击长度能加长则定位到关键点
- 然后改创造模式,右键找出谁访问了这个指针,再改生存模式,看看新增的访问改指针处就是该特征码位置
- 访问记录有很多,那么哪个才是我们需要的。
- 很简单, 这么多记录进入反汇编后肯定有一条,在3.0上面有7.0,那么这就是我们需要的
-
函数 破坏方块时调用的TICK
特征码:
48 89 5C 24 ? 48 89 6C 24 ? 56 57 41 56 48 83 EC 30 48 8B D9 0F 29 74 24 ? 48 8B 49 08函数结构:
float(void*, void*, int, float)
使用方法: 第一个参数 + 偏移0x24 设置破坏进度
特征码查找方法:- 1.19.11 :Minecraft.Windows.exe+17C032A
- 先计算出能够瞬间破坏的单浮点地址
- 找出谁改写了这个地址
- 一般只有两个 找到破坏方块时一直触发的那个
-
下落无伤害1 (这个函数只能在不高的地方(7格不跳)下落免伤)
特征码:
40 53 56 57 48 83 EC 50 48 8B 05 ? ? ? ? 48 33 C4 48 89 44 24 ? F2 41 0F 10 01
参数1 void*
参数2 void*
参数3 float* 当前需要的指针 在Hook里将他强制设置为0
参数4 void*
返回值 void*
__int64 __fastcall sub_14175BEB0(__int64 a1, float *a2, float *a3, __int64 *a4)
先搜索空气跳的地址(四字节) :16777473 / 0
出来后有两个地址
一个真一个假
将假的那个地址偏移减去4 (单浮点)锁定0就能下落无伤的地址了
找出谁写入了这个地址 一般是第一个 movss [rbp
反汇编后下面两层有个call 这个值刚好在这个call的参数区域 -
下落无伤害2
特征码:
48 89 5C 24 ? 57 48 83 EC 40 48 8B D9 48 8B FA 48 8B 89 ? ? ? ? 48 8B 01
__int64 __fastcall sub_141932540(__int64 a1, float *a2)
先定位下落无伤的地址
先搜索空气跳的地址(四字节) :16777473 / 0
出来后有两个地址
一个真一个假
将假的那个地址偏移减去4 (单浮点)锁定0就能下落无伤的地址了
找出谁写入了这个地址 这次搜索的是第三个
第一个里面找到能用的call Hook后只能在不高的高度(7格不跳)下落免伤
第二个悬空时 不调用
第四个只在落地的一瞬间调用一次 可能是将这个值归零的
第三个反汇编后 可以看到 rbx+1D4 是关键指针
往下找 第一个call字节太少,不能用特征码定位
第二个call可以 他第一个参数刚好就是rbx的指针
将他加上1D4就能转为float指针 写入0,以打到目的 -
HitBox
特征码:
48 8B C4 48 89 58 ? 48 89 68 ? 56 57 41 56 48 83 EC 70 48 8B EA
__int64 __fastcall sub_1419763A0(__int64 a1, __int64 a2, __int64 a3)
第二个参数+4D0 就是关键指针
调用原函数前修改
搜索关键指针:
搜索单浮点 0.6,kill后搜索0.2
将搜到的指针值改为4 ,看看玩家影子有没有变大
找谁访问了这个指针,一般只有在玩家疾跑的时候才有个
进去往上找call
大概是第三个call 这个call的第二个参数刚好含有 rbx(可以加上偏移变成关键指针)
且经过CE注入测试,在调用原函数前后都可以使用这个rbx加偏移得到关键指针
Rbx +4D0 -
TICK函数 (无用)
Minecraft.Windows.exe+F97BA0
第二行 48 8B 02 mov rax [rdx] Rdx 即为玩家地址, 不过貌似函数参数没有和玩家相关的地址 无法定位特征码 -
本地玩家Tick函数
函数 特征码:
48 83 EC 28 48 8B 91 ? ? ? ? 45 33 C0 48 8B 81 ? ? ? ? 48 2B C2 48 C1 F8 03 66 44 3B C0 73 ? 48 8B 02
Minecraft.Windows.exe+1937C10 1.19.11
double __fastcall sub_141937C10(_QWORD *a1)
第一个参数即为玩家 还可能只是本地玩家
找特征码
先找到本地玩家指针
然后找谁访问了这个指针
一般是第二个 较多的那个mov rdx,[rax]
反汇编后
可以看到 这里rax就是玩家指针
往下两个就是call
而这个call的第一个参数就是 rax,即玩家指针
疑似:

-
玩家位置修改
玩家+偏移4B8 1.19.11
一次改 24字节 24字节共两个xyz坐标,分别是玩家在地图上的两个顶点
-
Player can jump
如何找到这个函数指针
首先找到本地玩家指针 和 正确的 16777473这个能使玩家空气跳的指针
找到玩家到这个指针的偏移 1.19.11 的偏移是 +1D8
函数内容大概是

猜测函数的结构是 void(__fastcall)(Player*,int)
1.19.11 Minecraft.Windows.exe+8236B0 7FF6221F36B0
-
获取玩家位置(可修改的 342 两个坐标点)偏移
48 89 5C 24 ? 57 48 83 EC ? F3 0F 10 02 48 8B D9 F3 0F 58 81
获取玩家位置(可修改的 342 两个坐标点)偏移
public: void __cdecl Actor::moveBBs(class Vec3 const & __ptr64) __ptr64
定位这个函数,
+21 -> int Xoffset X
+X Xpos1 玩家X1位置指针
+X+4 Ypos1 玩家Y1位置指针
+X+8 Zpos1 玩家Z1位置指针
+X+12 Xpos2 玩家X2位置指针
+X+16 Ypos2 玩家Y2位置指针
+X+20 Zpos2 玩家Z2位置指针
两个坐标,第一个坐标的xyz值要小于第二个坐标
x相差:0.5999756
y相差: 1.80000305
z相差: 0.60002518
可以顺便把 HitBox偏移也设置了
就在上面第二个坐标的后面
+X+24 XHitbox 玩家横向碰撞体积的指针
+X+28 YHitBox 玩家纵向碰撞体积的指针
怎么找到这个特征码:
先找到(修改有效的)玩家X坐标地址
找谁修改了这个地址,只有一个
反汇编后就能看到偏移,这个偏移正好正确
这个偏移所在的函数即为这个特征码的地址
void __cdecl Actor::moveBBs(class Vec3 const & __ptr64) __ptr64
特征码:48 89 5C 24 ? 57 48 83 EC ? F3 0F 10 02 48 8B D9 F3 0F 58 81
实体移动消息
获取方法:
找到玩家的坐标,找到谁改写,只有一个,反汇编
按同样的方法进入 BDS反汇编可以知道这条汇编命令所在的call的名称是Actor::moveBBs
-
找玩家视角偏移
0F B6 D0 48 8B CE E8 ? ? ? ? F2 0F 10 86 ? ? ? ? F2 0F 11 86
找特征码:
首先从玩家地址结构中找到玩家视角
一般是这样两对一起 +15

选择第一个找谁访问了这个地址(这个地址只能读,写入无效)
一般第一个
(计数最多的:Actor::getRotation 很短的call 可惜不能特征码定位 )
可以看到上面有个call 下面有几个movsd, 将第一对中的第一第二个视角
传值给到第二对中的第一第二个视角
我们从上面这个call的传入参数部分开始算特征码
(下面是非最多的那些的第一个)

更新至 1.19.50版本以后 玩家的视角存储在一个结构里,这个结构在Player类中以指针的形式存在
也就是说 玩家视角由两个vec2组成,本该占用 4*2 *2 16字节的内存
由于这里以指针的形式存在于玩家类中 所以只占8字节的内存,这8字节是指向玩家视角结构的指针
比如从玩家指针到指向该视角指针的偏移为X
先找到本地玩家地址
然后看地址结构 展开其中的指针,观察指针指向的地址 其前四个float为玩家视角
找到后 将第一个拉入列表
找访问
访问次数高到低排列
选第二个 反汇编,往上可以看到 偏移X的值 从这一行开始计算特征码,拿到这个X的值

-
所有玩家Tick
1.19.11 特征码:48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 48 8B 01 48 8B F2 0F 29 74 24 ? 48 8B D9 0F 28 F2 (更新后函数变量,参数包含了所有实体)
float *__fastcall sub_14198A400(__int64 a1, float *a2, float a3)
1.19.20.02:Minecraft.Windows.exe+1A13950 7FF6FCC73950
第一个参数A1可能是玩家地址
(找到的另外一个函数 : Minecraft.Windows.exe+8FA180 )函数的第四行(无法定位特征码)
(找到的另外一个函数 : Minecraft.Windows.exe+FE5260 )函数的第二行(无法定位特征码)
怎么找:
用本地玩家地址找谁访问了
有很多 从上往下找
(让房间有两个玩家
反汇编,看 找出指令访问的地址,确保只出两个玩家地址,且进入别人房间这条指令也可以用
那这条指令所在的函数就是要找的call
1.19.11:Minecraft.Windows.exe+198A400
?
所有中计数最多?约每秒一千条
public: void __cdecl Dimension::forEachPlayer(class std::function<bool __cdecl(class Player & __ptr64)>)const __ptr64

-
AttributeInstance::_calculateValue
[原型] private: float __cdecl AttributeInstance::_calculateValue(void) __ptr64
属性单例 计算值
由饥饿值 找改写,跳跃自然消耗,选只有一个的第一个
(还有其他属性调用这个函数)
-
Player / Mob / Actor 虚表
以及还有 ServerPlayer 虚表
首先按照上面的方法找到 Player::setPlayerGameType 函数位置
然后退出地图到主界面
硬件断点(这里设置5000 可以视情况再少一点)找调用
调用者既是(可以比对BDS的伪源码得知)Player::Player
大概在伪源码 206 行左右找到 Player 虚表赋值
由此找到 Player虚表


在Player虚表赋值的上一行既是 Mob::Mob 构造函数 进入
在函数的开头即可看到虚表赋值 既是Mob的虚表找到


在Mob虚表赋值的上一行 既是Actor::Actor 构造函数
进入 往下 91行左右 大概能找到 Actor的虚表赋值
由此 Actor的虚表找到


ServerPlayer 虚表
进本地存档
找到Player构造函数结尾
断点找调用
找另外一个玩家进这个房间,触发断点
比对BDS伪源码,可以大致确定
调用者就是 ServerPlayer::ServerPlayer 构造函数
在大概 在源码 94 行左右 有ServerPlayer的虚函数地址赋值
-
isKeyDown
非Hook
特征码:4C 8D 05 ? ? ? ? 89 54 24 ? 88 4C 24
获取方法,进行游戏背包页面,仅在Minecraft.Windows.exe 中搜索
字节搜索 长按F搜索1 放开搜索0
最后得到一个值
找修改 则看到一个函数

这里 [r8+rax*4],edx 是关键信息,可以知道rax是是按键键值
R8 则是怎么键值表的开始,关键找到r8的地址
上面lea这条函数,可根据这条函数计算 从下一条也就是 1B6B0E 往后偏移 42F7422 即键值表
-
KeyUpdate
特征码:48 83 EC ? 0F B6 C1 4C 8D 05 ? ? ? ? 89 54 24
获取方法:
和上面 isKeyDown 一样,这个即是上面特征码所在的函数
__int64 __fastcall sub_1401B6B00(__int64 a1, int a2)
A1 is key
A2 is 是否按下 int 1 按下 int 0 松开
由KeyUpdate 找到MouseUpdate
首先定位到KeyUpdate 断点找调用 100个就行,找到调用处,注意它调用处的位置
找到其调用者开头,断点跟踪,看看它的运行轨迹,(这时没有按下按键他也触发了)
看看它是哪里跳过了call keyUpdate的代码,比如在300调用KeyUpdate,但它运行到 250 就jmp到了400,那就看看250处的代码,在后面一行再断点跟踪,这次发现只要鼠标悬浮在游戏窗口就触发了,然后看它是哪里触发了call,这个call就是调用MouseUpdate
-
发送消息
调用
14059052C
Minecraft.Windows.exe+59052C (1.19.22.01)
函数:
Minecraft.Windows.exe+6D6EF0
原型:__int64 __fastcall sub_1406D6EF0(__int64 a1, __int64 a2)
返回值:u int8 (if ( (unsigned __int8)sub_1406D6EF0(v11, v16) != 1 ))
A2: 聊天输入框内容地址
特征码寻找
E8 ? ? ? ? 3C ? 75 ? 48 8B 8F ? ? ? ? 48 8B 01 4C 89 75
调用处
首先在聊天框输入内容,然后CE搜索字符串,大概只有4、5个值,
找改写
然后改动聊天输入框的值,然后发送,
如果有个值中,只有在发送时调用一次的,则反汇编此处代码
将代码开头ret,会发现,消息发送不出去,用断点找函数运行路径
然后nop函数中调用的函数,看看能不能阻止发送消息
直到nop掉一个call,发送后 输入框清空但没有发送出去
这个call就是目标call,nop的这个位置就是调用处
-
获取鼠标位置:
首先找到CI单例指针
然后查结构
鼠标在游戏窗口内移动
大概在0x400位置,就能找到存储鼠标xy的指针
找访问或者改写
只有一条
代码很短很简单,但可能由于靠前,所以能用特征码定位
特征码:(1.19.30.04)F3 0F 11 89 ? ? ? ? F3 0F 11 91 ? ? ? ? F3 0F 11 99 ? ? ? ? C3
Minecraft.Windows.exe+21D570

前面458 和 45C 分别是相对CI的偏移,特征码定位后 获取这个偏移
(得获得CI的虚表指针后)
还有一种方法,这个函数定是CI的虚表地址,找到这个目标函数后,断点找调用,调用处为:
call qword ptr [rdx+00000818]
这里的818就是虚表偏移 就是将CI的虚表地址加上818就是目标函数的地址,所以可以从调用处这里获取特征码,来获取这个818,利用虚表和偏移找到目标函数地址
-
获取窗口大小
首先模糊搜索float大致大小,搜索几次后找结果中的大概在1000左右的数,然后精确搜索一次这个数。
在剩余的结果中找和CI最近的一个指针
选择它
找改写 反汇编
则这个函数就是我们要找的函数:
1.19.30.04:Minecraft.Windows.exe+217220

这里的+218 21C,就是我们的窗口大小指针相对CI的偏移
这点我们可以在CI的结构里确认
同样可以用上面的方法找虚表函数的偏移(找调用)
这个无法特征码定位,只有找到CI的虚表 用虚表定位了
调用处位置:Minecraft.Windows.exe+545490
-
鼠标调用CALL
原型:
void(__thiscall* Mouse)(__int64 a1, char mouseButton, char isDown, __int16 mouseX, __int16 mouseY, __int16 relativeMovementX, __int16 relativeMovementY, char a8);
函数获取
搜索字节
游戏窗口 鼠标按下为1 松开为0,扫描最后大概剩10条,有一条是7FF开头的
选中这条,找查找,按下和松开鼠标均有访问,进入汇编,找这条函数开头,分析特征码,该函数就是我们的目标函数
1.19.30.04:Minecraft.Windows.exe+307E450
特征码:
48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 54 41 55 41 56 41 57 48 83 EC ? 44 0F B7 BC 24 (来自:https://github.com/NRGJobro/Minecraft-DX12-Hook/blob/master/Hooks/Hooks.h)
48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 54 41 55 41 56 41 57 48 83 EC ? 44 0F