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:
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


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

  1. 3.1 After finishing analyzing go to Search -> sequence of bytes...
    upload_2020-10-3_19-38-4.png

    3.2. to showed window paste this:
    Code:
    00 04 00 AD C0 03 5F D6
    check "Find all occurences" and press OK
    upload_2020-10-3_19-39-11.png


    3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
    upload_2020-10-3_19-41-0.png


    3.4. Jump to result by pressing on it, we need to find function that will look like this
    upload_2020-10-3_19-42-58.png


    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).
    upload_2020-10-3_19-49-16.png


    So in this case we are copying:
    Code:
    12 11 34 56 78 90 12 34  43 21 09 87 65 43 21 00
    And paste it somewhere, for example to text file and save it.

    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).
    upload_2020-10-3_19-52-6.png

    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
  2. 3.1. After finishing analyzing go to Search -> Memory
    upload_2020-10-3_19-57-33.png


    3.2. Paste to "Search value" window this code:
    Code:
    00 04 00 AD C0 03 5F D6
    Be sure format is checked as "Hex" and press "Search All".
    upload_2020-10-3_19-58-51.png


    3.3. 3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
    upload_2020-10-3_19-59-42.png


    3.4. Jump to result by pressing on it, we need to find function that will look like this
    upload_2020-10-3_20-0-18.png


    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)
    upload_2020-10-3_20-4-30.png


    So in this case we are copying:
    Code:
    12 11 34 56 78 90 12 34 43 21 09 87 65 43 21 00
    Paste it somewhere, for example to text file, and save it.

    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)

    upload_2020-10-3_20-7-15.png


    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,

jmga

