-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathConfigDecrypter.py
More file actions
70 lines (54 loc) · 1.84 KB
/
ConfigDecrypter.py
File metadata and controls
70 lines (54 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import hashlib
import os
from Crypto.Cipher import AES
import struct
import argparse
'''
[Config Resource Format]
0x00: resource size (4 bytes)
0x04: AES key seed (32 bytes)
0x16: AES IV seed (32 bytes)
0x30: AES encrypted config
[Decrypted Config Format]
0x00: config size (4 bytes)
0x04: some crap (idk yet)
0x08: start of config XML
'''
class ConfigDecrypter:
def __init__(self, config):
self.config = config[0x30:]
self.aes_key = self.running_sha256(config[:0x20])
self.aes_iv = self.running_sha256(config[0x10:0x30])
@staticmethod
def running_sha256(initial_data):
hash_data = initial_data
while 1:
sha256_hash = hashlib.sha256(hash_data).digest()
hash_data += sha256_hash
if len(hash_data) > 0x1000:
break
return sha256_hash
def decrypt(self, data=None):
if data is None:
data = self.config
cipher = AES.new(self.aes_key, AES.MODE_CBC, self.aes_iv[:16])
decrypted_data = cipher.decrypt(data)
config_length = struct.unpack('<I', decrypted_data[:4])[0]
config_length += 0x08
return decrypted_data[0x08:config_length]
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', help="config file to decrypt", required=True)
parser.add_argument('-o', '--output', help="file to save decrypted config to")
args = parser.parse_args()
config_file = open(args.input, "rb")
config_res = config_file.read()
config_file.close()
decrypter = ConfigDecrypter(config_res)
decrypted_config = decrypter.decrypt()
if args.output is None:
print(decrypted_config)
else:
out_file = open(args.output, 'w')
out_file.write(decrypted_config)
out_file.close()