1
1
# based on: https://github.com/Razmoth/PGRStudio/blob/master/AssetStudio/PGR/PGR.cs
2
+ import re
2
3
from typing import Tuple , Union
3
4
4
5
from ..streams import EndianBinaryReader
@@ -20,7 +21,8 @@ def set_assetbundle_decrypt_key(key: Union[bytes, str]):
20
21
21
22
def read_vector (reader : EndianBinaryReader ) -> Tuple [bytes , bytes ]:
22
23
data = reader .read_bytes (0x10 )
23
- key = reader .read_string_to_null ().encode ("utf-8" , "surrogateescape" )
24
+ key = reader .read_bytes (0x10 )
25
+ reader .Position += 1
24
26
25
27
return data , key
26
28
@@ -32,6 +34,28 @@ def decrypt_key(key: bytes, data: bytes, keybytes: bytes):
32
34
return bytes (x ^ y for x , y in zip (data , key ))
33
35
34
36
37
+ def brute_force_key (
38
+ fp : str ,
39
+ key_sig : bytes ,
40
+ data_sig : bytes ,
41
+ pattern : re .Pattern = re .compile (rb"(?=(\w{16}))" ),
42
+ verbose : bool = False ,
43
+ ):
44
+ with open (fp , "rb" ) as f :
45
+ data = f .read ()
46
+
47
+ matches = pattern .findall (data )
48
+ for i , key in enumerate (matches ):
49
+ if verbose :
50
+ print (f"Trying { i + 1 } /{ len (matches )} - { key } " )
51
+ signature = decrypt_key (key_sig , data_sig , key )
52
+ if signature == UNITY3D_SIGNATURE :
53
+ if verbose :
54
+ print (f"Found key: { key } " )
55
+ return key
56
+ return None
57
+
58
+
35
59
def to_uint4_array (source : bytes , offset : int = 0 ):
36
60
buffer = bytearray (len (source ) * 2 )
37
61
for j in range (len (source )):
@@ -46,16 +70,25 @@ class ArchiveStorageDecryptor:
46
70
substitute : bytes = bytes (0x10 )
47
71
48
72
def __init__ (self , reader : EndianBinaryReader ) -> None :
49
- if DECRYPT_KEY is None :
50
- raise LookupError (
51
- "The BundleFile is encrypted, but no key was provided!\n You can set the key via UnityPy.set_assetbundle_decrypt_key(key)"
52
- )
53
73
self .unknown_1 = reader .read_u_int ()
54
74
55
75
# read vector data/key vectors
56
76
self .data , self .key = read_vector (reader )
57
77
self .data_sig , self .key_sig = read_vector (reader )
58
78
79
+ if DECRYPT_KEY is None :
80
+ raise LookupError (
81
+ "\n " .join (
82
+ [
83
+ "The BundleFile is encrypted, but no key was provided!" ,
84
+ "You can set the key via UnityPy.set_assetbundle_decrypt_key(key)." ,
85
+ "To try brute-forcing the key, use UnityPy.helpers.ArchiveStorageManager.brute_force_key(fp, key_sig, data_sig)" ,
86
+ f"with key_sig = { self .key_sig } , data_sig = { self .data_sig } ,"
87
+ "and fp being the path to global-metadata.dat or a memory dump." ,
88
+ ]
89
+ )
90
+ )
91
+
59
92
signature = decrypt_key (self .key_sig , self .data_sig , DECRYPT_KEY )
60
93
if signature != UNITY3D_SIGNATURE :
61
94
raise Exception (f"Invalid signature { signature } != { UNITY3D_SIGNATURE } " )
0 commit comments