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
from binascii import crc_hqx as crc16
from itertools import cycle
import os
from pathlib import Path
from sys import argv
from sys import stderr
# Structure of pre-encoded payload
# 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
from lib.encdec import eprint, encrypt, decrypt
def usage(info = None):
@ -57,7 +22,9 @@ def main():
file_bytes = Path(argv[2]).read_bytes()
if mode == 'd':
os.write(1, decrypt(file_bytes))
decrypted, version = decrypt(file_bytes)
eprint('version:', version)
os.write(1, decrypted)
eprint('Success!')
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])