Member
Newcomer
Joined
Nov 9, 2021
Messages
5
Trophies
0
Age
32
XP
37
Country
Spain
I'm curious of what I'm doing wrong, I found the addresses easily:
ADRP X8, #xmmword_51B1180@PAGE
ADRP X9, #xmmword_51AFD20@PAGE
LDR Q0, [X8,#xmmword_51B1180@PAGEOFF]
LDR Q1, [X9,#xmmword_51AFD20@PAGEOFF]
STP Q0, Q1, [X0]
RET

But the resulting key seems a bit akward, the first 16 bytes are the ASCII characters for Ftexture, the second 16 bytes are mostly 0.

First 16 bytes:
46005400650078007400750072006500
Second 16 bytes:
80BB0000000000000200000000000000

Any clue?
Thanks.
 

masagrator

The patches guy
OP
Developer
Joined
Oct 14, 2018
Messages
6,265
Trophies
3
XP
12,025
Country
Poland
I'm curious of what I'm doing wrong, I found the addresses easily:


But the resulting key seems a bit akward, the first 16 bytes are the ASCII characters for Ftexture, the second 16 bytes are mostly 0.

First 16 bytes:

Second 16 bytes:


Any clue?
Thanks.
What game and UE4 version is this game using?

I tested this method only with 4.23/v8.23 games, I'm not sure about other versions.
 

jmga

Member
Newcomer
Joined
Nov 9, 2021
Messages
5
Trophies
0
Age
32
XP
37
Country
Spain
Thanks, I will keep investigating.

EDIT: I finally could do it with Ghidra, strange because it didn't even resolved the addresses during my previous attempts.
 
Last edited by jmga,

Kimkadamura

Member
Newcomer
Joined
Nov 12, 2021
Messages
18
Trophies
0
Age
33
XP
265
Country
United States
I'm trying to decrypt smtv with unreal 4.23
according to what i did
The first is -removed-
The second is -removed-
But I can't decrypt because the key doesn't match
 
Last edited by Kimkadamura,

Kimkadamura

Member
Newcomer
Joined
Nov 12, 2021
Messages
18
Trophies
0
Age
33
XP
265
Country
United States
I don't know if I should like it or be sad because I said my method was half right.
#xmmword_71051B1180@PAGE
#xmmword_71051AFD20@PAGE
I saw two addresses like this

It seems to use this value
but could not actually decrypt
I want to know if there is anything wrong with my process or something to point out
 
Last edited by Kimkadamura,

masagrator

The patches guy
OP
Developer
Joined
Oct 14, 2018
Messages
6,265
Trophies
3
XP
12,025
Country
Poland
I don't know if I should like it or be sad because I said my method was half right.
#xmmword_71051B1180@PAGE
#xmmword_71051AFD20@PAGE
I saw two addresses like this
***
***
It seems to use this value
but could not actually decrypt
I want to know if there is anything wrong with my process or something to point out
As I said - your halfs are right. You don't need to share them again to break rules... again. Just connect first one with second one and you have a key. Nothing more to do here in this topic as this is not a topic for discussing unpacking PAKs.
 

Kimkadamura

Member
Newcomer
Joined
Nov 12, 2021
Messages
18
Trophies
0
Age
33
XP
265
Country
United States
As I said - your halfs are right. You don't need to share them again to break rules... again. Just connect first one with second one and you have a key. Nothing more to do here in this topic as this is not a topic for discussing unpacking PAKs.
Ah, I guess I got the key value right. Thank you.
I tried putting the value with this key in umodel.exe, but it kept saying the key didn't match, so I asked if I got the key value wrong.
Thank you for replying until now.
 
Last edited by Kimkadamura,

Eiffel2018

Well-Known Member
Member
Joined
Aug 23, 2020
Messages
1,582
Trophies
3
Age
24
XP
10,201
Country
Hong Kong
How to extract the GNames and GObjects ?

For developing cheats like https://gbatemp.net/threads/minecraft-dungeons-01006c100ec08000.605579/
, I need to get the classes and their properties names

e.g. Minecraft dungeon
Code:
[[[[[[GEngine]+GameEngine.GameInstance]+GameInstance.LocalPlayers]]+LocalPlayer.PlayerController]+PlayerController.Character]+PlayerController.bCanBeDamaged


[[[[[[[[[GEngine]+GameEngine.GameInstance]+GameInstance.LocalPlayers]]+LocalPlayer.PlayerController]+PlayerController.Character]++Player.AbilitySystem]+AbilitySystem.SpawnedAttributes]+8]+Movement.SpeedMultiplier


+E48 Player.PlayerExperienceComponent
    +Experience.mxp 160

+1108 Player.ArrowItemSlot
    +ItemSlot.Count 1EC

+1190 HealthComponent
    +104 ResistDeath
    +105 Invincible
    
+80 bit#4 PlayerController.bCanBeDamaged
The above I found in PC version, but I don't know how to find them in NS purely.
I just want to know the principle of the cracking method, it doesn't matter if there is no tool
 

masagrator

The patches guy
OP
Developer
Joined
Oct 14, 2018
Messages
6,265
Trophies
3
XP
12,025
Country
Poland
How to extract the GNames and GObjects ?

For developing cheats like https://gbatemp.net/threads/minecraft-dungeons-01006c100ec08000.605579/
, I need to get the classes and their properties names

e.g. Minecraft dungeon
Code:
[[[[[[GEngine]+GameEngine.GameInstance]+GameInstance.LocalPlayers]]+LocalPlayer.PlayerController]+PlayerController.Character]+PlayerController.bCanBeDamaged


[[[[[[[[[GEngine]+GameEngine.GameInstance]+GameInstance.LocalPlayers]]+LocalPlayer.PlayerController]+PlayerController.Character]++Player.AbilitySystem]+AbilitySystem.SpawnedAttributes]+8]+Movement.SpeedMultiplier


+E48 Player.PlayerExperienceComponent
    +Experience.mxp 160

+1108 Player.ArrowItemSlot
    +ItemSlot.Count 1EC

+1190 HealthComponent
    +104 ResistDeath
    +105 Invincible
 
+80 bit#4 PlayerController.bCanBeDamaged
The above I found in PC version, but I don't know how to find them in NS purely.
I just want to know the principle of the cracking method, it doesn't matter if there is no tool
This is not a thread to ask this kind of questions.

Edit: I see after reaction you have used that you're not even worth replying in the future. Ignore.
 
Last edited by masagrator,
  • Haha
Reactions: Eiffel2018

Eiffel2018

Well-Known Member
Member
Joined
Aug 23, 2020
Messages
1,582
Trophies
3
Age
24
XP
10,201
Country
Hong Kong
Last edited by Eiffel2018,

maztz

New Member
Newbie
Joined
Sep 14, 2022
Messages
4
Trophies
0
Age
17
Location
USA
XP
35
Country
United States
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.

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

All of them are using Unreal Engine 4.24.x, other versions may have different function for using it so if this tutorial won't work for some game, write comment in this thread.

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


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

  1. 3.1 After finishing analyzing go to Search -> sequence of bytes...
    View attachment 226951
    3.2. to showed window paste this:
    Code:
    00 04 00 AD C0 03 5F D6
    check "Find all occurences" and press OK
    View attachment 226952

    3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
    View attachment 226953

    3.4. Jump to result by pressing on it, we need to find function that will look like this
    View attachment 226955

    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).
    View attachment 226957

    So in this case we are copying:
    Code:
    12 11 34 56 78 90 12 34  43 21 09 87 65 43 21 00
    And paste it somewhere, for example to text file and save it.

    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).
    View attachment 226958
    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
  2. 3.1. After finishing analyzing go to Search -> Memory
    View attachment 226959

    3.2. Paste to "Search value" window this code:
    Code:
    00 04 00 AD C0 03 5F D6
    Be sure format is checked as "Hex" and press "Search All".
    View attachment 226960

    3.3. 3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
    View attachment 226961

    3.4. Jump to result by pressing on it, we need to find function that will look like this
    View attachment 226962

    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)
    View attachment 226963

    So in this case we are copying:
    Code:
    12 11 34 56 78 90 12 34 43 21 09 87 65 43 21 00
    Paste it somewhere, for example to text file, and save it.

    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)

    View attachment 226966

    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
I am using ida, when I search for the code the search fails. I'm trying Friday The 13th.
 

masagrator

The patches guy
OP
Developer
Joined
Oct 14, 2018
Messages
6,265
Trophies
3
XP
12,025
Country
Poland
I am using ida, when I search for the code the search fails. I'm trying Friday The 13th.
Game on top of encrypting stuff is also using modified PAK. So my tutorial won't work in your case. On PC there is a custom QuickBMS script for Friday 13th that you can find on zenhax, but it seems it's not compatible with Switch pak.
 
Last edited by masagrator,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Black_Manta_8bit @ Black_Manta_8bit: hey