本帖最后由 Slimu 于 2023-10-8 18:56 编辑
逆向UE4最全的一集
潜水时间过长,水一篇文章
在视频网站上看到许多课程,其中流行使用CE(Cheat Engine)来寻找数据。然而,这种介于模糊搜索、扫描和过滤的方式,不仅效率低下,对于逆向工程帮助甚微。有时候甚至换个游戏都难以取得有效成果。这时候就需要学习更高级的技巧。
随着时间的推移,对于UE4的逆向已经形成了一套成熟的方法和技术
以下介绍几个我认为很强的项目:
-
UnrealDumper-4.25,适用于Windows,早期版本的dump工具
-
UEDumper,适用于Windows,强大的工具
-
UE4Dumper,适用于Android的简单dump数据工具
-
AndUE4Dumper,适用于Android的可扩展dump工具,可导入Android Studio食用
-
iOS_UE4Dumper,适用于iOS的可扩展dump工具,可导入Xcode食用
-
UE4SDKGenerator,适用于Android,强大的工具
通过上述项目,我们可以看到,在逆向UE4游戏时,对于引擎级别的逆向毫无疑问是最为主流和有效的。这些项目提供了强大的功能,能够避免低效的搜索方法,同时能生成可导入到相应平台开发环境中使用的SDK,进而通过调用游戏自身提供的函数和方法来实现相应的功能。
掌握上述项目的使用方法,可轻松应对UE系列的游戏,这里分享我在实际操作中遇到的一些困难。
游戏说明
游戏名: StateOfDecay2 (4.13,无调试符号)
游戏名: Absolver (4.18,有调试符号)
我会通过两者的不同,来介绍当其中一种方法失效后应该怎么做
获取基础信息
首先需要获取游戏的一些基础信息,比如游戏使用的引擎版本、GUObjectArray、GName等,下面是针对4.23以下版本的演示,思路是通用的
引擎版本
-
IDA中搜索字符串:"+UE"
-
在对应目录检查
-
Windows: 游戏目录下运行的可执行文件,右键->属性->详细信息->产品版本
-
-
Android: 游戏apk中的AndroidManifest.xml
<meta-data
android:name="com.epicgames.ue4.GameActivity.EngineVersion"
android:value="4.xx.xx" />
-
iOS: 没试过
GUObjectArray
IDA中搜索字符串:"Max UObject count is invalid. It must be a number that is greater than 0."
-
有调试符号:
-
无调试符号:
-
如果字符串搜索不到,可在源代码中寻找其他的字符串
GName
-
CE搜索字符串:"ByteProperty",在None前下断点
-
IDA对应伪代码:
-
有调试符号:
-
-
无调试符号:
-
-
找到此函数后按X,寻找上层引用(默认是第一个)
-
FName::GetComparisonNameEntry是关键,能够获取到GName
-
解决被修改的问题
-
根据伪代码可以得出:
-
v3 = *a1(解引用,将a1存放的值赋值给v3)
-
返回值为 qword_1445B40C8 + v3
-
检查qword_1445B40C8的值是什么
-
-
当读取此地址的时候发现是空的
-
-
说明需要将此地址加上某个数值才会得到具体的名称
-
检查a1的值,CE下断点在被修改后的函数
-
-
将该值与qword_1445B40C8相加
-
-
OK,成功获取到一个字符串,确认了a1存放的一个ID,但仔细看就会发现还是差了一点。还记得在上面FNameEntry::GetPlainNameString吗,获取FString使用AnsiName或者WideName。通过两者的对比,发现这里偷偷加了一个0x8,且通过对其他的函数的伪代码来看同样如此
-
-
-
-
解决办法也很简单
-
通过读取qword_1445B40C8的值然后加上一个ID,即可得出一个FString
-
又或者使用函数指针,直接传入一个ID也行
总结
通过以上的逆向过程,我们成功地获取了项目所需的基础信息。接下来,只需要将这些偏移填入对应的项目中,就能够成功导出数据了。
尽管这一集相对简单,但仍然存在一些问题。其中,项目默认的配置可能无法适配所有游戏,从而导致生成SDK文件时出现错误。这时我们就需要手动检查每个结构体的偏移,包括UStruct、UFunction、UField、UProperty等。
希望此文章对你有所帮助。感谢造出轮子的人,让逆向变得如此简单。
|