mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-11-27 09:55:37 -05:00
Compare commits
5 commits
2669bb91ba
...
ee6c8b0ca8
Author | SHA1 | Date | |
---|---|---|---|
|
ee6c8b0ca8 | ||
|
501a23a7fa | ||
|
e3cd58a837 | ||
|
35c5803ae0 | ||
|
2e65679cc8 |
12 changed files with 244 additions and 108 deletions
Binary file not shown.
|
@ -309,7 +309,7 @@ class UsbClass(DeviceClass):
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.device is None:
|
if self.device is None:
|
||||||
self.debug("Couldn't detect the device. Is it connected ?")
|
# self.debug("Couldn't detect the device. Is it connected ?")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -96,15 +96,29 @@ class EntryRegion:
|
||||||
|
|
||||||
|
|
||||||
class DA:
|
class DA:
|
||||||
def __init__(self, data):
|
v6=False
|
||||||
|
loader=None
|
||||||
|
magic=0
|
||||||
|
hw_code=0
|
||||||
|
hw_sub_code=0
|
||||||
|
hw_version=0
|
||||||
|
sw_version=0
|
||||||
|
pagesize=512
|
||||||
|
entry_region_index=1
|
||||||
|
entry_region_count=0
|
||||||
|
region = []
|
||||||
|
|
||||||
|
def __init__(self, data, old_ldr:bool=False, v6:bool=False):
|
||||||
self.loader = None
|
self.loader = None
|
||||||
|
self.v6 = v6
|
||||||
sh = Structhelper(data)
|
sh = Structhelper(data)
|
||||||
self.magic = sh.short()
|
self.magic = sh.short()
|
||||||
self.hw_code = sh.short()
|
self.hw_code = sh.short()
|
||||||
self.hw_sub_code = sh.short()
|
self.hw_sub_code = sh.short()
|
||||||
self.hw_version = sh.short()
|
self.hw_version = sh.short()
|
||||||
self.sw_version = sh.short()
|
if not old_ldr:
|
||||||
self.reserved1 = sh.short()
|
self.sw_version = sh.short()
|
||||||
|
self.reserved1 = sh.short()
|
||||||
self.pagesize = sh.short()
|
self.pagesize = sh.short()
|
||||||
self.reserved3 = sh.short()
|
self.reserved3 = sh.short()
|
||||||
self.entry_region_index = sh.short()
|
self.entry_region_index = sh.short()
|
||||||
|
@ -113,6 +127,7 @@ class DA:
|
||||||
for _ in range(self.entry_region_count):
|
for _ in range(self.entry_region_count):
|
||||||
entry_tmp = EntryRegion(sh.bytes(20))
|
entry_tmp = EntryRegion(sh.bytes(20))
|
||||||
self.region.append(entry_tmp)
|
self.region.append(entry_tmp)
|
||||||
|
self.old_ldr = old_ldr
|
||||||
|
|
||||||
def setfilename(self, loaderfilename: str):
|
def setfilename(self, loaderfilename: str):
|
||||||
self.loader = loaderfilename
|
self.loader = loaderfilename
|
||||||
|
@ -222,11 +237,17 @@ class DAconfig(metaclass=LogBase):
|
||||||
hdr = bootldr.read(0x68)
|
hdr = bootldr.read(0x68)
|
||||||
count_da = unpack("<I", bootldr.read(4))[0]
|
count_da = unpack("<I", bootldr.read(4))[0]
|
||||||
v6 = b"MTK_DA_v6" in hdr
|
v6 = b"MTK_DA_v6" in hdr
|
||||||
|
old_ldr = False
|
||||||
|
bootldr.seek(0x6C+0xD8)
|
||||||
|
if bootldr.read(2) == b"\xDA\xDA":
|
||||||
|
offset=0xD8
|
||||||
|
old_ldr = True
|
||||||
|
else:
|
||||||
|
offset=0xDC
|
||||||
for i in range(0, count_da):
|
for i in range(0, count_da):
|
||||||
bootldr.seek(0x6C + (i * 0xDC))
|
bootldr.seek(0x6C + (i * offset))
|
||||||
da = DA(bootldr.read(0xDC))
|
da = DA(bootldr.read(offset),old_ldr, v6)
|
||||||
da.setfilename(loader)
|
da.setfilename(loader)
|
||||||
da.v6 = v6
|
|
||||||
# if da.hw_code == 0x8127 and "5.1824" not in loader:
|
# if da.hw_code == 0x8127 and "5.1824" not in loader:
|
||||||
# continue
|
# continue
|
||||||
if da.hw_code not in dasetup:
|
if da.hw_code not in dasetup:
|
||||||
|
|
|
@ -290,6 +290,12 @@ class DALegacy(metaclass=LogBase):
|
||||||
return False
|
return False
|
||||||
errorcode = int.from_bytes(buffer, 'big')
|
errorcode = int.from_bytes(buffer, 'big')
|
||||||
if errorcode == 0x0:
|
if errorcode == 0x0:
|
||||||
|
if hwcode == 0x6592:
|
||||||
|
tmp1=self.usbread(4)
|
||||||
|
tmp2=self.usbread(4)
|
||||||
|
tmp3=self.usbread(4)
|
||||||
|
tmp4 = self.usbread(4)
|
||||||
|
tmp5 = self.usbread(4)
|
||||||
return True
|
return True
|
||||||
if errorcode != 0xBC3:
|
if errorcode != 0xBC3:
|
||||||
self.error(self.eh.status(errorcode))
|
self.error(self.eh.status(errorcode))
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
|
@ -184,27 +185,28 @@ class DaHandler(metaclass=LogBase):
|
||||||
|
|
||||||
def da_vbmeta(self, vbmode:int=3):
|
def da_vbmeta(self, vbmode:int=3):
|
||||||
gpttable = self.mtk.daloader.get_partition_data(parttype="user")
|
gpttable = self.mtk.daloader.get_partition_data(parttype="user")
|
||||||
for partition in ["vbmeta","vbmeta_a"]:
|
slot = self.get_current_slot()
|
||||||
rpartition = None
|
partition="vbmeta"+slot
|
||||||
for gptentry in gpttable:
|
rpartition = None
|
||||||
if gptentry.name.lower() == partition.lower():
|
for gptentry in gpttable:
|
||||||
rpartition = gptentry
|
if gptentry.name.lower() == partition.lower():
|
||||||
break
|
rpartition = gptentry
|
||||||
if rpartition is not None:
|
break
|
||||||
self.info(f'Dumping partition "{rpartition.name}"')
|
if rpartition is not None:
|
||||||
vbmeta=self.mtk.daloader.readflash(addr=rpartition.sector * self.config.pagesize,
|
self.info(f'Dumping partition "{rpartition.name}"')
|
||||||
length=rpartition.sectors * self.config.pagesize,
|
vbmeta=self.mtk.daloader.readflash(addr=rpartition.sector * self.config.pagesize,
|
||||||
filename="", parttype="user")
|
length=rpartition.sectors * self.config.pagesize,
|
||||||
if vbmeta!=b"":
|
filename="", parttype="user")
|
||||||
self.info(f'Patching vbmeta"')
|
if vbmeta!=b"":
|
||||||
patched_vbmeta = self.patch_vbmeta(vbmeta,vbmode)
|
self.info(f'Patching {partition}"')
|
||||||
self.info(f'Writing partition "{rpartition.name}"')
|
patched_vbmeta = self.patch_vbmeta(vbmeta,vbmode)
|
||||||
if self.mtk.daloader.writeflash(addr=rpartition.sector * self.config.pagesize,
|
self.info(f'Writing partition "{rpartition.name}"')
|
||||||
length=rpartition.sectors * self.config.pagesize,
|
if self.mtk.daloader.writeflash(addr=rpartition.sector * self.config.pagesize,
|
||||||
wdata=patched_vbmeta, parttype="user"):
|
length=rpartition.sectors * self.config.pagesize,
|
||||||
self.info("Successfully patched vbmeta :)")
|
wdata=patched_vbmeta, parttype="user"):
|
||||||
else:
|
self.info("Successfully patched vbmeta :)")
|
||||||
self.error("Error on patching vbmeta :(")
|
else:
|
||||||
|
self.error("Error on patching vbmeta :(")
|
||||||
|
|
||||||
def da_gpt(self, directory: str):
|
def da_gpt(self, directory: str):
|
||||||
if directory is None:
|
if directory is None:
|
||||||
|
@ -225,6 +227,36 @@ class DaHandler(metaclass=LogBase):
|
||||||
wf.write(data[self.mtk.daloader.daconfig.pagesize:])
|
wf.write(data[self.mtk.daloader.daconfig.pagesize:])
|
||||||
print(f"Dumped Backup GPT to {sfilename}")
|
print(f"Dumped Backup GPT to {sfilename}")
|
||||||
|
|
||||||
|
def da_read_partition(self, partitionname, parttype="user"):
|
||||||
|
rpartition = None
|
||||||
|
gpttable = self.mtk.daloader.get_partition_data(parttype=parttype)
|
||||||
|
for gptentry in gpttable:
|
||||||
|
if gptentry.name.lower() == partitionname.lower():
|
||||||
|
rpartition = gptentry
|
||||||
|
break
|
||||||
|
if rpartition is not None:
|
||||||
|
self.info(f'Dumping partition "{rpartition.name}"')
|
||||||
|
data=self.mtk.daloader.readflash(addr=rpartition.sector * self.config.pagesize,
|
||||||
|
length=rpartition.sectors * self.config.pagesize,
|
||||||
|
filename="", parttype=parttype)
|
||||||
|
return data
|
||||||
|
return None
|
||||||
|
|
||||||
|
def da_write_partition(self, partitionname, data:bytes=None, parttype="user"):
|
||||||
|
rpartition = None
|
||||||
|
gpttable = self.mtk.daloader.get_partition_data(parttype=parttype)
|
||||||
|
for gptentry in gpttable:
|
||||||
|
if gptentry.name.lower() == partitionname.lower():
|
||||||
|
rpartition = gptentry
|
||||||
|
break
|
||||||
|
if rpartition is not None:
|
||||||
|
self.info(f'Writing partition "{rpartition.name}"')
|
||||||
|
res=self.mtk.daloader.writeflash(addr=rpartition.sector * self.config.pagesize,
|
||||||
|
length=rpartition.sectors * self.config.pagesize,
|
||||||
|
filename="", parttype=parttype, wdata=data)
|
||||||
|
return res
|
||||||
|
return None
|
||||||
|
|
||||||
def da_read(self, partitionname, parttype, filename):
|
def da_read(self, partitionname, parttype, filename):
|
||||||
filenames = filename.split(",")
|
filenames = filename.split(",")
|
||||||
partitions = partitionname.split(",")
|
partitions = partitionname.split(",")
|
||||||
|
@ -639,6 +671,16 @@ class DaHandler(metaclass=LogBase):
|
||||||
data = bytearray(self.mtk.daloader.peek(addr=addr, length=4))
|
data = bytearray(self.mtk.daloader.peek(addr=addr, length=4))
|
||||||
self.info(f"EFuse Idx {hex(idx)}: {data.hex()}")
|
self.info(f"EFuse Idx {hex(idx)}: {data.hex()}")
|
||||||
|
|
||||||
|
def get_current_slot(self):
|
||||||
|
tmp = self.da_read_partition("misc")
|
||||||
|
if tmp == b"":
|
||||||
|
tmp = self.da_read_partition("para")
|
||||||
|
if tmp != b"":
|
||||||
|
slot = tmp[0x800:0x802].decode('utf-8')
|
||||||
|
else:
|
||||||
|
slot = ""
|
||||||
|
return slot
|
||||||
|
|
||||||
def da_brom(self, filename: str):
|
def da_brom(self, filename: str):
|
||||||
return self.mtk.daloader.dump_brom(filename)
|
return self.mtk.daloader.dump_brom(filename)
|
||||||
|
|
||||||
|
|
|
@ -572,7 +572,7 @@ class XFlashExt(metaclass=LogBase):
|
||||||
towrite -= sz
|
towrite -= sz
|
||||||
if display:
|
if display:
|
||||||
progressbar.show_progress("RPMB written", sectors * 0x100, sectors * 0x100, display)
|
progressbar.show_progress("RPMB written", sectors * 0x100, sectors * 0x100, display)
|
||||||
self.info(f"Done reading writing {filename} to rpmb")
|
self.info(f"Done writing {filename} to rpmb")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -868,7 +868,7 @@ class XFlashExt(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
||||||
if self.config.chipconfig.gcpu_base is not None:
|
if self.config.chipconfig.gcpu_base is not None:
|
||||||
if self.config.hwcode in [0x335, 0x8167, 0x8163, 0x8176]:
|
if self.config.hwcode in [0x335, 0x8167, 0x8168, 0x8163, 0x8176]:
|
||||||
self.info("Generating gcpu mtee2 key...")
|
self.info("Generating gcpu mtee2 key...")
|
||||||
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
||||||
if mtee2 is not None:
|
if mtee2 is not None:
|
||||||
|
|
|
@ -278,6 +278,11 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
da2patched[idx2:idx2 + 8] = b"\x00\x00\xA0\xE3\x1E\xFF\x2F\xE1"
|
da2patched[idx2:idx2 + 8] = b"\x00\x00\xA0\xE3\x1E\xFF\x2F\xE1"
|
||||||
self.info("Patched Vivo Remote SLA authentification.")
|
self.info("Patched Vivo Remote SLA authentification.")
|
||||||
else:
|
else:
|
||||||
|
idx=da2patched.find(b"DA.SLA\x00ENABLED")
|
||||||
|
if idx!=-1:
|
||||||
|
patch = b"DA.SLA\x00DISABLE"
|
||||||
|
da2patched[idx:idx+len(patch)] = patch
|
||||||
|
"""
|
||||||
n = "9BB734774443D77557A76E24B10733787750D90D09C869CD606D54F28978EA6220DC9948B3C9E89284F8551D6166F3754B6A3B890AC9CDA9E37DFAA0C1317E351CE5107C4273795949C6CCE638314AB1A345385D7642CB8D055A1F410C7D7E24A6F0A2AAB8184E773D21B3754A947541680F2C1A8D6BA5BEFD3B6E1FC28EC0B61D55B1454383F2C3E8BD27170A25978608F6788B90A2FC34F0CE35056BF7520795C8C60232CBBC0B0399367AF937869CA45CF737A8A066127893E93166C433298DD6FD009E6790E743B3392ACA8EA99F61DFC77BD99416DDA4B8A9D7E4DA24217427F3584119A4932016F1735CC63B12650FDDDA73C8FCFBC79E058F36219D3D"
|
n = "9BB734774443D77557A76E24B10733787750D90D09C869CD606D54F28978EA6220DC9948B3C9E89284F8551D6166F3754B6A3B890AC9CDA9E37DFAA0C1317E351CE5107C4273795949C6CCE638314AB1A345385D7642CB8D055A1F410C7D7E24A6F0A2AAB8184E773D21B3754A947541680F2C1A8D6BA5BEFD3B6E1FC28EC0B61D55B1454383F2C3E8BD27170A25978608F6788B90A2FC34F0CE35056BF7520795C8C60232CBBC0B0399367AF937869CA45CF737A8A066127893E93166C433298DD6FD009E6790E743B3392ACA8EA99F61DFC77BD99416DDA4B8A9D7E4DA24217427F3584119A4932016F1735CC63B12650FDDDA73C8FCFBC79E058F36219D3D"
|
||||||
pubkey = bytes.fromhex(n)
|
pubkey = bytes.fromhex(n)
|
||||||
# Generic SLA patch, just replace the public key with a known one
|
# Generic SLA patch, just replace the public key with a known one
|
||||||
|
@ -291,7 +296,7 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
if idx2 is not None:
|
if idx2 is not None:
|
||||||
da2patched[idx2 - 0x100:idx2] = pubkey
|
da2patched[idx2 - 0x100:idx2] = pubkey
|
||||||
self.warning("SLA authentification not patched.")
|
self.warning("SLA authentification not patched.")
|
||||||
|
"""
|
||||||
# open("da.patched.bin",
|
# open("da.patched.bin",
|
||||||
# "wb").write(da2patched)
|
# "wb").write(da2patched)
|
||||||
return da2patched
|
return da2patched
|
||||||
|
@ -341,12 +346,11 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
if len(data) % 0x100 != 0:
|
if len(data) % 0x100 != 0:
|
||||||
self.error("Incorrect rpmb frame length. Aborting")
|
self.error("Incorrect rpmb frame length. Aborting")
|
||||||
return False
|
return False
|
||||||
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMRPMBW")
|
|
||||||
if self.xflash.emmc is not None:
|
if self.xflash.emmc is not None:
|
||||||
ufs = False
|
ufs = False
|
||||||
|
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMRPMBW")
|
||||||
else:
|
else:
|
||||||
ufs = True
|
ufs = True
|
||||||
if ufs:
|
|
||||||
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMURPMBW")
|
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMURPMBW")
|
||||||
if self.xsend(xmlcmd):
|
if self.xsend(xmlcmd):
|
||||||
result = self.xflash.get_response()
|
result = self.xflash.get_response()
|
||||||
|
@ -405,14 +409,20 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
ufs = False
|
ufs = False
|
||||||
if self.xflash.emmc is None:
|
if self.xflash.emmc is None:
|
||||||
ufs = True
|
ufs = True
|
||||||
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMMMCINIT")
|
|
||||||
if ufs:
|
|
||||||
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMUFSINIT")
|
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMUFSINIT")
|
||||||
|
else:
|
||||||
|
xmlcmd = self.xflash.Cmd.create_cmd("CUSTOMMMCINIT")
|
||||||
if self.xsend(xmlcmd):
|
if self.xsend(xmlcmd):
|
||||||
result = self.xflash.get_response()
|
result = self.xflash.get_response()
|
||||||
if result == "OK":
|
if result == "OK":
|
||||||
derivedrpmb = self.xflash.get_response(raw=True)
|
derivedrpmb = self.xflash.get_response(raw=True)
|
||||||
if int.from_bytes(derivedrpmb[:4], 'little') != 0xff:
|
if int.from_bytes(derivedrpmb[:4], 'little') != 0xff:
|
||||||
|
# rpmb frame
|
||||||
|
result = self.xflash.get_response(raw=True)
|
||||||
|
self.xflash.ack()
|
||||||
|
# hash
|
||||||
|
result = self.xflash.get_response(raw=True)
|
||||||
|
self.xflash.ack()
|
||||||
# CMD:END
|
# CMD:END
|
||||||
result = self.xflash.get_response()
|
result = self.xflash.get_response()
|
||||||
self.xflash.ack()
|
self.xflash.ack()
|
||||||
|
@ -450,7 +460,7 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
ufs = True
|
ufs = True
|
||||||
if sectors == 0:
|
if sectors == 0:
|
||||||
if not ufs:
|
if self.xflash.emmc is not None:
|
||||||
sectors = self.xflash.emmc.rpmb_size // 0x100
|
sectors = self.xflash.emmc.rpmb_size // 0x100
|
||||||
elif self.xflash.ufs.lu1_size != 0:
|
elif self.xflash.ufs.lu1_size != 0:
|
||||||
sectors = (512 * 256)
|
sectors = (512 * 256)
|
||||||
|
@ -507,7 +517,7 @@ class XmlFlashExt(metaclass=LogBase):
|
||||||
towrite -= 0x1
|
towrite -= 0x1
|
||||||
if display:
|
if display:
|
||||||
progressbar.show_progress("RPMB written", sectors * 0x100, sectors * 0x100, display)
|
progressbar.show_progress("RPMB written", sectors * 0x100, sectors * 0x100, display)
|
||||||
self.info(f"Done reading writing {filename} to rpmb")
|
self.info(f"Done writing {filename} to rpmb")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ class DAXML(metaclass=LogBase):
|
||||||
da2sig_len = self.daconfig.da_loader.region[2].m_sig_len
|
da2sig_len = self.daconfig.da_loader.region[2].m_sig_len
|
||||||
bootldr.seek(da2offset)
|
bootldr.seek(da2offset)
|
||||||
da2 = bootldr.read(self.daconfig.da_loader.region[2].m_len)
|
da2 = bootldr.read(self.daconfig.da_loader.region[2].m_len)
|
||||||
if self.patch or not self.config.target_config["sbc"]:
|
if self.patch or not self.config.target_config["sbc"] and not self.config.stock:
|
||||||
da1, da2 = self.patch_da(da1, da2)
|
da1, da2 = self.patch_da(da1, da2)
|
||||||
self.patch = True
|
self.patch = True
|
||||||
self.daconfig.da2 = da2
|
self.daconfig.da2 = da2
|
||||||
|
@ -453,9 +453,10 @@ class DAXML(metaclass=LogBase):
|
||||||
if display:
|
if display:
|
||||||
self.mtk.daloader.progress.clear()
|
self.mtk.daloader.progress.clear()
|
||||||
resp = self.get_response()
|
resp = self.get_response()
|
||||||
byteswritten = 0
|
pos = 0
|
||||||
|
bytestowrite=length
|
||||||
if resp == "OK":
|
if resp == "OK":
|
||||||
for pos in range(0, length, packet_length):
|
while bytestowrite>0:
|
||||||
self.ack_value(0)
|
self.ack_value(0)
|
||||||
resp = self.get_response()
|
resp = self.get_response()
|
||||||
if "OK" not in resp:
|
if "OK" not in resp:
|
||||||
|
@ -470,9 +471,10 @@ class DAXML(metaclass=LogBase):
|
||||||
if "OK" not in resp:
|
if "OK" not in resp:
|
||||||
self.error(f"Error on writing stage2 at pos {hex(pos)}")
|
self.error(f"Error on writing stage2 at pos {hex(pos)}")
|
||||||
return False
|
return False
|
||||||
byteswritten += tmplen
|
pos += tmplen
|
||||||
if display:
|
if display:
|
||||||
self.mtk.daloader.progress.show_progress("Written", byteswritten, length, display)
|
self.mtk.daloader.progress.show_progress("Written", pos, length, display)
|
||||||
|
bytestowrite-=packet_length
|
||||||
if raw:
|
if raw:
|
||||||
self.ack()
|
self.ack()
|
||||||
cmd, result = self.get_command_result()
|
cmd, result = self.get_command_result()
|
||||||
|
@ -597,8 +599,8 @@ class DAXML(metaclass=LogBase):
|
||||||
self.info("Stage 1 successfully loaded.")
|
self.info("Stage 1 successfully loaded.")
|
||||||
da2 = self.daconfig.da2
|
da2 = self.daconfig.da2
|
||||||
da2offset = self.daconfig.da_loader.region[2].m_start_addr
|
da2offset = self.daconfig.da_loader.region[2].m_start_addr
|
||||||
if not self.mtk.daloader.patch:
|
if not self.mtk.daloader.patch and not self.mtk.config.stock:
|
||||||
if self.carbonara is not None:
|
if self.carbonara is not None and self.mtk.config.target_config["sbc"]:
|
||||||
loaded = self.boot_to(da2offset, da2)
|
loaded = self.boot_to(da2offset, da2)
|
||||||
if loaded:
|
if loaded:
|
||||||
self.patch = True
|
self.patch = True
|
||||||
|
@ -798,8 +800,9 @@ class DAXML(metaclass=LogBase):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def change_usb_speed(self):
|
def change_usb_speed(self):
|
||||||
return self.send_command(self.Cmd.cmd_can_higher_usb_speed())
|
resp = self.send_command(self.Cmd.cmd_can_higher_usb_speed())
|
||||||
|
if not resp:
|
||||||
|
return False
|
||||||
|
|
||||||
def read_partition_table(self) -> tuple:
|
def read_partition_table(self) -> tuple:
|
||||||
self.send_command(self.Cmd.cmd_read_partition_table(), noack=True)
|
self.send_command(self.Cmd.cmd_read_partition_table(), noack=True)
|
||||||
|
|
|
@ -125,63 +125,51 @@ class Port(metaclass=LogBase):
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def run_handshake(self):
|
# def run_handshake(self):
|
||||||
ep_out = self.cdc.EP_OUT.write
|
|
||||||
ep_in = self.cdc.EP_IN.read
|
|
||||||
maxinsize = self.cdc.EP_IN.wMaxPacketSize
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
startcmd = b"\xa0\x0a\x50\x05"
|
|
||||||
length = len(startcmd)
|
|
||||||
# On preloader, send 0xa0 first
|
|
||||||
if self.cdc.pid!=0x3:
|
|
||||||
ep_out(startcmd[0:1])
|
|
||||||
try:
|
|
||||||
while i < length:
|
|
||||||
if ep_out(startcmd[i:i+1]):
|
|
||||||
if ep_in(maxinsize)[-1] == ~(startcmd[i]) & 0xFF:
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
i = 0
|
|
||||||
self.info("Device detected :)")
|
|
||||||
return True
|
|
||||||
except Exception as serr:
|
|
||||||
self.debug(str(serr))
|
|
||||||
time.sleep(0.005)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def handshake(self, maxtries=None, loop=0):
|
def handshake(self, maxtries=None, loop=0):
|
||||||
counter = 0
|
counter = 0
|
||||||
|
|
||||||
while not self.cdc.connected:
|
while not self.cdc.connected:
|
||||||
try:
|
try:
|
||||||
if maxtries is not None and counter == maxtries:
|
if maxtries is not None and counter == maxtries:
|
||||||
break
|
break
|
||||||
counter += 1
|
counter += 1
|
||||||
if self.cdc.connect() and self.run_handshake():
|
self.cdc.connect()
|
||||||
return True
|
ep_out = self.cdc.EP_OUT.write
|
||||||
else:
|
ep_in = self.cdc.EP_IN.read
|
||||||
if loop == 5:
|
maxinsize = self.cdc.EP_IN.wMaxPacketSize
|
||||||
sys.stdout.write('\n')
|
|
||||||
self.info("Hint:\n\nPower off the phone before connecting.\n" +
|
i = 0
|
||||||
"For brom mode, press and hold vol up, vol dwn, or all hw buttons and " +
|
startcmd = b"\xa0\x0a\x50\x05"
|
||||||
"connect usb.\n" +
|
length = len(startcmd)
|
||||||
"For preloader mode, don't press any hw button and connect usb.\n"
|
# On preloader, send 0xa0 first
|
||||||
"If it is already connected and on, hold power for 10 seconds to reset.\n")
|
if self.cdc.pid!=0x3:
|
||||||
sys.stdout.write('\n')
|
ep_out(startcmd[0:1])
|
||||||
if loop >= 10:
|
try:
|
||||||
sys.stdout.write('.')
|
while i < length:
|
||||||
if loop >= 20:
|
if ep_out(startcmd[i:i+1]):
|
||||||
sys.stdout.write('\n')
|
if ep_in(maxinsize)[-1] == ~(startcmd[i]) & 0xFF:
|
||||||
loop = 0
|
i += 1
|
||||||
loop += 1
|
else:
|
||||||
time.sleep(0.3)
|
i = 0
|
||||||
sys.stdout.flush()
|
|
||||||
|
|
||||||
|
self.info("Device detected :)")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as serr:
|
||||||
|
self.debug(str(serr))
|
||||||
|
time.sleep(0.005)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
except Exception as serr:
|
except Exception as serr:
|
||||||
if "access denied" in str(serr):
|
if "access denied" in str(serr):
|
||||||
self.warning(str(serr))
|
self.warning(str(serr))
|
||||||
self.debug(str(serr))
|
# self.debug(str(serr))
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,6 @@ class Preloader(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
res = self.mtk.port.handshake(maxtries=maxtries)
|
res = self.mtk.port.handshake(maxtries=maxtries)
|
||||||
if not res:
|
if not res:
|
||||||
if display:
|
|
||||||
self.error("Status: Handshake failed, retrying...")
|
|
||||||
self.config.set_gui_status(self.config.tr("Status: Handshake failed, retrying..."))
|
|
||||||
self.mtk.port.close()
|
self.mtk.port.close()
|
||||||
tries += 1
|
tries += 1
|
||||||
if tries == 1000:
|
if tries == 1000:
|
||||||
|
|
|
@ -275,6 +275,8 @@ class Structhelper:
|
||||||
|
|
||||||
def bytes(self, rlen=1):
|
def bytes(self, rlen=1):
|
||||||
dat = self.data[self.pos:self.pos + rlen]
|
dat = self.data[self.pos:self.pos + rlen]
|
||||||
|
if dat==b"":
|
||||||
|
return b""
|
||||||
self.pos += rlen
|
self.pos += rlen
|
||||||
if rlen == 1:
|
if rlen == 1:
|
||||||
return dat[0]
|
return dat[0]
|
||||||
|
|
|
@ -5,6 +5,10 @@ class DAmodes:
|
||||||
|
|
||||||
|
|
||||||
class Efuse:
|
class Efuse:
|
||||||
|
efuses = []
|
||||||
|
internal_fuses = []
|
||||||
|
external_fuses = []
|
||||||
|
|
||||||
def __init__(self, base, hwcode):
|
def __init__(self, base, hwcode):
|
||||||
if hwcode in [0x6570, 0x6580, 0x321, 0x335]:
|
if hwcode in [0x6570, 0x6580, 0x321, 0x335]:
|
||||||
self.efuses = [base + 0x20, base + 0x30, base + 0x38, base + 0x40, base + 0x44,
|
self.efuses = [base + 0x20, base + 0x30, base + 0x38, base + 0x40, base + 0x44,
|
||||||
|
@ -222,13 +226,43 @@ class Efuse:
|
||||||
|
|
||||||
|
|
||||||
class Chipconfig:
|
class Chipconfig:
|
||||||
|
var1 = None
|
||||||
|
watchdog = None
|
||||||
|
uart = None
|
||||||
|
brom_payload_addr = None
|
||||||
|
da_payload_addr = None
|
||||||
|
pl_payload_addr = None
|
||||||
|
cqdma_base = None
|
||||||
|
ap_dma_mem = None
|
||||||
|
sej_base = None
|
||||||
|
dxcc_base = None
|
||||||
|
name = ""
|
||||||
|
description = ""
|
||||||
|
dacode = 0
|
||||||
|
blacklist = None
|
||||||
|
blacklist_count = None
|
||||||
|
send_ptr = None
|
||||||
|
ctrl_buffer = None
|
||||||
|
cmd_handler = None
|
||||||
|
brom_register_access = None
|
||||||
|
meid_addr = None
|
||||||
|
socid_addr = None
|
||||||
|
prov_addr = None
|
||||||
|
gcpu_base = None
|
||||||
|
dacode = None
|
||||||
|
damode = None
|
||||||
|
loader = None
|
||||||
|
misc_lock = None
|
||||||
|
efuse_addr = None
|
||||||
|
has64bit = False
|
||||||
|
|
||||||
def __init__(self, var1=None, watchdog=None, uart=None, brom_payload_addr=None,
|
def __init__(self, var1=None, watchdog=None, uart=None, brom_payload_addr=None,
|
||||||
da_payload_addr=None, pl_payload_addr=None, cqdma_base=None, sej_base=None, dxcc_base=None,
|
da_payload_addr=None, pl_payload_addr=None, cqdma_base=None, sej_base=None, dxcc_base=None,
|
||||||
gcpu_base=None, ap_dma_mem=None, name="", description="", dacode=None,
|
gcpu_base=None, ap_dma_mem=None, name="", description="", dacode=None,
|
||||||
meid_addr=None, socid_addr=None, blacklist=(), blacklist_count=None,
|
meid_addr=None, socid_addr=None, blacklist=(), blacklist_count=None,
|
||||||
send_ptr=None, ctrl_buffer=(), cmd_handler=None, brom_register_access=None,
|
send_ptr=None, ctrl_buffer=(), cmd_handler=None, brom_register_access=None,
|
||||||
damode=DAmodes.LEGACY, loader=None, prov_addr=None, misc_lock=None,
|
damode=DAmodes.LEGACY, loader=None, prov_addr=None, misc_lock=None,
|
||||||
efuse_addr=None):
|
efuse_addr=None, has64bit=False):
|
||||||
self.var1 = var1
|
self.var1 = var1
|
||||||
self.watchdog = watchdog
|
self.watchdog = watchdog
|
||||||
self.uart = uart
|
self.uart = uart
|
||||||
|
@ -257,6 +291,7 @@ class Chipconfig:
|
||||||
self.loader = loader
|
self.loader = loader
|
||||||
self.misc_lock = misc_lock
|
self.misc_lock = misc_lock
|
||||||
self.efuse_addr = efuse_addr
|
self.efuse_addr = efuse_addr
|
||||||
|
self.has64bit = has64bit
|
||||||
|
|
||||||
# Credits to cyrozap and Chaosmaster for some values
|
# Credits to cyrozap and Chaosmaster for some values
|
||||||
"""
|
"""
|
||||||
|
@ -539,8 +574,8 @@ hwconfig = {
|
||||||
ap_dma_mem=0xC100119C,
|
ap_dma_mem=0xC100119C,
|
||||||
# blacklist
|
# blacklist
|
||||||
damode=DAmodes.LEGACY,
|
damode=DAmodes.LEGACY,
|
||||||
dacode=0x6572,
|
dacode=0x6575,
|
||||||
name="MT6575/77"),
|
name="MT6575/MT6577/MT8317"),
|
||||||
0x6577: Chipconfig( # var1
|
0x6577: Chipconfig( # var1
|
||||||
watchdog=0xC0000000,
|
watchdog=0xC0000000,
|
||||||
uart=0xC1009000,
|
uart=0xC1009000,
|
||||||
|
@ -1412,10 +1447,12 @@ hwconfig = {
|
||||||
# brom_register_access=(0xeba4, 0xec5c),
|
# brom_register_access=(0xeba4, 0xec5c),
|
||||||
meid_addr=0x1008EC,
|
meid_addr=0x1008EC,
|
||||||
socid_addr=0x100934,
|
socid_addr=0x100934,
|
||||||
|
efuse_addr=0x11EE0000,
|
||||||
# prov_addr=0x1066C0,
|
# prov_addr=0x1066C0,
|
||||||
damode=DAmodes.XML,
|
damode=DAmodes.XML,
|
||||||
dacode=0x907,
|
dacode=0x907,
|
||||||
name="MT6983",
|
name="MT6983",
|
||||||
|
has64bit=True,
|
||||||
description="Dimensity 9000/9000+"
|
description="Dimensity 9000/9000+"
|
||||||
# loader="mt6983_payload.bin"
|
# loader="mt6983_payload.bin"
|
||||||
),
|
),
|
||||||
|
@ -1468,6 +1505,7 @@ hwconfig = {
|
||||||
# brom_register_access=(0xeba4, 0xec5c),
|
# brom_register_access=(0xeba4, 0xec5c),
|
||||||
meid_addr=0x1008EC,
|
meid_addr=0x1008EC,
|
||||||
socid_addr=0x100934,
|
socid_addr=0x100934,
|
||||||
|
efuse_addr=0x11F10000,
|
||||||
# prov_addr=0x1066C0,
|
# prov_addr=0x1066C0,
|
||||||
damode=DAmodes.XML,
|
damode=DAmodes.XML,
|
||||||
dacode=0x1172,
|
dacode=0x1172,
|
||||||
|
@ -1475,6 +1513,33 @@ hwconfig = {
|
||||||
description="Dimensity 8200"
|
description="Dimensity 8200"
|
||||||
# loader="mt6893_payload.bin"
|
# loader="mt6893_payload.bin"
|
||||||
),
|
),
|
||||||
|
0x1203: Chipconfig(
|
||||||
|
var1=0xA,
|
||||||
|
watchdog=0x1c007000,
|
||||||
|
uart=0x11002000,
|
||||||
|
brom_payload_addr=0x100A00,
|
||||||
|
da_payload_addr=0x201000,
|
||||||
|
pl_payload_addr=0x40200000,
|
||||||
|
gcpu_base=0x1000D000,
|
||||||
|
dxcc_base=0x10403000,
|
||||||
|
sej_base=0x1040E000,
|
||||||
|
# cqdma_base=0x10212000,
|
||||||
|
# ap_dma_mem=0x11300800 + 0x1a0,
|
||||||
|
# blacklist=[(0x102848, 0x0), (0x00106B60, 0x0)],
|
||||||
|
# blacklist_count=0x0000000A,
|
||||||
|
# send_ptr=(0x102888, 0xE79C),
|
||||||
|
# ctrl_buffer=0x00102A9C,
|
||||||
|
# cmd_handler=0x0000F569,
|
||||||
|
# brom_register_access=(0xeba4, 0xec5c),
|
||||||
|
# meid_addr=0x1008EC,
|
||||||
|
socid_addr=0x20E7090,
|
||||||
|
# prov_addr=0x1066C0,
|
||||||
|
damode=DAmodes.XML,
|
||||||
|
dacode=0x1203,
|
||||||
|
name="MT6897",
|
||||||
|
description="Dimensity 8300 Ultra"
|
||||||
|
# loader="mt6897_payload.bin"
|
||||||
|
),
|
||||||
# MT6789 Oppo Realme 10 / Gigaset GX4
|
# MT6789 Oppo Realme 10 / Gigaset GX4
|
||||||
0x1208: Chipconfig(
|
0x1208: Chipconfig(
|
||||||
var1=0xA,
|
var1=0xA,
|
||||||
|
@ -1500,7 +1565,7 @@ hwconfig = {
|
||||||
efuse_addr=0x11C10000,
|
efuse_addr=0x11C10000,
|
||||||
damode=DAmodes.XML,
|
damode=DAmodes.XML,
|
||||||
dacode=0x1208,
|
dacode=0x1208,
|
||||||
name="MT6789",
|
name="MT6789/MT8781V",
|
||||||
description="MTK Helio G99"
|
description="MTK Helio G99"
|
||||||
# loader="mt6789_payload.bin"
|
# loader="mt6789_payload.bin"
|
||||||
),
|
),
|
||||||
|
@ -1511,10 +1576,10 @@ hwconfig = {
|
||||||
brom_payload_addr=0x100A00,
|
brom_payload_addr=0x100A00,
|
||||||
da_payload_addr=0x2001000,
|
da_payload_addr=0x2001000,
|
||||||
pl_payload_addr=0x40200000,
|
pl_payload_addr=0x40200000,
|
||||||
# gcpu_base=0x10050000,
|
gcpu_base=0x1000D000,
|
||||||
dxcc_base=0x10210000,
|
dxcc_base=0x1C807000,
|
||||||
# sej_base=0x1000a000,
|
sej_base=0x1C009000,
|
||||||
cqdma_base=0x10212000,
|
# cqdma_base=0x10212000,
|
||||||
# ap_dma_mem=0x11300800 + 0x1a0,
|
# ap_dma_mem=0x11300800 + 0x1a0,
|
||||||
# blacklist=[(0x102d5c, 0x0)],
|
# blacklist=[(0x102d5c, 0x0)],
|
||||||
# blacklist_count=0x0000000A,
|
# blacklist_count=0x0000000A,
|
||||||
|
@ -1525,23 +1590,24 @@ hwconfig = {
|
||||||
# meid_addr=0x1008EC,
|
# meid_addr=0x1008EC,
|
||||||
# socid_addr=0x100934,
|
# socid_addr=0x100934,
|
||||||
# prov_addr=0x1066C0,
|
# prov_addr=0x1066C0,
|
||||||
# efuse_addr=0x11C10000,
|
efuse_addr=0x11E30000,
|
||||||
damode=DAmodes.XML,
|
damode=DAmodes.XML,
|
||||||
dacode=0x1229,
|
dacode=0x1229,
|
||||||
|
has64bit=True,
|
||||||
name="MT6886",
|
name="MT6886",
|
||||||
description="Dimensity 7200 Ultra"
|
description="Dimensity 7200 Ultra"
|
||||||
# loader="mt7200_payload.bin"
|
# loader="mt7200_payload.bin"
|
||||||
),
|
),
|
||||||
0x1296: Chipconfig(
|
0x1296: Chipconfig(
|
||||||
var1=0xA,
|
var1=0xA,
|
||||||
watchdog=0x10007000,
|
watchdog=0x1C007000,
|
||||||
uart=0x11002000,
|
uart=0x1C011000,
|
||||||
brom_payload_addr=0x100A00,
|
brom_payload_addr=0x100A00,
|
||||||
da_payload_addr=0x201000,
|
da_payload_addr=0x201000,
|
||||||
pl_payload_addr=0x40200000,
|
pl_payload_addr=0x40200000,
|
||||||
# gcpu_base=0x10050000,
|
# gcpu_base=0x10050000,
|
||||||
dxcc_base=0x10210000,
|
dxcc_base=0x1C807000,
|
||||||
sej_base=0x1000a000,
|
sej_base=0x1C009000,
|
||||||
# cqdma_base=0x10212000,
|
# cqdma_base=0x10212000,
|
||||||
# ap_dma_mem=0x11300800 + 0x1a0,
|
# ap_dma_mem=0x11300800 + 0x1a0,
|
||||||
# blacklist=[(0x102d5c, 0x0)],
|
# blacklist=[(0x102d5c, 0x0)],
|
||||||
|
@ -1553,9 +1619,10 @@ hwconfig = {
|
||||||
meid_addr=0x1008EC,
|
meid_addr=0x1008EC,
|
||||||
socid_addr=0x100934,
|
socid_addr=0x100934,
|
||||||
# prov_addr=0x1066C0,
|
# prov_addr=0x1066C0,
|
||||||
# efuse_addr=0x11C10000,
|
efuse_addr=0x11E80000,
|
||||||
damode=DAmodes.XML,
|
damode=DAmodes.XML,
|
||||||
dacode=0x1296,
|
dacode=0x1296,
|
||||||
|
has64bit=True,
|
||||||
name="MT6985",
|
name="MT6985",
|
||||||
description="Dimensity 9200/9200+"
|
description="Dimensity 9200/9200+"
|
||||||
# loader="mt6985_payload.bin"
|
# loader="mt6985_payload.bin"
|
||||||
|
|
Loading…
Reference in a new issue