forked from mathieulh/sceutils
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscedecrypt.py
More file actions
49 lines (41 loc) · 1.58 KB
/
Copy pathscedecrypt.py
File metadata and controls
49 lines (41 loc) · 1.58 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
#!/usr/bin/python3
import argparse
import os
import pathlib
import sys
import zlib
import sceutils
from scetypes import SceHeader
from Cryptodome.Cipher import AES
from Cryptodome.Util import Counter
import keys
def scedecrypt(inf, outdir, decompress=True, silent=False):
sce = SceHeader.unpack(inf)
if not silent:
print(sce)
(sysver, selftype), use_spkg2 = sceutils.get_key_type(inf, sce, silent)
scesegs = sceutils.get_segments(inf, sce, sysver, selftype, silent=silent, use_spkg2=use_spkg2)
for i, sceseg in scesegs.items():
if not silent:
print(f'Decrypting segment {i}...')
outf = open(os.path.join(outdir, f"{os.path.basename(inf.name)}.seg{i:02}"), "wb")
inf.seek(sceseg.offset)
dat = inf.read(sceseg.size)
ctr = Counter.new(128, initial_value=int.from_bytes(sceseg.iv, "big"))
section_aes = AES.new(sceseg.key, AES.MODE_CTR, counter=ctr)
dat = section_aes.decrypt(dat)
if decompress and sceseg.compressed:
if not silent:
print(f'Decompressing segment {i}...')
z = zlib.decompressobj()
dat = z.decompress(dat)
outf.write(dat)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("filename", type=pathlib.Path)
parser.add_argument("outdir", type=pathlib.Path)
parser.add_argument("-keys", type=pathlib.Path, default="keys_external.py", required=False)
args = parser.parse_args()
keys.use_keys(args.keys)
with open(args.filename, "rb") as inf:
scedecrypt(inf, args.outdir)