refactor; feat: modder initial

modder2
Mikhail Yudin 2023-06-03 09:55:17 +07:00
rodzic 76559dabc8
commit fb62b129ed
9 zmienionych plików z 89 dodań i 37 usunięć

Wyświetl plik

@ -0,0 +1,16 @@
# thanks to gabizro
[bands]
B1_1=0xE074
B1_2=0xE090
B2_1=0xE078
B2_2=0xE094
B3_1=0xE07C
B3_2=0xE098
B4_1=0xE080
B4_2=0xE09C
B5_1=0xE084
B5_2=0xE0A0
B6_1=0xE088
B6_2=0xE0A4
B7_1=0xE08C
B7_2=0xE0A8

Wyświetl plik

@ -1,45 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from binascii import crc_hqx as crc16
from itertools import cycle
import os import os
from pathlib import Path from pathlib import Path
from sys import argv from sys import argv
from sys import stderr
# Structure of pre-encoded payload from lib.encdec import eprint, encrypt, decrypt
# 8196 | 16 | ... | 2 |
# data | version | data | crc |
KEY = Path('./key.bin').read_bytes()
V_START = 8192
V_END = V_START + 16
CRC_LEN = 2
def eprint(*args, **kwargs):
print(*args, **kwargs, file=stderr)
def xor(var):
return bytes(a ^ b for a, b in zip(var, cycle(KEY)))
def make_16byte_version(version):
return bytes([ord(c) for c in version] + [0] * (16 - len(version)))
def decrypt(data):
decrypted = xor(data)
eprint('version:', decrypted[V_START:V_END].decode())
return decrypted[:V_START] + decrypted[V_END:-CRC_LEN]
def encrypt(data, version='2.01.26'):
v = make_16byte_version(version)
encrypted = xor(data[:V_START] + v + data[V_START:])
checksum = crc16(encrypted, 0).to_bytes(2, 'little')
return encrypted + checksum
def usage(info = None): def usage(info = None):
@ -57,7 +22,9 @@ def main():
file_bytes = Path(argv[2]).read_bytes() file_bytes = Path(argv[2]).read_bytes()
if mode == 'd': if mode == 'd':
os.write(1, decrypt(file_bytes)) decrypted, version = decrypt(file_bytes)
eprint('version:', version)
os.write(1, decrypted)
eprint('Success!') eprint('Success!')
return return

41
lib/encdec.py 100644
Wyświetl plik

@ -0,0 +1,41 @@
from binascii import crc_hqx as crc16
from itertools import cycle
from sys import stderr
from pathlib import Path
# Structure of pre-encoded payload
# 8196 | 16 | ... | 2 |
# data | version | data | crc |
LIB_DIR = Path(__file__).parent
DATA_DIR = LIB_DIR / '..' / 'data'
KEY = (DATA_DIR / 'key.bin').read_bytes()
V_START = 8192
V_END = V_START + 16
CRC_LEN = 2
def eprint(*args, **kwargs):
print(*args, **kwargs, file=stderr)
def xor(var):
return bytes(a ^ b for a, b in zip(var, cycle(KEY)))
def make_16byte_version(version):
return bytes([ord(c) for c in version] + [0] * (16 - len(version)))
def decrypt(data):
decrypted = xor(data)
version = decrypted[V_START:V_END].decode().rstrip('\x00')
return (decrypted[:V_START] + decrypted[V_END:-CRC_LEN], version)
def encrypt(data, version='2.01.26'):
v = make_16byte_version(version)
encrypted = xor(data[:V_START] + v + data[V_START:])
checksum = crc16(encrypted, 0).to_bytes(2, 'little')
return encrypted + checksum

28
modder.py 100644
Wyświetl plik

@ -0,0 +1,28 @@
#!/usr/bin/env python3
from pathlib import Path
from sys import argv
from configparser import ConfigParser
from lib.encdec import decrypt, eprint
ADDR_DIR = Path(__file__).parent / 'addresses'
def main(encrypted_file_path):
file_bytes = Path(encrypted_file_path).read_bytes()
decrypted, version = decrypt(file_bytes)
eprint('version:', version)
addr_file = ADDR_DIR / ('%s.ini' % version)
addresses = ConfigParser()
addresses.read(addr_file)
bands_addr = addresses['bands']
for k in bands_addr:
addr = int(bands_addr.get(k), 16)
value = int.from_bytes(decrypted[addr:addr+4], 'little')
eprint(k, addr, value)
if __name__ == "__main__":
main(argv[1])