import typing from struct import pack, unpack from .blobs import db_write_enable from .hw_tables import flash_ic_table_lookup, FlashIcInfo from .tls import tls from .util import assert_status, unhex # type 01 is for the firmware - written blocks are decrypted on the fly using fw key # access lvl: # 2 -- write only # 7 -- can read/write even without TLS class PartitionInfo: def __init__(self, id: int, type: int, access_lvl: int, offset: int, size: int): self.id, self.type, self.access_lvl, self.offset, self.size = id, type, access_lvl, offset, size def __repr__(self): return 'PartitionInfo(0x%02x, 0x%02x, 0x%04x, 0x%08x, 0x%08x)' % ( self.id, self.type, self.access_lvl, self.offset, self.size) class FlashInfo: def __init__(self, ic: FlashIcInfo, blocks: int, unknown0: int, blocksize: int, unknown1: int, partitions: typing.Sequence[PartitionInfo]): self.ic = ic self.blocks = blocks self.unknown0 = unknown0 self.blocksize = blocksize self.unknown1 = unknown1 self.partitions = partitions def __repr__(self): return 'FlashInfo(%s, 0x%x, 0x%x, 0x%x, 0x%x, %s)' % (repr( self.ic), self.blocks, self.unknown0, self.blocksize, self.unknown1, repr(self.partitions)) def get_flash_info(): rsp = tls.cmd(unhex('3e')) assert_status(rsp) rsp = rsp[2:] hdr = rsp[:0xe] rsp = rsp[0xe:] jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack('>> 4302 -- get partition header (get fwext info) # b004 -- no fw detected # 0000 # 0100 (major) 0100 (minor) 0800 (modules) c28c745a (buildtime) # type subtype major minor size # 0100 3446 0200 0700 d03e0000 # 0100 8408 0100 0700 00040000 # 0200 8428 0300 1200 e0100000 # 0200 7636 0100 0c00 100a0000 # 0100 8647 0000 0100 505a0000 # 0200 2377 0000 0100 802f0000 # 0200 6637 0100 0c00 f0220200 # 0100 2556 0000 0100 60040000 class ModuleInfo: def __init__(self, type: int, subtype: int, major: int, minor: int, size: int): self.type, self.subtype, self.major, self.minor, self.size = type, subtype, major, minor, size def __repr__(self): return 'ModuleInfo(0x%04x, 0x%04x, %d, %d, %d)' % (self.type, self.subtype, self.major, self.minor, self.size) class FirmwareInfo: def __init__(self, major: int, minor: int, buildtime: int, modules: typing.Sequence[ModuleInfo]): self.major, self.minor, self.buildtime, self.modules = major, minor, buildtime, modules def __repr__(self): return 'FirmwareInfo(%d, %d, %d, %s)' % (self.major, self.minor, self.buildtime, repr(self.modules)) def get_fw_info(partition: int): rsp = tls.cmd(pack(' bytes: cmd = pack(' 0: chunk, buf = buf[:bs], buf[bs:] write_flash(partition, ptr, chunk) ptr += len(chunk) def read_flash_all(partition: int, start: int, size: int): bs = 0x1000 blocks = [read_flash(partition, addr, bs) for addr in range(start, start + size, bs)] return b''.join(blocks)[:size] def write_fw_signature(partition: int, signature: bytes): rsp = tls.cmd(pack('