Update - Cleanup, Fixes and add new cpu

This commit is contained in:
Bjoern Kerler 2021-10-19 10:29:32 +02:00
parent 5d85238829
commit 55a679831d
21 changed files with 448 additions and 308 deletions

17
mtk
View file

@ -302,7 +302,7 @@ class Main(metaclass=LogBase):
logfilename = os.path.join("logs", "log.txt")
if os.path.exists(logfilename):
os.remove(logfilename)
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.debug(" ".join(sys.argv))
@ -388,15 +388,17 @@ class Main(metaclass=LogBase):
"Trying to dump preloader from ram.")
plt = PLTools(mtk=mtk, loglevel=self.__logger.level)
dadata, filename = plt.run_dump_preloader(self.args.ptype)
mtk.config.preloader = self.patch_preloader_security(dadata)
mtk.config.preloader = mtk.patch_preloader_security(dadata)
if mtk.config.preloader is not None:
self.info("Using custom preloader : "+filename)
daaddr, dadata = mtk.parse_preloader(mtk.config.preloader)
mtk.config.preloader = mtk.patch_preloader_security(dadata)
if mtk.preloader.send_da(daaddr, len(dadata), 0x100, dadata):
self.info(f"Sent preloader to {hex(daaddr)}, length {hex(len(dadata))}")
if mtk.preloader.jump_da(daaddr):
self.info(f"PL Jumped to daaddr {hex(daaddr)}.")
time.sleep(2)
sys.exit(1)
mtk = Mtk(config=mtk.config, loglevel=self.__logger.level)
res = mtk.preloader.init()
if not res:
@ -412,6 +414,9 @@ class Main(metaclass=LogBase):
# data=0x200*b"\x00"+data
mtk.preloader.send_partition_data(partition, pldata)
status = mtk.preloader.jump_to_partition(partition) # Do not remove !
res=mtk.preloader.read32(0x10C180,10)
for val in res:
print(hex(val))
if status!=0x0:
self.error("Error on jumping to partition: "+self.eh.status(status))
else:
@ -631,12 +636,6 @@ class Main(metaclass=LogBase):
if mtk.port.cdc.connected and os.path.exists(".state"):
info=mtk.daloader.reinit()
else:
if os.path.exists("logs"):
try:
shutil.rmtree("logs", ignore_errors=True, onerror=None)
os.mkdir("logs")
except:
pass
try:
preloader = self.args.preloader
except:
@ -1109,7 +1108,7 @@ class Main(metaclass=LogBase):
self.close()
info = "MTK Flash/Exploit Client V1.50 (c) B.Kerler 2018-2021"
info = "MTK Flash/Exploit Client V1.51 (c) B.Kerler 2018-2021"
cmds = {
"printgpt": "Print GPT Table information",

View file

@ -36,7 +36,7 @@ class Port(metaclass=LogBase):
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.__logger.setLevel(logging.DEBUG)
else:

View file

@ -58,7 +58,7 @@ class cqdma(metaclass=LogBase):
self.reg = cqdma_reg(setup)
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.__logger.setLevel(logging.DEBUG)
else:

View file

@ -7,6 +7,7 @@ from struct import unpack
from mtkclient.Library.utils import LogBase, read_object, logsetup
from mtkclient.config.payloads import pathconfig
from mtkclient.config.brom_config import damodes
from mtkclient.Library.utils import structhelper
class Storage:
MTK_DA_HW_STORAGE_NOR = 0
@ -73,27 +74,41 @@ class NandCellUsage:
CELL_OCT = 7
entry_region = [
('m_buf', 'I'),
('m_len', 'I'),
('m_start_addr', 'I'),
('m_start_offset', 'I'),
('m_sig_len', 'I')]
class entry_region:
m_buf = None
m_len = None
m_start_addr = None
m_start_offset = None
m_sig_len = None
def __init__(self, data):
sh = structhelper(data)
self.m_buf = sh.dword()
self.m_len = sh.dword()
self.m_start_addr = sh.dword()
self.m_start_offset = sh.dword()
self.m_sig_len = sh.dword()
DA = [
('magic', 'H'),
('hw_code', 'H'),
('hw_sub_code', 'H'),
('hw_version', 'H'),
('sw_version', 'H'),
('reserved1', 'H'),
('pagesize', 'H'),
('reserved3', 'H'),
('entry_region_index', 'H'),
('entry_region_count', 'H')
# vector<entry_region> LoadRegion
]
class DA:
def __init__(self,data):
self.loader = None
sh = structhelper(data)
self.magic = sh.short()
self.hw_code = sh.short()
self.hw_sub_code = sh.short()
self.hw_version = sh.short()
self.sw_version = sh.short()
self.reserved1 = sh.short()
self.pagesize = sh.short()
self.reserved3 = sh.short()
self.entry_region_index = sh.short()
self.entry_region_count = sh.short()
self.region = []
for _ in range(self.entry_region_count):
entry_tmp = entry_region(sh.bytes(20))
self.region.append(entry_tmp)
def setfilename(self, loaderfilename: str):
self.loader = loaderfilename
class DAconfig(metaclass=LogBase):
def __init__(self, mtk, loader=None, preloader=None, loglevel=logging.INFO):
@ -118,8 +133,9 @@ class DAconfig(metaclass=LogBase):
loaders = []
for root, dirs, files in os.walk(self.pathconfig.get_loader_path(), topdown=False):
for file in files:
if "Preloader" not in root:
if "MTK_AllInOne_DA" in file:
loaders.append(os.path.join(root, file))
loaders = sorted(loaders)[::-1]
for loader in loaders:
self.parse_da_loader(loader)
else:
@ -170,11 +186,7 @@ class DAconfig(metaclass=LogBase):
self.emi = self.m_extract_emi(data)
def parse_da_loader(self, loader):
if not "MTK_AllInOne_DA" in loader:
return True
try:
if loader not in self.dasetup:
self.dasetup[loader] = []
with open(loader, 'rb') as bootldr:
# data = bootldr.read()
# self.debug(hexlify(data).decode('utf-8'))
@ -182,15 +194,20 @@ class DAconfig(metaclass=LogBase):
count_da = unpack("<I", bootldr.read(4))[0]
for i in range(0, count_da):
bootldr.seek(0x6C + (i * 0xDC))
datmp = read_object(bootldr.read(0x14), DA) # hdr
datmp["loader"] = loader
da = [datmp]
# bootldr.seek(0x6C + (i * 0xDC) + 0x14) #sections
count = datmp["entry_region_count"]
for m in range(0, count):
entry_tmp = read_object(bootldr.read(20), entry_region)
da.append(entry_tmp)
self.dasetup[loader].append(da)
da = DA(bootldr.read(0xDC))
da.setfilename(loader)
if da.hw_code not in self.dasetup:
self.dasetup[da.hw_code] = [da]
else:
for ldr in self.dasetup[da.hw_code]:
found = False
if da.hw_version == ldr.hw_version:
if da.sw_version == ldr.sw_version:
if da.hw_sub_code == da.hw_sub_code:
found = True
break
if not found:
self.dasetup[da.hw_code].append(da)
return True
except Exception as e:
self.error("Couldn't open loader: " + loader + ". Reason: " + str(e))
@ -198,14 +215,14 @@ class DAconfig(metaclass=LogBase):
def setup(self):
dacode = self.config.chipconfig.dacode
for loader in self.dasetup:
for setup in self.dasetup[loader]:
if setup[0]["hw_code"] == dacode:
if setup[0]["hw_version"] <= self.config.hwver:
if setup[0]["sw_version"] <= self.config.swver:
if dacode in self.dasetup:
loaders = self.dasetup[dacode]
for loader in loaders:
if loader.hw_version <= self.config.hwver:
if loader.sw_version <= self.config.swver:
if self.loader is None:
self.da = setup
self.loader = loader
self.da = loader
self.loader = loader.loader
if self.da is None:
self.error("No da config set up")

View file

@ -145,7 +145,7 @@ class gpt(metaclass=LogBase):
self.__logger.setLevel(loglevel)
if loglevel == logging.DEBUG:
logfilename = "log.txt"
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
def parseheader(self, gptdata, sectorsize=512):

View file

@ -29,7 +29,29 @@ oem_pubk = "DACD8B5FDA8A766FB7BCAA43F0B16915" + \
"5CD9D430F02EE46F80DE6C63EA802BEF" + \
"90673AAC4C6667F2883FB4501FA77455"
mtk_oem_key = hashlib.sha256(bytes.fromhex(oem_pubk)).digest()
huawei_med_lx9 = "C1A9D3E65C7EAEB31932E9DD224C07C0" + \
"70D879FB4FE518C64E92C24B79DC1EE1" + \
"535D91D38DD34D7E32A22DEED60F0727" + \
"FF8F8747E2598ACB5DDC73C61D2434A9" + \
"1D568FE3E773BD0D17AA46B0364E0DCF" + \
"3B41E0034605D572B6CD7DD8A816E7D6" + \
"84181B1646628576D1E22F55071687B9" + \
"E5B2F9C9536167B7EDCF10F1F85BE57B" + \
"6EE873BFE952BB33F0001140E0E46AF2" + \
"D64D39C568D8E372BCE3609BCACA5316" + \
"E4EBDDE5721B33611E064DF41A4BCF0A" + \
"3A395791D3203BF220DC71F4267093CE" + \
"B78E30A844D4631DE8CE6D0514202BB5" + \
"8AD2024B16558C2AD9B30CE05043FF67" + \
"C4D265A3D5F3275D93AFDC1A39625C2C" + \
"5BD6FDCDBD75E76E6D9E74E9672B5897"
buffer = bytearray(b"\x00" * 0x20C)
buffer[0:4] = pack("<I", 3)
buffer[4:8] = pack("<I", 256)
buffer[12:15] = b"\x01\x00\x01"
buffer[0x10C:0x20C] = bytes.fromhex(huawei_med_lx9)
huawei_oem_key = bytearray(hashlib.sha256(buffer).digest())
regval = {
"DXCC_CON": 0x0000,
@ -1072,7 +1094,7 @@ class dxcc(metaclass=LogBase):
itrustee = b"TrustedCorekeymaster" + b"\x07" * 0x10
seed = itrustee + pack("<B", ctr)
paddr = self.SBROM_AesCmac(1, 0x0, seed, 0x0, len(seed), dstaddr)
for field in self.read32(paddr + 0x108, 4):
for field in self.read32(paddr, 4):
fdekey += pack("<I", field)
self.tzcc_clk(0)
return fdekey
@ -1099,8 +1121,29 @@ class dxcc(metaclass=LogBase):
prov_key = b"PROVISION KEY"
self.tzcc_clk(1)
dstaddr = self.da_payload_addr - 0x300
platkey = self.SBROM_KeyDerivation(2, plat_key, mtk_oem_key, 0x20, dstaddr)
provkey = self.SBROM_KeyDerivation(5, prov_key, mtk_oem_key, 0x20, dstaddr)
mtk_oem_key = hashlib.sha256(bytes.fromhex(oem_pubk)).digest()
provkey = self.SBROM_KeyDerivation(HwCryptoKey.PROVISIONING_KEY, plat_key, mtk_oem_key, 0x10, dstaddr)
while True:
val = self.read32(self.dxcc_base + 0xAF4) & 1
if val != 0:
break
platkey = self.SBROM_KeyDerivation(HwCryptoKey.PLATFORM_KEY, prov_key, mtk_oem_key, 0x10, dstaddr)
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
self.write32(self.dxcc_base + 0xACC, 0)
pdesc = hw_desc_init()
pdesc[0] = 0
pdesc[1] = 0x8000081
pdesc[2] = 0
pdesc[3] = 0
pdesc[4] = 0x4801C20
pdesc[5] = 0
self.sasi_sb_adddescsequence(pdesc)
dstaddr = self.da_payload_addr - 0x300
self.SB_HalWaitDescCompletion(dstaddr)
# data=self.read32(0x200D90)
self.tzcc_clk(0)
return platkey, provkey
@ -1112,54 +1155,39 @@ class dxcc(metaclass=LogBase):
result.extend(pack("<I", field))
return result
# SBROM_KeyDerivation(dxcc_base,encmode=1,fde1,8,fde2,4,fdekey,fdekey>>31,fdekeylen
"""
SBROM_KeyDerivation PC(00230B77) R0:10210000,R1:00000001,R2:001209D8,R3:00000008,R4:00100000,R5:00233760,R6:00000010
R2:53514e43214c465a
R5:52504d42204b45595341534953514e43
key="SQNC!LFZ",8
salt="SASI",4
requestedlen=0x10
"""
def SBROM_KeyDerivation(self, aeskeytype, key, salt, requestedlen, destaddr):
def SBROM_KeyDerivation(self, aeskeytype, label, salt, requestedlen, destaddr):
result = bytearray()
buffer = bytearray(b"\x00" * 0x43)
if aeskeytype - 1 > 4 or (1 << (aeskeytype - 1) & 0x17) == 0:
return 0xF2000002
if requestedlen > 0xFF or (requestedlen << 28) & 0xFFFFFFFF:
return 0xF2000003
if 0x0 >= len(key) > 0x20:
if 0x0 >= len(label) > 0x20:
return 0xF2000003
bufferlen = len(salt) + 3 + len(key)
bufferlen = len(salt) + 3 + len(label)
iterlength = (requestedlen + 0xF) >> 4
if len(key) == 0:
keyend = 1
else:
buffer[1:1 + len(key)] = key
keyend = len(key) + 1
saltstart = keyend + 1
if len(salt) > 0:
buffer[saltstart:saltstart + len(salt)] = salt
# ToDo: verify buffer structure
buffer[saltstart + len(salt):saltstart + len(salt) + 4] = pack("<I", 8 * requestedlen)
# buffer=0153514e43214c465a005442544a80
for i in range(0, iterlength):
buffer[0] = i + 1
dstaddr = self.SBROM_AesCmac(aeskeytype, 0x0, buffer, 0, bufferlen, destaddr)
buffer = pack("<B", i + 1) + label + b"\x00" + salt + pack("<B", (8 * requestedlen) & 0xFF)
dstaddr = self.SBROM_AesCmac(aeskeytype, 0x0, buffer[:bufferlen], 0, bufferlen, destaddr)
if dstaddr != 0:
for field in self.read32(dstaddr + 0x108, 4):
for field in self.read32(dstaddr, 4):
result.extend(pack("<I", field))
return result
def SBROM_AesCmac(self, aesKeyType, pInternalKey, buffer, flag, bufferlen, destaddr):
dataptr = destaddr + 0x118 # SP - 0xA8 - 0x24 - 0x28 - 0x38 - 0x88 - 0x30 - ((12 * 8) - 16)
pInternalKeyptr = destaddr + 0x108 # dataptr - 0x10
destptr = destaddr
self.writemem(dataptr, buffer[:bufferlen])
self.writemem(pInternalKeyptr, pack("<Q", pInternalKey))
if self.SBROM_AesCmacDriver(aesKeyType, pInternalKeyptr, dataptr, DmaMode.DMA_DLLI, bufferlen, destaddr):
return destptr
def SBROM_AesCmac(self, aesKeyType, InternalKey, DataIn, dmaMode, bufferlen, destaddr):
sramAddr = destaddr
ivSramAddr = sramAddr
inputSramAddr = ivSramAddr + AES_IV_COUNTER_SIZE_IN_BYTES
blockSize = len(DataIn) // 0x20 * 0x20
outputSramAddr = inputSramAddr + blockSize
keySramAddr = outputSramAddr + blockSize
pInternalKey = keySramAddr
if InternalKey != 0:
self.writemem(keySramAddr, InternalKey)
if dmaMode != 0:
dmaMode = dmaMode
self.writemem(inputSramAddr, DataIn[:bufferlen])
if self.SBROM_AesCmacDriver(aesKeyType, pInternalKey, inputSramAddr, dmaMode, bufferlen, sramAddr):
return pInternalKey
return 0
def SB_HalInit(self):
@ -1191,6 +1219,7 @@ class dxcc(metaclass=LogBase):
return 0xF6000001
def SBROM_AesCmacDriver(self, aesKeyType, pInternalKey, pDataIn, dmaMode, blockSize, pCMacResult):
ivSramAddr = 0
if aesKeyType == HwCryptoKey.ROOT_KEY:
if self.read32(self.dxcc_base + self.DX_HOST_SEP_HOST_GPR4) & 2 != 0:
keySizeInBytes = 0x20 # SEP_AES_256_BIT_KEY_SIZE
@ -1204,22 +1233,25 @@ class dxcc(metaclass=LogBase):
pdesc = hw_desc_set_cipher_mode(pdesc, sep_cipher_mode.SEP_CIPHER_CMAC) # desc[4]=0x1C00
pdesc = hw_desc_set_cipher_config0(pdesc, DescDirection.DESC_DIRECTION_ENCRYPT_ENCRYPT)
pdesc = hw_desc_set_key_size_aes(pdesc, keySizeInBytes) # desc[4]=0x801C00
# pdesc = hw_desc_set_din_sram(pdesc, ivSramAddr, AES_IV_COUNTER_SIZE_IN_BYTES)
pdesc = hw_desc_set_din_sram(pdesc, ivSramAddr, AES_IV_COUNTER_SIZE_IN_BYTES)
pdesc = hw_desc_set_din_const(pdesc, 0, AES_IV_COUNTER_SIZE_IN_BYTES) # desc[1]=0x8000041
pdesc = hw_desc_set_flow_mode(pdesc, FlowMode.S_DIN_to_AES) # desc[4]=0x801C20
pdesc = hw_desc_set_setup_mode(pdesc, SetupOp.SETUP_LOAD_STATE0) # desc[4]=0x1801C20
pdesc[1] |= 0x8000000
self.sasi_sb_adddescsequence(pdesc)
# Load key
mdesc = hw_desc_init()
if aesKeyType == HwCryptoKey.USER_KEY:
mdesc = hw_desc_set_din_sram(mdesc, pInternalKey, AES_Key128Bits_SIZE_IN_BYTES)
keySramAddr = pInternalKey
mdesc = hw_desc_set_din_sram(mdesc, keySramAddr, AES_Key128Bits_SIZE_IN_BYTES)
mdesc = hw_desc_set_cipher_do(mdesc, aesKeyType) # desc[4]=0x8000
mdesc = hw_desc_set_cipher_mode(mdesc, sep_cipher_mode.SEP_CIPHER_CMAC) # desc[4]=0x9C00
mdesc = hw_desc_set_cipher_config0(mdesc, DescDirection.DESC_DIRECTION_ENCRYPT_ENCRYPT)
mdesc = hw_desc_set_key_size_aes(mdesc, keySizeInBytes) # desc[4]=0x809C00
mdesc = hw_desc_set_flow_mode(mdesc, FlowMode.S_DIN_to_AES) # desc[4]=0x809C20
mdesc = hw_desc_set_setup_mode(mdesc, SetupOp.SETUP_LOAD_KEY0) # desc[4]=0x4809C20
mdesc[4] |= ((aesKeyType >> 2) & 3) << 20
self.sasi_sb_adddescsequence(mdesc)
# Process input data

View file

@ -153,7 +153,7 @@ class sej(metaclass=LogBase):
self.info = self.__logger.info
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.__logger.setLevel(logging.DEBUG)
else:

View file

@ -7,82 +7,155 @@ import os
import time
from struct import pack, unpack
from binascii import hexlify
from mtkclient.Library.utils import LogBase, progress, read_object, logsetup
from mtkclient.Library.utils import LogBase, progress, read_object, logsetup, structhelper
from mtkclient.Library.error import ErrorHandler
from mtkclient.Library.daconfig import DaStorage, EMMC_PartitionType
from mtkclient.Library.partition import Partition
from mtkclient.config.payloads import pathconfig
norinfo = [
('m_nor_ret', '>I'),
('m_nor_chip_select', '2B'),
('m_nor_flash_id', '>H'),
('m_nor_flash_size', '>I'),
('m_nor_flash_dev_code', '>4H'),
('m_nor_flash_otp_status', '>I'),
('m_nor_flash_otp_size', '>I')
]
nandinfo32 = [
('m_nand_info', '>I'),
('m_nand_chip_select', '>B'),
('m_nand_flash_id', '>H'),
('m_nand_flash_size', '>I'),
('m_nand_flash_id_count', '>H'),
]
class norinfo:
m_nor_ret = None
m_nor_chip_select = None
m_nor_flash_id = None
m_nor_flash_size = None
m_nor_flash_dev_code = None
m_nor_flash_otp_status = None
m_nor_flash_otp_size = None
def __init__(self, data):
sh = structhelper(data)
self.m_nor_ret = sh.dword(True)
self.m_nor_chip_select = sh.bytes(2)
self.m_nor_flash_id = sh.short(True)
self.m_nor_flash_size = sh.dword(True)
self.m_nor_flash_dev_code = sh.shorts(4, True)
self.m_nor_flash_otp_status = sh.dword(True)
self.m_nor_flash_otp_size = sh.dword(True)
class nandinfo32:
m_nand_info = None
m_nand_chip_select = None
m_nand_flash_id = None
m_nand_flash_size = None
m_nand_flash_id_count = None
info2 = None
def __init__(self, data):
sh = structhelper(data)
self.m_nand_info = sh.dword(True)
self.m_nand_chip_select = sh.bytes(1)
self.m_nand_flash_id = sh.short(True)
self.m_nand_flash_size = sh.dword(True)
self.m_nand_flash_id_count = sh.short(True)
self.info2 = None
class nandinfo64:
m_nand_info = None
m_nand_chip_select = None
m_nand_flash_id = None
m_nand_flash_size = None
m_nand_flash_id_count = None
info2 = None
def __init__(self, data):
sh = structhelper(data)
self.m_nand_info = sh.dword(True)
self.m_nand_chip_select = sh.bytes(1)
self.m_nand_flash_id = sh.short(True)
self.m_nand_flash_size = sh.qword(True)
self.m_nand_flash_id_count = sh.short(True)
self.info2 = None
nandinfo64 = [
('m_nand_info', '>I'),
('m_nand_chip_select', '>B'),
('m_nand_flash_id', '>H'),
('m_nand_flash_size', '>Q'),
('m_nand_flash_id_count', '>H'),
]
# ('m_nand_flash_dev_code', '>7H'),
nandinfo2 = [
('m_nand_pagesize', '>H'),
('m_nand_sparesize', '>H'),
('m_nand_pages_per_block', '>H'),
('m_nand_io_interface', 'B'),
('m_nand_addr_cycle', 'B'),
('m_nand_bmt_exist', 'B'),
]
class nandinfo2:
m_nand_pagesize = None
m_nand_sparesize = None
m_nand_pages_per_block = None
m_nand_io_interface = None
m_nand_addr_cycle = None
m_nand_bmt_exist = None
emmcinfo = [
('m_emmc_ret', '>I'),
('m_emmc_boot1_size', '>Q'),
('m_emmc_boot2_size', '>Q'),
('m_emmc_rpmb_size', '>Q'),
('m_emmc_gp_size', '>4Q'),
('m_emmc_ua_size', '>Q'),
('m_emmc_cid', '>2Q'),
('m_emmc_fwver', '8B')
]
def __init__(self, data):
sh = structhelper(data)
self.m_nand_pagesize = sh.short(True)
self.m_nand_sparesize = sh.short(True)
self.m_nand_pages_per_block = sh.short(True)
self.m_nand_io_interface = sh.bytes(1)
self.m_nand_addr_cycle = sh.bytes(1)
self.m_nand_bmt_exist = sh.bytes(1)
sdcinfo = [
('m_sdmmc_info', '>I'),
('m_sdmmc_ua_size', '>Q'),
('m_sdmmc_cid', '>2Q')
]
configinfo = [
('m_int_sram_ret', '>I'),
('m_int_sram_size', '>I'),
('m_ext_ram_ret', '>I'),
('m_ext_ram_type', 'B'),
('m_ext_ram_chip_select', 'B'),
('m_ext_ram_size', '>Q'),
('randomid', '>2Q'),
]
class emmcinfo:
m_emmc_ret = None
m_emmc_boot1_size = None
m_emmc_boot2_size = None
m_emmc_rpmb_size = None
m_emmc_gp_size = None
m_emmc_ua_size = None
m_emmc_cid = None
m_emmc_fwver = None
passinfo = [
('ack', 'B'),
('m_download_status', '>I'),
('m_boot_style', '>I'),
('soc_ok', 'B')
]
def __init__(self, data):
sh = structhelper(data)
self.m_emmc_ret = sh.dword(True)
self.m_emmc_boot1_size = sh.qword(True)
self.m_emmc_boot2_size = sh.qword(True)
self.m_emmc_rpmb_size = sh.qword(True)
self.m_emmc_gp_size = sh.qwords(4, True)
self.m_emmc_ua_size = sh.qword(True)
self.m_emmc_cid = sh.qwords(2, True)
self.m_emmc_fwver = sh.bytes(8)
class sdcinfo:
m_sdmmc_info = None
m_sdmmc_ua_size = None
m_sdmmc_cid = None
def __init__(self, data):
sh = structhelper(data)
self.m_sdmmc_info = sh.dword(True)
self.m_sdmmc_ua_size = sh.qword(True)
self.m_sdmmc_cid = sh.qwords(2, True)
class configinfo:
m_int_sram_ret = None
m_int_sram_size = None
m_ext_ram_ret = None
m_ext_ram_type = None
m_ext_ram_chip_select = None
m_ext_ram_size = None
randomid = None
def __init__(self, data):
sh = structhelper(data)
self.m_int_sram_ret = sh.dword(True)
self.m_int_sram_size = sh.dword(True)
self.m_ext_ram_ret = sh.dword(True)
self.m_ext_ram_type = sh.bytes()
self.m_ext_ram_chip_select = sh.bytes()
self.m_ext_ram_size = sh.qword(True)
self.randomid = sh.qwords(2, True)
class passinfo:
ack = None
m_download_status = None
m_boot_style = None
soc_ok = None
def __init__(self, data):
sh = structhelper(data)
self.ack = sh.bytes()
self.m_download_status = sh.dword(True)
self.m_boot_style = sh.dword(True)
self.soc_ok = sh.bytes()
def crc_word(data, chs=0):
@ -491,6 +564,9 @@ class DALegacy(metaclass=LogBase):
def __init__(self, mtk, daconfig, loglevel=logging.INFO):
self.__logger = logsetup(self, self.__logger, loglevel)
self.debug = self.debug
self.error = self.error
self.info = self.info
self.emmc = None
self.nand = None
self.nor = None
@ -762,22 +838,19 @@ class DALegacy(metaclass=LogBase):
return buffer
def read_flash_info(self):
data = self.usbread(0x1C)
self.nor = read_object(data, norinfo)
self.nor = norinfo(self.usbread(0x1C))
data = self.usbread(0x11)
self.nand = read_object(data, nandinfo64)
nandcount = self.nand["m_nand_flash_id_count"]
self.nand = nandinfo64(data)
nandcount = self.nand.m_nand_flash_id_count
if nandcount == 0:
self.nand = read_object(data, nandinfo32)
nandcount = self.nand["m_nand_flash_id_count"]
self.nand = nandinfo32(data)
nandcount = self.nand.m_nand_flash_id_count
nc = data[-4:] + self.usbread(nandcount * 2 - 4)
else:
nc = self.usbread(nandcount * 2)
m_nand_dev_code = unpack(">" + str(nandcount) + "H", nc)
self.nand["m_nand_flash_dev_code"] = m_nand_dev_code
ni2 = read_object(self.usbread(9), nandinfo2)
for ni in ni2:
self.nand[ni] = ni2[ni]
self.nand.m_nand_flash_dev_code = m_nand_dev_code
self.nand.info2 = nandinfo2(self.usbread(9))
self.emmc = read_object(self.usbread(0x5C), emmcinfo)
self.sdc = read_object(self.usbread(0x1C), sdcinfo)
self.flashconfig = read_object(self.usbread(0x26), configinfo)
@ -798,11 +871,11 @@ class DALegacy(metaclass=LogBase):
self.info("Uploading stage 1...")
with open(loader, 'rb') as bootldr:
# stage 1
stage = 2
offset = self.daconfig.da[stage]["m_buf"]
size = self.daconfig.da[stage]["m_len"]
address = self.daconfig.da[stage]["m_start_addr"]
sig_len = self.daconfig.da[stage]["m_sig_len"]
stage = 1
offset = self.daconfig.da.region[stage].m_buf
size = self.daconfig.da.region[stage].m_len
address = self.daconfig.da.region[stage].m_start_addr
sig_len = self.daconfig.da.region[stage].m_sig_len
bootldr.seek(offset)
dadata = bootldr.read(size)
if self.mtk.preloader.send_da(address, size, sig_len, dadata):
@ -849,16 +922,16 @@ class DALegacy(metaclass=LogBase):
self.set_stage2_config(self.config.hwcode)
self.info("Uploading stage 2...")
# stage 2
if self.brom_send(self.daconfig, bootldr, 3):
if self.brom_send(self.daconfig, bootldr, 2):
if self.read_flash_info():
if self.daconfig.flashtype == "nand":
self.daconfig.flashsize = self.nand["m_nand_flash_size"]
self.daconfig.flashsize = self.nand.m_nand_flash_size
elif self.daconfig.flashtype == "emmc":
self.daconfig.flashsize = self.emmc["m_emmc_ua_size"]
self.daconfig.flashsize = self.emmc.m_emmc_ua_size
if self.daconfig.flashsize == 0:
self.daconfig.flashsize = self.sdc["m_sdmmc_ua_size"]
self.daconfig.flashsize = self.sdc.m_sdmmc_ua_size
elif self.daconfig.flashtype == "nor":
self.daconfig.flashsize = self.nor["m_nor_flash_size"]
self.daconfig.flashsize = self.nor.m_nor_flash_size
self.info("Reconnecting to preloader")
self.set_usb_cmd()
self.mtk.port.close(reset=False)
@ -908,9 +981,9 @@ class DALegacy(metaclass=LogBase):
self.mtk.port.close(reset=True)
def brom_send(self, dasetup, da, stage, packetsize=0x1000):
offset = dasetup.da[stage]["m_buf"]
size = dasetup.da[stage]["m_len"]
address = dasetup.da[stage]["m_start_addr"]
offset = dasetup.da.region[stage].m_buf
size = dasetup.da.region[stage].m_len
address = dasetup.da.region[stage].m_start_addr
da.seek(offset)
dadata = da.read(size)
self.usbwrite(pack(">I", address))
@ -974,40 +1047,8 @@ class DALegacy(metaclass=LogBase):
return False
def sdmmc_write_data(self, addr, length, filename, offset=0, parttype=None, wdata=None, display=True):
if parttype is None or parttype == "user":
length = min(length, self.emmc["m_emmc_ua_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_USER
elif parttype == "boot1":
length = min(length, self.emmc["m_emmc_boot1_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT1
elif parttype == "boot2":
length = min(length, self.emmc["m_emmc_boot2_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT2
elif parttype == "gp1":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP1
elif parttype == "gp2":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP2
elif parttype == "gp3":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP3
elif parttype == "gp4":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP4
elif parttype == "rpmb":
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_RPMB
if self.daconfig.flashtype == "nor":
storage = DaStorage.MTK_DA_STORAGE_NOR
elif self.daconfig.flashtype == "nand":
storage = DaStorage.MTK_DA_STORAGE_NAND
elif self.daconfig.flashtype == "ufs":
storage = DaStorage.MTK_DA_STORAGE_UFS
elif self.daconfig.flashtype == "sdc":
storage = DaStorage.MTK_DA_STORAGE_SDMMC
else:
storage = DaStorage.MTK_DA_STORAGE_EMMC
length, parttype = self.get_parttype(length, parttype)
storage = self.get_storage()
if filename is not None:
fh = open(filename, "rb")
@ -1043,6 +1084,19 @@ class DALegacy(metaclass=LogBase):
self.progress.show_progress("Write", 100, 100, display)
return True
def get_storage(self):
if self.daconfig.flashtype == "nor":
storage = DaStorage.MTK_DA_STORAGE_NOR
elif self.daconfig.flashtype == "nand":
storage = DaStorage.MTK_DA_STORAGE_NAND
elif self.daconfig.flashtype == "ufs":
storage = DaStorage.MTK_DA_STORAGE_UFS
elif self.daconfig.flashtype == "sdc":
storage = DaStorage.MTK_DA_STORAGE_SDMMC
else:
storage = DaStorage.MTK_DA_STORAGE_EMMC
return storage
def sdmmc_write_image(self, addr, length, filename, display=True):
if filename != "":
with open(filename, "rb") as rf:
@ -1091,29 +1145,7 @@ class DALegacy(metaclass=LogBase):
wdata=wdata, display=display)
def formatflash(self, addr, length, parttype=None, display=True):
if parttype is None or parttype == "user" or parttype == "":
length = min(length, self.emmc["m_emmc_ua_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_USER
elif parttype == "boot1":
length = min(length, self.emmc["m_emmc_boot1_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT1
elif parttype == "boot2":
length = min(length, self.emmc["m_emmc_boot2_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT2
elif parttype == "gp1":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP1
elif parttype == "gp2":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP2
elif parttype == "gp3":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP3
elif parttype == "gp4":
length = min(length, self.emmc["m_emmc_gp_size"])
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP4
elif parttype == "rpmb":
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_RPMB
length, parttype = self.get_parttype(length, parttype)
self.check_usb_cmd()
if self.daconfig.flashtype == "emmc":
self.sdmmc_switch_part(parttype)
@ -1149,30 +1181,34 @@ class DALegacy(metaclass=LogBase):
return True
return False
def readflash(self, addr, length, filename, parttype=None, display=True):
def get_parttype(self, length, parttype):
if parttype is None or parttype == "user" or parttype == "":
length = min(length, self.emmc["m_emmc_ua_size"])
length = min(length, self.emmc.m_emmc_ua_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_USER
elif parttype == "boot1":
length = min(length, self.emmc["m_emmc_boot1_size"])
length = min(length, self.emmc.m_emmc_boot1_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT1
elif parttype == "boot2":
length = min(length, self.emmc["m_emmc_boot2_size"])
length = min(length, self.emmc.m_emmc_boot2_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_BOOT2
elif parttype == "gp1":
length = min(length, self.emmc["m_emmc_gp_size"])
length = min(length, self.emmc.m_emmc_gp_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP1
elif parttype == "gp2":
length = min(length, self.emmc["m_emmc_gp_size"])
length = min(length, self.emmc.m_emmc_gp_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP2
elif parttype == "gp3":
length = min(length, self.emmc["m_emmc_gp_size"])
length = min(length, self.emmc.m_emmc_gp_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP3
elif parttype == "gp4":
length = min(length, self.emmc["m_emmc_gp_size"])
length = min(length, self.emmc.m_emmc_gp_size)
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_GP4
elif parttype == "rpmb":
parttype = EMMC_PartitionType.MTK_DA_EMMC_PART_RPMB
return length, parttype
def readflash(self, addr, length, filename, parttype=None, display=True):
length, parttype = self.get_parttype(length, parttype)
self.check_usb_cmd()
packetsize = 0x0
if self.daconfig.flashtype == "emmc":

View file

@ -885,7 +885,7 @@ class DAXFlash(metaclass=LogBase):
dsize = min(write_packet_size, bytestowrite)
if fh:
data = bytearray(fh.read(dsize))
if len(data)<0x200:
if len(data)<write_packet_size:
data.extend(b"\x00"*fill)
else:
data = wdata[pos:pos + dsize]
@ -945,18 +945,18 @@ class DAXFlash(metaclass=LogBase):
self.info(f"Uploading stage 1 from {os.path.basename(loader)}")
with open(loader, 'rb') as bootldr:
# stage 1
da1offset = self.daconfig.da[2]["m_buf"]
da1size = self.daconfig.da[2]["m_len"]
da1address = self.daconfig.da[2]["m_start_addr"]
da2address = self.daconfig.da[2]["m_start_addr"]
da1sig_len = self.daconfig.da[2]["m_sig_len"]
da1offset = self.daconfig.da.region[1].m_buf
da1size = self.daconfig.da.region[1].m_len
da1address = self.daconfig.da.region[1].m_start_addr
da2address = self.daconfig.da.region[1].m_start_addr
da1sig_len = self.daconfig.da.region[1].m_sig_len
bootldr.seek(da1offset)
da1 = bootldr.read(da1size)
# ------------------------------------------------
da2offset = self.daconfig.da[3]["m_buf"]
da2sig_len = self.daconfig.da[3]["m_sig_len"]
da2offset = self.daconfig.da.region[2].m_buf
da2sig_len = self.daconfig.da.region[2].m_sig_len
bootldr.seek(da2offset)
da2 = bootldr.read(self.daconfig.da[3]["m_len"])
da2 = bootldr.read(self.daconfig.da.region[2].m_len)
hashaddr, hashmode = self.compute_hash_pos(da1, da2[:-da2sig_len])
if hashaddr is not None:
@ -983,7 +983,7 @@ class DAXFlash(metaclass=LogBase):
self.info("Successfully received DA sync")
return True
else:
self.error("Error on jumping to DA: " + hexlify(res).decode('utf-8'))
self.error(f"Error jumping to DA: {res}")
else:
self.error("Error on jumping to DA.")
else:
@ -1041,7 +1041,7 @@ class DAXFlash(metaclass=LogBase):
# dramtype = self.get_dram_type()
stage = None
if connagent == b"brom":
stage = 2
stage = 1
if self.daconfig.emi is None:
self.info("No preloader given. Searching for preloader")
found = False
@ -1073,12 +1073,12 @@ class DAXFlash(metaclass=LogBase):
else:
self.info("Sending emi data succeeded.")
elif connagent == b"preloader":
stage = 2
if stage == 2:
stage = 1
if stage == 1:
self.info("Uploading stage 2...")
with open(self.daconfig.loader, 'rb') as bootldr:
stage = stage + 1
loaded = self.boot_to(self.daconfig.da[stage]["m_start_addr"], self.daconfig.da2)
loaded = self.boot_to(self.daconfig.da.region[stage].m_start_addr, self.daconfig.da2)
if loaded:
self.info("Successfully uploaded stage 2")
self.reinit(True)

View file

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021 MIT License
import os
import shutil
import logging
from enum import Enum
from struct import unpack, pack

View file

@ -46,7 +46,7 @@ class PLTools(metaclass=LogBase):
self.pathconfig = pathconfig()
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.__logger.setLevel(logging.DEBUG)
else:

View file

@ -95,7 +95,7 @@ class usb_class(metaclass=LogBase):
self.__logger.setLevel(loglevel)
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
if sys.platform.startswith('freebsd') or sys.platform.startswith('linux'):

View file

@ -14,6 +14,7 @@ import copy
import time
import io
import datetime as dt
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding='utf-8')
@ -59,6 +60,7 @@ def find_binary(data, strf, pos=0):
pre += 1
return None
class progress:
def __init__(self, pagesize):
self.progtime = 0
@ -136,28 +138,39 @@ class structhelper:
self.pos = 0
self.data = data
def qword(self):
dat = unpack("<Q", self.data[self.pos:self.pos + 8])[0]
def qword(self, big=False):
e = ">" if big else "<"
dat = unpack(e + "Q", self.data[self.pos:self.pos + 8])[0]
self.pos += 8
return dat
def dword(self):
dat = unpack("<I", self.data[self.pos:self.pos + 4])[0]
def dword(self, big=False):
e = ">" if big else "<"
dat = unpack(e + "I", self.data[self.pos:self.pos + 4])[0]
self.pos += 4
return dat
def dwords(self, dwords=1):
dat = unpack("<" + str(dwords) + "I", self.data[self.pos:self.pos + 4 * dwords])
def dwords(self, dwords=1, big=False):
e = ">" if big else "<"
dat = unpack(e + str(dwords) + "I", self.data[self.pos:self.pos + 4 * dwords])
self.pos += 4 * dwords
return dat
def short(self):
dat = unpack("<H", self.data[self.pos:self.pos + 2])[0]
def qwords(self, qwords=1, big=False):
e = ">" if big else "<"
dat = unpack(e + str(qwords) + "Q", self.data[self.pos:self.pos + 8 * qwords])
self.pos += 4 * qwords
return dat
def short(self, big=False):
e = ">" if big else "<"
dat = unpack(e + "H", self.data[self.pos:self.pos + 2])[0]
self.pos += 2
return dat
def shorts(self, shorts):
dat = unpack("<" + str(shorts) + "H", self.data[self.pos:self.pos + 2 * shorts])
def shorts(self, shorts, big=False):
e = ">" if big else "<"
dat = unpack(e + str(shorts) + "H", self.data[self.pos:self.pos + 2 * shorts])
self.pos += 2 * shorts
return dat
@ -358,7 +371,7 @@ def logsetup(self, logger, loglevel):
self.warning = logger.warning
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
logger.addHandler(fh)
logger.setLevel(logging.DEBUG)
else:

View file

@ -120,7 +120,7 @@ class xflashext(metaclass=LogBase):
def patch(self):
self.da2 = self.xflash.daconfig.da2
self.da2address = self.xflash.daconfig.da[3]["m_start_addr"] # at_address
self.da2address = self.xflash.daconfig.da.region[2].m_start_addr # at_address
daextensions = os.path.join(self.pathconfig.get_payloads_path(), "da_x.bin")
if os.path.exists(daextensions):
daextdata = bytearray(open(daextensions, "rb").read())
@ -515,6 +515,8 @@ class xflashext(metaclass=LogBase):
socid = bytes.fromhex(open(os.path.join("logs", "socid.txt"), "r").read())
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
if self.config.chipconfig.dxcc_base is not None:
self.info("Generating dxcc platkey + provkey key...")
platkey, provkey = hwc.aes_hwcrypt(btype="dxcc", mode="prov")
self.info("Generating dxcc rpmbkey...")
rpmbkey = hwc.aes_hwcrypt(btype="dxcc", mode="rpmb")
self.info("Generating dxcc fdekey...")
@ -523,7 +525,8 @@ class xflashext(metaclass=LogBase):
rpmb2key = hwc.aes_hwcrypt(btype="dxcc", mode="rpmb2")
self.info("Generating dxcc itrustee key...")
ikey = hwc.aes_hwcrypt(btype="dxcc", mode="itrustee")
self.info("Provkey : " + hexlify(provkey).decode('utf-8'))
self.info("Platkey : " + hexlify(platkey).decode('utf-8'))
if rpmbkey is not None:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
open(os.path.join("logs", "rpmbkey.txt"), "wb").write(hexlify(rpmbkey))
@ -543,10 +546,15 @@ class xflashext(metaclass=LogBase):
open(os.path.join("logs", "hrid.txt"), "wb").write(hexlify(hrid))
"""
elif self.config.chipconfig.sej_base is not None:
if meid == b"":
if self.config.chipconfig.meid_addr:
meid = self.custom_read(self.config.chipconfig.meid_addr,16)
if meid != b"":
self.info("Generating sej rpmbkey...")
self.setotp(hwc)
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej")
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
open(os.path.join("logs", "rpmbkey.txt"), "wb").write(hexlify(rpmbkey))
else:
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
return True

View file

@ -611,29 +611,30 @@ hwconfig = {
description="Helio P20",
loader="mt6757_payload.bin"),
0x688: chipconfig(
# var1
watchdog=0x10210000,
var1=0xA,
watchdog=0x10211000, #
uart=0x11020000,
brom_payload_addr=0x100A00,
da_payload_addr=0x201000,
brom_payload_addr=0x100A00, #
da_payload_addr=0x201000, #
pl_payload_addr=0x40200000, #
gcpu_base=0x10050000,
gcpu_base=0x10050000, #
sej_base=0x10080000, # hacc
dxcc_base=0x11240000,
cqdma_base=0x10200000,
ap_dma_mem=0x11000000 + 0x1A0,
# blacklist
# blacklist_count
# send_ptr
# ctrl_buffer
# cmd_handler
# brom_Register_access
# meid_addr
dxcc_base=0x11240000, #
cqdma_base=0x10200000, #
ap_dma_mem=0x11000000 + 0x1A0, #
blacklist=[(0x102830,0),(0x106A60,0)],
blacklist_count=0xA,
send_ptr=(0x102874,0xd860),
ctrl_buffer=0x102B28,
cmd_handler=0xE58D,
brom_register_access=(0xdc74,0xdd2c),
meid_addr=0x102bf8,
socid_addr=0x102c08,
damode=damodes.XFLASH,
dacode=0x6758,
name="MT6758",
description="Helio P30",
# loader
loader="mt6758_payload.bin"
),
0x507: chipconfig( # var1
watchdog=0x10210000,

View file

@ -0,0 +1,34 @@
mt0571
mt0598
mt0992
mt2503
mt3967
mt5700
mt6255
mt6280
mt6516
mt6570 = 0x633
mt6571
mt6573
mt6575
mt6577
mt6588
mt6583
mt6750 = 6x601
mt6752
mt6758 = 0x688
mt6759 = 0x507
mt6877 = 0x959
mt8110
mt8135
mt8168
mt8176
mt8195 = 0x930
mt8512
mt8518
mt8696 = 0x908

View file

@ -7,5 +7,4 @@ default_ids = [
[0x1004, 0x6000, 2], # LG Preloader
[0x22d9, 0x0006, -1], # OPPO Preloader
[0x0FCE, 0xF200, -1], # Sony Brom
[0x1a86, 0x7523, 0]
]

Binary file not shown.

Binary file not shown.

2
stage2
View file

@ -33,7 +33,7 @@ class Stage2(metaclass=LogBase):
logfilename = os.path.join("logs", "log.txt")
if os.path.exists(logfilename):
os.remove(logfilename)
fh = logging.FileHandler(logfilename)
fh = logging.FileHandler(logfilename, encoding='utf-8')
self.__logger.addHandler(fh)
self.__logger.setLevel(logging.DEBUG)
else: