-
Notifications
You must be signed in to change notification settings - Fork 2
/
generateSecureFat.py
72 lines (63 loc) · 2.52 KB
/
generateSecureFat.py
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
71
72
#
# https://github.com/wukko/ubiart-secure-fat
#
# UbiArt secure_fat.gf file generator using existing IPK bundles by https://github.com/wukko
# Tested on Just Dance 2015 - 2022 games on PC, Wii, Wii U, Nintendo Switch (NX).
# This script should work for Rayman Legends/Origins and other UbiArt games too.
#
# This script includes all matching files in current directory and its subdirectories when used standalone. Keep this in mind when using it.
#
# Credit to me (https://github.com/wukko) is required when this script is used in other projects.
import os
# Modify these variables for standalone use if needed
out = "secure_fat.gf"
bext = ".ipk"
ignore = ["patch"]
p = ["pc", "wiiu", "wii", "nx", "x360", "durango", "scarlett", "ps3", "orbis", "prospero", "ggp"]
def nameOnly(name, ext):
name = name.split('/')[len(name.split('/'))-1]
for i in p:
name = name.replace(ext, '').replace('_'+i, '')
return name
def hashList(input):
hashes = []
with open(input, "rb") as f:
f.read(16)
filecount = int.from_bytes(f.read(4), "big")
f.read(40)
counter = 0
while counter != filecount:
f.read(16)
f.read(int.from_bytes(f.read(4), "big"))
f.read(int.from_bytes(f.read(4), "big"))
hashes.append(f.read(4))
f.read(16)
counter += 1
return hashes
def generateSecureFat(cwd, out, bext, ignore):
bl = []
for root, dir_names, file_names in os.walk(cwd):
for f in file_names:
path = os.path.join(root, f).replace(cwd, '')[1:]
if path[-4:] == bext:
bl.append(path)
bl = [b for b in bl if not nameOnly(b, bext) in ignore]
with open(out, "wb") as f:
bundleCount = 0
hashesCount = 0
body = b''
footer = b''
for i in bl:
ipkhash = hashList(i)
hashesCount += len(ipkhash)
ipkname = nameOnly(i, bext).encode()
for h in ipkhash:
body += h + b'\x00\x00\x00\x01' + bundleCount.to_bytes(1, "big")
footer += bundleCount.to_bytes(1, "big") + len(ipkname).to_bytes(4, "big") + ipkname
bundleCount = bundleCount + 1
f.write(b'\x55\x53\x46\x54\x1F\x5E\xE4\x2F\x00\x00\x00\x01' + hashesCount.to_bytes(4, "big"))
f.write(body)
f.write(bundleCount.to_bytes(4, "big"))
f.write(footer)
if __name__ == "__main__":
generateSecureFat(os.getcwd(), out, bext, ignore)