forked from 641i130/klbvfs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlab.py
121 lines (93 loc) · 3.63 KB
/
lab.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/bin/env python3
import os
import re
import base64
import urllib.parse
import subprocess
import zlib
from functools import partial
from klbvfs import *
##GLOBALES##
root = os.path.abspath(".")
dump_folder = os.path.join(root, "dump")
output_folder = os.path.join(root, "extracted")
app_package = "com.klab.lovelive.allstars.global" #TODO: detectar las demás versiones
##UTILS##
def read_SQKey():
shared_prefs_path = os.path.join(os.path.join(dump_folder, "shared_prefs"), app_package + '.v2.playerprefs.xml')
xml_file = open(shared_prefs_path, 'r').read()
sqm = re.search("(SQ).+", xml_file)
sq = urllib.parse.unquote(xml_file[sqm.start()+4:sqm.end()-9])
sq = base64.b64decode(sq)
return sq
def sqlite_key(dbfile):
sqkey = read_SQKey()
basename = os.path.basename(dbfile)
sha1 = hmac_sha1(key=sqkey, s=basename.encode('utf-8'))
return list(struct.unpack('>III', sha1[:12]))
def decrypt_db(source):
dstpath = '_'.join(source.split('_')[:-1])
print(os.path.basename(dstpath))
src = codecs.open(source, mode='rb', encoding='klbvfs', errors=sqlite_key(source))
dst = open(dstpath, 'wb+')
print('decrypting databases %s -> %s' % (source, dstpath))
shutil.copyfileobj(src, dst)
src.close()
dst.close()
return dstpath
#https://heapspray.io/decompressing-android-backups-python.html
def ab_unpack(source, destination):
print("Extraccion del ab en progreso...")
abfile = open(source, "rb")
output = open(destination, "wb")
abfile.seek(24)
obj = zlib.decompressobj(zlib.MAX_WBITS)
for chunk in iter(partial(abfile.read, 1024), ""):
if chunk == b'':
output.flush()
output.close()
break;
out_chunk = obj.decompress(chunk)
output.write(out_chunk)
print("Extraccion completada.")
##ACCIONES##
#extraer datos del juego desde el dispositivo, y mover los archivos a su respectiva carpeta
def dump():
raw_folder = os.path.join(dump_folder, "raw")
#solo para ver si esta conectado el dispositivo.
subprocess.run(["adb", "devices"])
#hacer dump de todos los datos
#subprocess.run(["adb", "pull", "/sdcard/Android/data/"+app_package, os.path.join(raw_folder, app_package)])
#hacer backup de la app para extraer el shared_prefs (por alguna razón, el dump no extrae todos los archivos, por eso es necesario tambien hacer adb pull)
subprocess.run(["adb", "backup", "-shared", app_package, "-f", os.path.join(raw_folder, "dump.ab")])
#convertir el ab a tar
ab_unpack(os.path.join(raw_folder, "dump.ab"), os.path.join(raw_folder, "dump.tar"))
#extraer el shared preference desde el tar.
os.chdir(raw_folder)
subprocess.run(["tar", "-xvf", os.path.join(raw_folder, "dump.tar"), "apps/"+app_package+"/sp/"+app_package+".v2.playerprefs.xml"])
os.chdir(root)
#preparar entorno la primera vez
def init():
#mover shared_prefs DE raw/apps/{app_package}/sp/*.xml A dump/shared_prefs
#mover *.db DE raw/{app_package}/files/files/ A dump/databases
#mover packs DE raw/{app_package}/files/files/ A dump/packs
#desencriptar bases de datos
print("Desencriptando las bases de datos, esto puede tardar.")
db_folder = os.path.join(dump_folder, "db")
for dbfile in os.listdir(db_folder):
decrypt_db(os.path.join(db_folder, dbfile))
print("Bases de datos desencriptadas.")
#actualizar packs y bases de datos
def update():
print("TODO")
#borrar el contenido de la carpeta raw
#ejecutar dump()
#desencriptar base de datos y reemplazar los viejos
#mover packs del raw a dump/packs pero sin reemplazar los ya existentes.
#acciones para desempaquetar
def unpack():
print("TODO")
#klbvfs y tools.py pero adaptado al esquema de directorios de lab.py
##TESTS##
dump()
#init()