Tutorial
Updated
How to extract decryption key for Unreal Engine 4 *.pak files
So lately we got two games that are using index encryption which hides informations about file names, compressed and decompressed sizes + offsets where they are. Assets are not encrypted.
Here I will provide a method how to get 32 bytes hex decryption key from main file. This tutorial is based on Ninjala 2.1 version.
Don't share here keys as this is violation of rules. Provided key in this tutorial has been faked.
This method works only with v7 or newer PAKs. v3 and older don't support native PAK encryption.
For v4-v6 after reading this tutorial look HERE.
Method was checked on those games:
1. Load "main" from exefs to IDA or Ghidra
2. Analyze them so they will be disassembled as much as possible (we don't need any types, demangled symbols, etc. Only assembler)
3. Now next points will depend on what you are using
Here I will provide a method how to get 32 bytes hex decryption key from main file. This tutorial is based on Ninjala 2.1 version.
Don't share here keys as this is violation of rules. Provided key in this tutorial has been faked.
This method works only with v7 or newer PAKs. v3 and older don't support native PAK encryption.
For v4-v6 after reading this tutorial look HERE.
Method was checked on those games:
Code:
- Ninjala 2.1
- Five Nights at Freddy's: Help Wanted 1.22
- FUSER
- Little Nightmares II 1.2
- Shin Megami Tensei V 1.0.1
- BassMaster 2022 1.0.2
- SD GUNDAM BATTLE ALLIANCE 1.3.1
- GetsuFumaDen: Undying Moon 1.1.1
- GHOSTRUNNER 1.8
Requirements:
- IDA or Ghidra (you don't need decompilers) with support for ARM64/AArch64
- Knowledge how to extract main from exefs (you can use nxdumptool) and how to use IDA or Ghidra (I won't explain how to load properly main to them)
- Some time
- IDA or Ghidra (you don't need decompilers) with support for ARM64/AArch64
- Knowledge how to extract main from exefs (you can use nxdumptool) and how to use IDA or Ghidra (I won't explain how to load properly main to them)
- Some time
1. Load "main" from exefs to IDA or Ghidra
2. Analyze them so they will be disassembled as much as possible (we don't need any types, demangled symbols, etc. Only assembler)
3. Now next points will depend on what you are using
IDAGhidra
- 3.1 After finishing analyzing go to Search -> sequence of bytes...
3.2. to showed window paste this:
Code:00 04 00 AD C0 03 5F D6
3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
3.4. Jump to result by pressing on it, we need to find function that will look like this
By this I mean short function that includes three or four lines with "xmmword" text.
If function looks different, then this is wrong function and check other results.
3.5. Press on first xmmword so it will jump to different address (in this case 7106753E30 which you can see after "xmmword_". This way we are at first 16 bytes of our decryption key.
Go to Hex View tab and copy 16 bytes starting from address where xmmword provides (which means 7106753E30).
So in this case we are copying:
Code:12 11 34 56 78 90 12 34 43 21 09 87 65 43 21 00
Go back to last function where xmmwords were. Now go to second xmmword (in this case xmmword_710675B580).
Go to Hex View tab and copy 16 bytes starting from address where xmmword provides (which means 710675B580).
So in this case we are copying:
Code:36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 21
and paste it at the end of file where you have pasted previous 16 bytes. Delete all spaces that are in this file.
Now our decryption key is ready:
Code:1211345678901234432109876543210036363636363636363636363636363621
- 3.1. After finishing analyzing go to Search -> Memory
3.2. Paste to "Search value" window this code:
Code:00 04 00 AD C0 03 5F D6
3.3. 3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
3.4. Jump to result by pressing on it, we need to find function that will look like this
In Ghidra case we have little trouble because on how advanced analyze you had you will get different output in disassembler window. Maybe the best solution will be to check if function you have has 5 or 6 instructions. If not, it's wrong and you should check other results.
DAT_ can be named differently dependent on quality of analyze. Have that in mind.
3.5. Press on first "offset DAT_" (in this case "offset DAT_7106753e30") so you will jump to different offset. You are now at the beginning of first 16 bytes of decryption key. Go to "Bytes: " window and copy 16 bytes starting from offset where DAT pointed us (in this case 7106753e30)
So in this case we are copying:
Code:12 11 34 56 78 90 12 34 43 21 09 87 65 43 21 00
Go back to last function where "offset DAT_" were. Now go to second "offset DAT_" (in this case DAT_710675b580) and now we are at last 16 bytes of decryption key.
Again go to "Bytes: " window and copy 16 bytes starting from offset where DAT pointed us (in this case 710675b580)
So in this case we are copying:
Code:36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 21
and paste it at the end of file where you have pasted previous 16 bytes. Delete all spaces that are in this file.
Now our decryption key is ready:
Code:1211345678901234432109876543210036363636363636363636363636363621
Last edited by masagrator,