UE4找Actor区分标识

标识的作用

我们如何区分 ActorArray 中的 Actor 是敌人、队友、自己、物品还是其他东西?比较通用的做法是对比多个 Actor 的结构,找出不同类型的 Actor 在同一偏移,数值的异同规律。

比如在 Actor 下 0x555 偏移,类型为 4 Bytes,是敌人的时候这个数值为0,是队友的时候数值为1,是自己的时候数值为2,不是人的时候数值为3。这样就可以区分出人和其他物品,并且可以区分出人里面的敌人、队友和自己。这就是找标识的作用。

由于我测试的游戏是一个单机游戏,相对来说是比较容易对比 Actor 结构中的数据。

找出区分的标识

先遍历 ActorArray 并绘制所有 Actor 的地址,然后观察绘制出来的地址。发现自己身上有多个地址,这是因为身上的装备也是 Actor。

我发现在人物播放闲置动画或下蹲的时候,不会移动的是人物的地址,会移动的是物品的地址。(只是刚好这个游戏是这样的)

还有一种区分方式是把自己身上的所有地址都添加到 CE 地址列表,然后挨个浏览内存区域,类型改为 float,将附近的 1.0 数值改为其他数值检查人物是否有加速效果。如果有加速效果,则说明这地址是人物的地址。这是 UE4 引擎结构的原因,加速控制的数值就是 Actor 下面很靠前的偏移,类型是 float。

注意:有些第一人称游戏,看不到自己身上的一些地址,可以通过调整坐标,让地址显示出来。比如调整自己的 x 坐标增加 50-200,再转屏幕坐标。这样就可以把本该绘制在自己身上的地址绘制在自己旁边。

Actor内存布局

使用自己的人物地址、多个敌人的人物地址、物品的地址去结构分析,找到能够区分他们的条件。

Actor内存布局分析

观察自己的人物数值、敌人的人物数值、物品数值:

  • 自己的人物数值和所有敌人的人物数值相同,但于物品的数值不同,则可用来区分人物和物品。
  • 自己的人物数值、所有敌人的人物数值、物品的数值都不同,可以用来区分是自己还是敌人。

Actor数值对比

偏移数据记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
人物和模型区分
50 1-人物 0-模型-----------没变
54 4-人物 0-模型-----------没变
84 258-人物 2-模型-----------没变
B8 512-人物 0-模型-----------没变
138 3-人物 1-模型 float-----------没变
154 4-人物 0-模型-----------没变
298 10-人物 2-模型-----------没变
29C 24-人物 4-模型-----------没变
2A0 1023-人物 3-模型-----------没变
2B8 10-人物 2-模型-----------没变
2C8 2-人物 1-模型-----------没变
2D8 16-人物 1-模型-----------没变
308 6-人物 2-模型-----------没变
30C 24-人物 4-模型-----------没变

自己和敌人区分
150 3-自己 1-敌人 0-模型

网络游戏

在网络游戏中,敌人和队友可不会站桩等你去对比数据,所以可以将想要对比的 Actor 地址挨个结构分析并保存数值到本地 txt 文本文件,然后再用其他文本对比工具来对比数据。比如免费开源的 WinMerge。

我们可以在代码中实现拷贝 Actor 地址到剪贴板,从而实现快速收集需要分析的结构。

比如我可以像自瞄那样计算目标到准星的距离,将距离准星距离最新的 Actor 在我们按下某个快捷键的时候绘制出特殊的文字(文字更大、颜色和其他不一样之类的),并且使用拷贝这个地址到剪贴板。

UE4更好的区分标识办法

在 UE4 中,我们除了通过上面说的找不同 Actor 的异同标识来区分类型外,还有一种更精准并且更容易的方式。

首先需要熟悉一个 UE4 的固定结构,也就是 UWorld -> GameInstance -> LocalPlayer -> PlayerController -> APawn,而 APawn 则和 ActorArray 中某个 Actor 是同一个对象,也就是玩家自己的 Actor。

有了这个结构,我们就可以在遍历 ActorArray 的时候,判断和 APawn 地址相同的 Actor 就是玩家自己。

GName查找和算法

  1. 字符串搜索 MulticastDelegateProperty
  2. 搜到结果后,查看内存浏览器,切换到字节类型显示
  3. 向上翻,查找顶部有没有 ….*.None 开头
  4. 如果是则鼠标放 * 上,得到一个地址,加入地址列表里:

GName搜索

对这个地址搜索16进制8字节,得到一个静态地址:

静态地址

这个静态地址减去 0x10,就是 Gname 入口地址:

Gname入口

读出每个 Actor 的蓝图类名后,像绘制基址那样绘制出来,观察并区分即可。