什么是Count?
Count
就是 UE4 引擎开发的游戏在运行过程中动态创建的 Actor
的数量,也可以说是在当前玩家一定范围内的 Actor
的数量。因为如果离得太远,由于游戏性能优化原因,是不会把非常远的 Actor
也获取的。
我们找Count来干啥?
找到 Count
,我们也就找到了 UWorld
、ULevel
和 ActorArray
的地址。因为 Count
的地址都是在 UWorld
里的 ULevel
下的。
而 ActorArray
在 UE4 里其实是一个 TArray
的结构体,第一个变量为一个指针,指向一个存放 Actor
指针的数组,第二个变量 Num
就是这个数组的长度,也就是 UE4 逆向中的 Count
。
所以得出 Count
的地址减去8字节,得到 ActorArray
的地址。我们得到了 Count
和 ActorArray
后,就可以遍历得到所有的 Actor
。
吃鸡模拟器
测试游戏为 Battle Royale Trainer
吃鸡模拟器,是一个 UE4 引擎开发的单机游戏。单机游戏和网络游戏找数据的方法大体是一致的,只是网络游戏找数据时会有更多的干扰。所以都是先以单机游戏练手,等熟悉了数据挖掘的各种技巧,才开始分析网络游戏。
这个测试游戏的辅助的完整源码:http://gitee.com/zhoujianfeng2016/battle-royale-trainer-mfc 。
搜Count的动态地址
首次扫描,4字节,值介于1到2000两者之间。一般游戏开始的时候,Count 只有几十到几百,所以我们搜 2000 内基本是够了。
对着靶子打一枪,因为击中靶子后会创建一个飘动的伤害数值 Actor
,所以可以搜增加的数值。再打再搜,反复操作多次。(不是所有游戏都这样,如果是网络游戏,队友和敌人在战斗过程中,也会不断的产生 Actor,所以还能不断的搜增加的数值)
打空枪,不会创建新的 Actor
。所以搜未变动的数值,重复这两个步骤,最后只剩下少许结果。
把这些结果挨个浏览相关内存区域(Ctrl+B),显示类型改为8字节(HEX)。
我们知道 Count
地址减少8字节,就是 ActorArray
的地址,而 ActorArray
里的数据非常整齐,一眼就可以看出来,我们就以此来确定 Count
地址。
找到正确的 Actor
的数据如下,0000020B
整齐划一:
找到Count基址
对找到的 Count
地址进行指针扫描,修改偏移最大级别,UE4 的 Count
一般都是2级偏移。每个节点的偏移最大相差去掉勾选,还有注意指针扫描的保存路径不能有中文。
扫描出结果后,拖动 指针:
列的宽度调整,观察不会闪动的行。(拖动的时候,会不断的去读取偏移后的地址中当前的数据)
发现有12个,但为了保险起见,我还是把所有地址都保存,然后重启游戏。
重启游戏后,发现12个地址中,还有2个是有效的。UE4 的 Count
基址一般第一层偏移是 30
(第一层偏移是 ULevel
),其中一个就是偏移 30 -> B8
,所以这个地址就是 Count
的基址。
基址
有了 Count
基址后,我们就得到了下面数据:
UWorld:"BattleRoyaleTrainer-Win64-Shipping.exe"+02AEFFB8
ULevel:UWorld -> 30
Count:UWorld -> 30 -> B8
ActorArray:UWorld -> 30 -> B0
联网游戏
联网游戏在搜索 Count
的过程中,会受到其他玩家的干扰。可以先搜1-2000的范围数值,然后多次搜增加的数值,慢慢缩小搜索范围。如果可以找到 Count
就最好,找不到则可以通过其他方式逆推出 Count
的基址。
比如通过人物所处游戏位置的高低变化,找人物 Z 坐标,然后扫描指针,逆推 UWorld
、Count
和 ActorArray
的基址。
根据 UE4 引擎的结构,Count
是在 UWorld
下的 ULevel
下的。而 ULevel
的偏移基本都是 0x30
,这样我们就确定了第一层偏移和第二层偏移大概数值。
对人物 Z 坐标扫描指针后,找出符合偏移的数据,然后使用内存浏览器查看并验证。