UE源码版编译-Unreal 4(ue4)引擎加密pak解包教程(初学者逆向x64源代码)

本文是看学论坛上的一篇优秀文章

看学论坛作者ID:devseed

前言

遇到自己喜欢的游戏,想要提取壁纸,于是找到了quickbms这样的Unreal 4引擎解包工具。 不幸的是,游戏已加密,无法解压。

在不知道秘钥的情况下,我在网上并没有找到现成的加密pak解包工具。 想到Unreal4已经开源了,就尝试自己找到秘钥,也算是针对源代码的x64逆向分析调试。

我之前接触过的OllyDbg都是32位程序,64位略有不同。 本教程可以算是我第一次接触x64dbg的笔记,包括我对源代码和编译器优化特性的理解,以及如何定位源代码和反汇编代码。 的意见.

本教程仅适用于非魔改引擎和免杀源码的对比分析,以ue 4.23为例。

注意,本教程仅用于逆向学习分析,请勿用于各种侵权行为。

完全的初学者应该能够轻松理解它。 欢迎您一起探讨、交流。 如有错误,还请指教~

这篇文章的内容和我在对门发的内容一模一样。

观察源码,找到入口点

我用的是vscode,搜索关键字decrypt。 我们发现FAES::Key结构体就是加密密钥,并在epic官网查了[5],发现是aes256加密。

注意游戏版本一定要和源码版本一致,否则源码可能不正确UE源码版编译,不存在magic修改版本ue4、程序反杀等问题。

参见void DecryptData(uint8* InData, uint32 InDataSize, FGuid InEncryptionKeyGuid)函数,右键findallreference查找相关信息,找到入口点,我们在文件IPlatformFilePak.cpp中看到void FPakFile::LoadIndex(FArchive* Reader)函数文件中有致命错误日志,这可以成为我们的关键点(因为是致命的,所以一般会保留该日志,而其他日志可能不会被编译到程序中[1])。

x64dbg 找到入口点

(为了缓解中断,只在设置中检查entry并附加断点,但不知道为什么还是被raiseerror中断?)右键搜索所有模块,引用字符串“Corrupted index offset in pak file.”,可以找到 void FPakFile::LoadIndex( FArchive* Reader) 函数。

分析函数并寻找关键点

这部分是最复杂、最麻烦的,主要是编译器的优化使得很多函数内联,

典型的句子如push rbp、mov rbp、rsp不一定要跟在函数后面,函数也不一定有调用,但多重嵌套通常有最大嵌套调用数。

还记得x64和x86反汇编的区别,基本上__fastcall,前四个参数是rcx,rdx,r8,r9(c++这个指针是rcx[2]),剩下的都是从右向左压入,被调用者清除堆栈[3]。

我们的目的是定位void DecryptData(uint8* InData, uint32 InDataSize, FGuidInEncryptionKeyGuid), FAES::DecryptData(InData, InDataSize, Key),该函数找到KEY的数据结构。

不需要弄清楚加密原理(其实也没有必要,应该调用标准的aes256加密算法),按照源码中的跳转指令即可。 一般来说,JGE 是 if(a

有时也可以通过观察源码和反汇编来定位,看到跳过了一大段内容。 本例的具体切入点:

3.1

观察源码bool bFisrtPass=TrueUE源码版编译,同时看x64dbg中的反汇编mov r12b,1猜测r12b可能代表bFisrtPass(编译器不一定优化局部变量调用栈,有的直接使用寄存器) 。

3.2

继续往下滚动,观察相关的r12b,看到test r12b,r12b 这是检查r12b是否为0,所以推测下一句是if(!bFirstPass),因为jne跳转后cmd直接查找并定位if (Info.bEncryptedIndex)。

3.3

根据源代码DecryptData输入3个参数,反汇编mov edx, lea r8, mov rcx也有3个参数,因此推断光标处调用的是DecryptData函数。 Decrypt 条件句中只有一次调用,因为 GetData 直接取值。

3.4

DecryptData函数在反汇编中比较混乱,因为内联函数很多,小跳转也很多,我们先找到大跳转来定位。 可以在graph视图中粗略的看一下,然后在cpu中进行标记。

UE源码版编译-Unreal 4(ue4)引擎加密pak解包教程(初学者逆向x64源代码)

3.5

最后还需要耐心调试才能找到关键。 关键是要注意FPakPlatformFile::GetPakEncryptionKey(Key,InEncryptionKeyGuid)、FAES::DecryptData(InData,InDataSize, Key)。 这两个步骤是和key相关的。 调试时要注意ecx(c函数,rcx为第一个参数)之前的调用,r8(第三个参数)存储的是地址指向的值(即[rcx],[r8]),并多次循环执行该步骤,判断key是否相等。

此外,关键特征通常是 256 位(即内存转储中的两列),它看起来是随机的,通常看起来不太整齐。

经过调试对比三个参数的含义,发现倒数第二个调用的是FAES::DecryptData(InData, InDataSize,Key) !)函数。 至此,[rcx]中的32字节就是请求的key。

拿到钥匙后开箱

使用base 64得到asci字符串[6],并引用[1]的crypto.json文件

[Unreal EngineInstall]/Engine/Binaries/Win64/UnrealPak.exe -Test [PAK 文件路径] -cryptokeys=[crypto.json 的位置]

命令解压 pak 文件。 然后用umodel查看,有的文件可以转成png等。

参考:

(1)

(2)

(3)

(4)

(5)

(6)

- 结尾 -

看学 ID:devseed

*本文由看学论坛devseed原创创作,转载时请注明来自看学社区

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 UE源码版编译-Unreal 4(ue4)引擎加密pak解包教程(初学者逆向x64源代码) https://www.wkzy.net/game/169973.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务