小木曾雪菜 发表于 2019-11-19 12:11

虚幻4(ue4)引擎加密pak解包教程(初学者向x64源码逆向)

本帖最后由 小木曾雪菜 于 2019-11-19 12:56 编辑

0. 前言:
遇到了喜欢的游戏,想提取壁纸,于是找quickbms等虚幻4引擎解包工具。无奈游戏加密,无法解包。
不知密钥情况下,也没在网上找到现成的加密pak解包工具。
想到Unreal4已经开源,就尝试着自己找一下密钥,也算是对照源码的x64逆向分析调试。
以前接触的ollydbg都是32位程序,64位稍有不同,这篇教程也算是我的初次接触x64dbg笔记了,
包括了我对源码和编译器优化特征的理解,以及如何定位源码和反汇编代码的想法。

本教程仅适用于非魔改版引擎和未加壳源码对照分析,以ue 4.23为例。
注意,此教程仅用于逆向学习分析,请勿用于各种侵权行为。

完全初学者应该也能很容易看明白,欢迎大家讨论交流,如有错误请多指教~

1. 观察源码,寻找切入点
我用的vscode,搜索关键字decrypt。我们发现FAES:: Key结构,就是加密key,去epic官网查发现是aes256加密。
注意游戏版本要与源码版本一致,否则源码有可能修改对不上,还有此处不讨论魔改版ue4和程序加壳等问题。


看见void DecryptData(uint8* InData, uint32InDataSize, FGuid InEncryptionKeyGuid)函数,右键findallreference找到相关信息,寻找切入点。
我们看到文件IPlatformFilePak.cpp文件中voidFPakFile::LoadIndex(FArchive* Reader)函数有fatal error的log,这个可以成为我们的关键点。
(因为是fatal,一般都会保留log,其他的log可能就没有编译到程序中。
比如https://www.52pojie.cn/thread-907938-1-1.html中的"No valid decryption key specified",不知道是新版ue4还是游戏没编译这个log,查不到这个字符串)。


2. x64dbg寻找切入点,
(为了减少break,在setting中只勾选entry和attach breakpoint,但是不知为什么还是在raiseerror中断?)
右键搜索all module,reference string "Corrupted index offset in pak file.",可以定位void FPakFile::LoadIndex(FArchive* Reader)函数了。


3. 分析函数与找到key
这部分最复杂也最麻烦,主要因为编译器的优化将很多函数变成了inline,
函数前面不一定非得有push rbp,mov rbp,rsp这种典型的语句,而且并不一定函数一定会有call,但是多个嵌套一般最多有嵌套个数个call。
还有要记住x64与x86反汇编的不同,基本上都是__fastcall, 前四个参数为rcx,rdx,r8,r9(c++ this指针为rcx ),剩下的从右向左push,被调用者清理堆栈 。
我们的目的是定位void DecryptData(uint8* InData, uint32 InDataSize, FGuidInEncryptionKeyGuid),FAES::DecryptData(InData,InDataSize, Key),函数找到KEY这个数据结构。
不需要弄清楚加密原理(其实也没什么必要,应该是调用了标准的aes256加密算法),因此对照源码关注Jump类指令即可,一般JGE为if(a<b), JNE为if(!a)。
有时也可以通过观察源码和反汇编看到跳过大段内容来定位。具体本例的切入点:
3.1观察源码bool bFisrtPass=True,同时看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个参数,因此推测光标处的call即为DecryptData函数。
Decrypt条件语句中只有一个call因为GetData直接取值了。

3.4 DecryptData函数在反汇编中就比较混乱了,因为出现了大量的inline函数,好多小的跳转,我们先找大的跳转来定位。可以在graph视图下粗鲁看,然后在cpu中标记。


3.5 最后找key就要耐心调试一下了,关键是注意FPakPlatformFile::GetPakEncryptionKey(Key,InEncryptionKeyGuid),FAES::DecryptData(InData,InDataSize, Key),
这两步和key相关,调试的时候要关注call之前ecx(c函数,rcx为第一个参数),r8(第三个参数)存储地址指向的值(即,),多次循环到此步骤是否相等来判断key。
还有key特点一般是256bit(即memory dump中的两列)看起来比较随机,一般不会出现特别整齐的。经调试并且对照三个参数的意义,发现倒数第二个call即为FAES::DecryptData(InData, InDataSize,Key)函数。到此在的32字节即为所求的key。


4. 得到key后解包
用base 64得到asci字符串,并且参考的crypto.json文件用
/Engine/Binaries/Win64/UnrealPak.exe -Test -cryptokeys=,
指令即可解开pak文件。然后再用umodel来查看即可,一些文件可以转换为png等。

Refer:
(1) https://blog.jamie.holdings/2019/03/23/reverse-engineering-aes-keys-from-unreal-engine-4-projects/
(2) https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
(3) https://softwareengineering.stackexchange.com/questions/245668/where-does-this-go-in-a-x64-thiscall
(4) https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-architecture
(5) https://docs.unrealengine.com/en-US/API/Runtime/Core/Misc/FAES/FAESKey/index.html
(6) https://base64.guru/converter/encode/hex

小木曾雪菜 发表于 2019-11-19 12:52

SherryMefum 发表于 2019-11-19 12:48
ue4,C++?

是的ue4引擎就是c++写的

Akkariins 发表于 2021-9-16 13:20

大佬你好,想问一下我已经照着操作拿到 AES 密钥了,但是用 UnrealPak.exe 加载 pak 文件的时候始终提示这个:
LogInit: Display: Loading text-based GConfig....
LogPaths: Warning: No paths for game localization data were specifed in the game configuration.
LogInit: Warning: No paths for engine localization data were specifed in the engine configuration.
LogPakFile: Display: Parsing crypto keys from a crypto key cache file
LogPakFile: Error: Unable to open pak file "O:\Project\Game\Paks\paks/pakchunk0-Android_ASTC.pak".
LogPakFile: Display: Unreal pak executed in 0.000749 seconds
即使没有设置密钥也是同样的错误,我也试过换其他引擎版本,4.24、4.25、4.26 都试过了,自带的 UnrealPak 都解不了。
然后还试过 QuickBMS,结果也不行:
Error: incomplete input file -10:
       Can't read 4 bytes from offset 00000000.
       Anyway don't worry, it's possible that the BMS script has been written
       to exit in this way if it's reached the end of the archive so check it
       or contact its author or verify that all the files have been extracted.
       Please check the following coverage information to know if it's ok.


Last script line before the error or that produced the error:
319 get NAMESZ signed_long TOC_FILE
coverage file 0   0%   312      773549050. offset 00000000

Press ENTER or close the window to quit
不知道是哪里的问题

SherryMefum 发表于 2019-11-19 12:48

ue4,C++?

cskie 发表于 2019-11-19 13:05

天天向上

kijone 发表于 2019-11-19 13:13

这么高端的技术贴居然只是为了获得壁纸?

委员长_ 发表于 2019-11-19 13:36

这个不错,感谢分享

论坛搅屎棍 发表于 2019-11-19 13:47

本帖最后由 论坛搅屎棍 于 2019-11-19 16:23 编辑

大老牛逼

Godopa 发表于 2019-11-19 13:51

这个厉害。

朽殇 发表于 2019-11-19 14:18

学习学习,谢谢楼主分享!!!!

海细123 发表于 2019-11-19 14:30

感谢分享。
页: [1] 2 3 4
查看完整版本: 虚幻4(ue4)引擎加密pak解包教程(初学者向x64源码逆向)