mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-11-14 19:25:05 -05:00
Update - Cleanup, Fixes and add new cpu
This commit is contained in:
parent
5d85238829
commit
55a679831d
21 changed files with 448 additions and 308 deletions
17
mtk
17
mtk
|
@ -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",
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
@ -148,9 +164,9 @@ class DAconfig(metaclass=LogBase):
|
|||
val = unpack("<I", emi[-4:])[0]
|
||||
if val == rlen:
|
||||
emi = emi[:rlen]
|
||||
if not self.config.chipconfig.damode==damodes.XFLASH:
|
||||
if emi.find(b"MTK_BIN")!=-1:
|
||||
emi=emi[emi.find(b"MTK_BIN")+0xC:]
|
||||
if not self.config.chipconfig.damode == damodes.XFLASH:
|
||||
if emi.find(b"MTK_BIN") != -1:
|
||||
emi = emi[emi.find(b"MTK_BIN") + 0xC:]
|
||||
return emi
|
||||
return None
|
||||
|
||||
|
@ -165,16 +181,12 @@ class DAconfig(metaclass=LogBase):
|
|||
with open(preloader, "rb") as rf:
|
||||
data = rf.read()
|
||||
else:
|
||||
assert "Preloader :"+preloader+" doesn't exist. Aborting."
|
||||
assert "Preloader :" + preloader + " doesn't exist. Aborting."
|
||||
exit(1)
|
||||
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 self.loader is None:
|
||||
self.da = setup
|
||||
self.loader = loader
|
||||
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 = loader
|
||||
self.loader = loader.loader
|
||||
|
||||
if self.da is None:
|
||||
self.error("No da config set up")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
@ -731,7 +807,7 @@ class DALegacy(metaclass=LogBase):
|
|||
dramlength = unpack(">I", self.usbread(0x4))[0] # 0x000000BC
|
||||
self.debug("Info: " + hex(dramlength))
|
||||
self.usbwrite(self.Rsp.ACK)
|
||||
lendram=len(self.daconfig.emi)
|
||||
lendram = len(self.daconfig.emi)
|
||||
self.usbwrite(pack(">I", lendram))
|
||||
elif val in [0x0B]:
|
||||
info = self.usbread(0x10) # 0x000000BC
|
||||
|
@ -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,43 +1047,11 @@ 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")
|
||||
fh = open(filename, "rb")
|
||||
fh.seek(offset)
|
||||
self.progress.show_progress("Write", 0, 100, display)
|
||||
self.usbwrite(self.Cmd.SDMMC_WRITE_DATA_CMD)
|
||||
|
@ -1029,20 +1070,33 @@ class DALegacy(metaclass=LogBase):
|
|||
if fh:
|
||||
data = bytearray(fh.read(count))
|
||||
else:
|
||||
data = wdata[offset:offset+count]
|
||||
data = wdata[offset:offset + count]
|
||||
self.usbwrite(data)
|
||||
chksum = sum(data) & 0xFFFF
|
||||
self.usbwrite(pack(">H", chksum))
|
||||
if self.usbread(1) != self.Rsp.CONT_CHAR:
|
||||
self.error("Data ack failed for sdmmc_write_data")
|
||||
return False
|
||||
self.progress.show_progress("Write",offset,length,display)
|
||||
self.progress.show_progress("Write", offset, length, display)
|
||||
offset += count
|
||||
if fh:
|
||||
fh.close()
|
||||
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":
|
||||
|
@ -1210,7 +1246,7 @@ class DALegacy(metaclass=LogBase):
|
|||
self.daconfig.readsize = self.daconfig.flashsize // self.daconfig.pagesize * (
|
||||
self.daconfig.pagesize + self.daconfig.sparesize)
|
||||
if display:
|
||||
self.progress.show_progress("Read",0,100,display)
|
||||
self.progress.show_progress("Read", 0, 100, display)
|
||||
if filename != "":
|
||||
with open(filename, "wb") as wf:
|
||||
bytestoread = length
|
||||
|
@ -1220,10 +1256,10 @@ class DALegacy(metaclass=LogBase):
|
|||
size = packetsize
|
||||
wf.write(self.usbread(size))
|
||||
bytestoread -= size
|
||||
checksum = unpack(">H", self.usbread(1)+self.usbread(1))[0]
|
||||
checksum = unpack(">H", self.usbread(1) + self.usbread(1))[0]
|
||||
self.debug("Checksum: %04X" % checksum)
|
||||
self.usbwrite(self.Rsp.ACK)
|
||||
self.progress.show_progress("Read", length-bytestoread, length, display)
|
||||
self.progress.show_progress("Read", length - bytestoread, length, display)
|
||||
self.progress.show_progress("Read", 100, 100, display)
|
||||
return True
|
||||
else:
|
||||
|
@ -1238,6 +1274,6 @@ class DALegacy(metaclass=LogBase):
|
|||
checksum = unpack(">H", self.usbread(2))[0]
|
||||
self.debug("Checksum: %04X" % checksum)
|
||||
self.usbwrite(self.Rsp.ACK)
|
||||
self.progress.show_progress("Read", length-bytestoread, length, display)
|
||||
self.progress.show_progress("Read", length - bytestoread, length, display)
|
||||
self.progress.show_progress("Read", 100, 100, display)
|
||||
return buffer
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -14,8 +14,9 @@ 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')
|
||||
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding='utf-8')
|
||||
|
||||
try:
|
||||
from capstone import *
|
||||
|
@ -59,6 +60,7 @@ def find_binary(data, strf, pos=0):
|
|||
pre += 1
|
||||
return None
|
||||
|
||||
|
||||
class progress:
|
||||
def __init__(self, pagesize):
|
||||
self.progtime = 0
|
||||
|
@ -76,7 +78,7 @@ class progress:
|
|||
lefttime = testimated - telapsed # in seconds
|
||||
return (int(telapsed), int(lefttime), finishtime)
|
||||
else:
|
||||
return 0,0,""
|
||||
return 0, 0, ""
|
||||
|
||||
def show_progress(self, prefix, pos, total, display=True):
|
||||
prog = round(float(pos) / float(total) * float(100), 1)
|
||||
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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,
|
||||
|
|
34
mtkclient/config/missing_brom.txt
Normal file
34
mtkclient/config/missing_brom.txt
Normal 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
|
|
@ -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.
BIN
mtkclient/payloads/mt6758_payload.bin
Executable file
BIN
mtkclient/payloads/mt6758_payload.bin
Executable file
Binary file not shown.
2
stage2
2
stage2
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue