aes256 加密后的长度_虚幻4(ue4)引擎加密pak解包教程(初学者向x64源码逆向)

本文为看雪论坛优秀文章

看雪论坛作者ID:devseed

前言

遇到了喜欢的游戏,想提取壁纸,于是找quickbms等虚幻4引擎解包工具。无奈游戏加密,无法解包。

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

以前接触的OllyDbg都是32位程序,64位稍有不同,这篇教程也算是我的初次接触x64dbg笔记了,包括了我对源码和编译器优化特征的理解,以及如何定位源码和反汇编代码的想法。本教程仅适用于非魔改版引擎和未加壳源码对照分析,以ue 4.23为例。

注意,此教程仅用于逆向学习分析,请勿用于各种侵权行为。完全初学者应该也能很容易看明白,欢迎大家讨论交流,如有错误请多指教~

本文内容与我在隔壁发的完全一样。

观察源码,寻找切入点

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

注意游戏版本要与源码版本一致,否则源码有可能修改对不上,还有此处不讨论魔改版ue4和程序加壳等问题。

v2-a12f8356aac1659f4e702219b8002188_b.jpg

v2-481d884537d29c95e138876fa0c07ef8_b.jpg

看见void DecryptData(uint8* InData, uint32 InDataSize,FGuid InEncryptionKeyGuid)函数,右键findallreference找到相关信息,寻找切入点,我们看到文件IPlatformFilePak.cpp文件中void FPakFile::LoadIndex(FArchive* Reader)函数有fatal error的log,这个可以成为我们的关键点(因为是fatal,一般都会保留log,其他的log可能就没有编译到程序中[1])。

v2-dd5477da19aa02368730374786377cbf_b.jpg

x64dbg寻找切入点

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

v2-0aa8879c8f245778aec5673e80f37fd6_b.jpg

分析函数与找到key

这部分最复杂也最麻烦,主要因为编译器的优化将很多函数变成了inline,

函数前面不一定非得有push rbp,mov rbp,rsp这种典型的语句,而且并不一定函数一定会有call,但是多个嵌套一般最多有嵌套个数个call。

还有要 记住x64与x86反汇编的不同,基本上都是__fastcall, 前四个参数为rcx,rdx,r8,r9(c++ this指针为rcx [2]),剩下的从右向左push,被调用者清理堆栈 [3]。我们的目的是定位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(编译器优化局部变量不一定调用堆栈,有些直接就用寄存器了)。

v2-2de5696ba87430a1b4348a63370075b8_b.jpg

3.2

一直往下拉吧,观察r12b相关的,看见test r12b,r12b 这个就是检查r12b是否为0,因此推断出下一句为if (!bFirstPass),因为jne跳转后直接cmd顺腾摸瓜同时定位了if (Info.bEncryptedIndex)。

v2-aa8c45e8b7e0b2fc197af80d0820e259_b.jpg

3.3

对照源码DecryptData输入3个参数和反汇编mov edx, lea r8, mov rcx 也是3个参数,因此推测光标处的call即为DecryptData函数。Decrypt条件语句中只有一个call因为GetData直接取值了。

v2-396c489d72f7b64af339e1a4bf48086e_b.jpg

v2-90abc98bb7dfd67629cdeb14698d9cca_b.jpg

3.4

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

v2-e36061b10a7b360c2bb582bfd70086a9_b.jpg

v2-82e9b0c5cdac58de4a052517079b7555_b.jpg

v2-aa8c45e8b7e0b2fc197af80d0820e259_b.jpg

3.5

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

经调试并且对照三个参数的意义,发现倒数第二个call即为FAES::DecryptData(InData, InDataSize,Key) !)函数。到此在[rcx]的32字节即为所求的key。

v2-5bd42b6baabe30f668605121bf9c3850_b.jpg

得到key后解包

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

[Unreal EngineInstall]/Engine/Binaries/Win64/UnrealPak.exe -Test [PAK FILE PATH]-cryptokeys=[LOCATION OF crypto.json]

指令即可解开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

v2-6d654f7f0528a43fa6e93c1b3334f39e_b.gif

- End -

看雪ID:devseed

https://bbs.pediy.com/user-617776.htm

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

推荐文章++++

* GandCrab v5.2 分析

* 恶意代码分析中一些常见的非PE样本分析

* 定制Xposed框架

* 通过一道pwn题详细分析retdlresolve技术

* 打造属于自己的渗透神器——WiFi-ducky

v2-86e04047fba1b1599dd0c120c7209735_b.jpg

公众号ID:ikanxue

官方微博:看雪安全

商务合作:wsc@kanxue.com

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值