1. Fix kamakiri not working

2. Fix vendor interfaces not detected (aka CDC Interface issue)
3. Fix UFS read flash issue
4. Add further improvements for meid detection
This commit is contained in:
Bjoern Kerler 2022-02-07 20:46:15 +01:00
parent 6e2686bc7a
commit 646311cd3d
11 changed files with 187 additions and 95 deletions

View file

@ -49,7 +49,9 @@ sudo usermod -a -G dialout $USER
sudo cp Setup/Linux/*.rules /etc/udev/rules.d
sudo udevadm control -R
```
Make sure to reboot after adding the user to dialout/plugdev.
Make sure to reboot after adding the user to dialout/plugdev. If the device
has a vendor interface 0xFF (like LG), make sure to add "blacklist qcaux" to
the "/etc/modprobe.d/blacklist.conf".
---------------------------------------------------------------------------------------------------------------

View file

@ -132,7 +132,7 @@ class Port(metaclass=LogBase):
data = [data]
for val in data:
self.usbwrite(val)
tmp = self.usbread(len(val))
tmp = self.usbread(len(val), maxtimeout=0)
# print(hexlify(tmp))
if val != tmp:
return False

View file

@ -71,8 +71,11 @@ class Kamakiri(metaclass=LogBase):
def kamakiri2(self, addr):
self.udev = self.mtk.port.cdc.device
try:
self.udev.ctrl_transfer(0x21, 0x20, 0, 0, self.linecode + array.array('B', pack("<I", addr)))
self.udev.ctrl_transfer(0x80, 0x6, 0x0200, 0, 9)
except:
pass
def da_read_write(self, address, length, data=None, check_result=True):
self.udev = self.mtk.port.cdc.device
@ -214,6 +217,7 @@ class Kamakiri(metaclass=LogBase):
return True, address
except RuntimeError:
try:
self.info("Bruteforce, testing " + hex(address) + "...")
self.mtk.preloader.read32(addr)
except:
return False, address + 4

View file

@ -185,7 +185,6 @@ class legacyext(metaclass=LogBase):
def generate_keys(self):
hwc = self.cryptosetup()
meid = b""
retval = {}
retval["hwcode"] = hex(self.config.hwcode)
meid = self.config.get_meid()
@ -194,8 +193,7 @@ class legacyext(metaclass=LogBase):
self.info("MEID : " + hexlify(meid).decode('utf-8'))
else:
try:
if self.config.chipconfig.meid_addr is not None:
meid = b"".join([pack("<I", val) for val in self.readmem(self.config.chipconfig.meid_addr, 4)])
meid = b"".join([pack("<I", val) for val in self.readmem(0x1008ec, 4)])
self.config.set_meid(meid)
self.info("MEID : " + hexlify(meid).decode('utf-8'))
retval["meid"] = hexlify(meid).decode('utf-8')
@ -206,8 +204,7 @@ class legacyext(metaclass=LogBase):
retval["socid"] = socid
else:
try:
if self.config.chipconfig.socid_addr is not None:
socid = b"".join([pack("<I",val) for val in self.readmem(self.config.chipconfig.socid_addr,8)])
socid = b"".join([pack("<I", val) for val in self.readmem(0x100934, 8)])
self.config.set_socid(socid)
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
retval["socid"] = hexlify(socid).decode('utf-8')

View file

@ -7,7 +7,7 @@ from binascii import hexlify
from mtkclient.Library.utils import LogBase, logsetup, getint
from mtkclient.config.payloads import pathconfig
from mtkclient.Library.error import ErrorHandler
from mtkclient.Library.utils import progress
class DA_handler(metaclass=LogBase):
def __init__(self, mtk, loglevel=logging.INFO):
@ -89,6 +89,8 @@ class DA_handler(metaclass=LogBase):
preloader = self.dump_preloader_ram()
else:
self.info("Device is unprotected.")
#if not mtk.config.is_brom:
# self.mtk.preloader.reset_to_brom()
if mtk.config.is_brom:
self.info("Device is in BROM-Mode. Bypassing security.")
mtk = mtk.bypass_security() # Needed for dumping preloader
@ -109,8 +111,6 @@ class DA_handler(metaclass=LogBase):
mtk.daloader.writestate()
return mtk
def da_gpt(self, directory:str):
if directory is None:
directory = ""
@ -234,13 +234,13 @@ class DA_handler(metaclass=LogBase):
def da_rf(self, filename, parttype):
if self.mtk.daloader.daconfig.flashtype == "ufs":
if parttype == "lu0":
length = self.mtk.daloader.daconfig.flashsize[0]
length = self.mtk.daloader.daconfig.flashsize
elif parttype == "lu1":
length = self.mtk.daloader.daconfig.flashsize[1]
length = self.mtk.daloader.daconfig.flashsize
elif parttype == "lu2":
length = self.mtk.daloader.daconfig.flashsize[2]
length = self.mtk.daloader.daconfig.flashsize
else:
length = self.mtk.daloader.daconfig.flashsize[0]
length = self.mtk.daloader.daconfig.flashsize
else:
length = self.mtk.daloader.daconfig.flashsize
print(f"Dumping sector 0 with flash size {hex(length)} as {filename}.")
@ -494,14 +494,34 @@ class DA_handler(metaclass=LogBase):
f"sector count {str(size // 0x200)}.")
def da_peek(self, addr: int, length: int, filename: str):
data = self.mtk.daloader.peek(addr=addr, length=length)
if data != b"":
bytestoread = length
pos = 0
pagesize = 0x200
if self.mtk.daloader.xflash:
pagesize = 1*1024*1024
pg = progress(pagesize)
bytesread=0
wf = None
if filename is not None:
open(filename, "wb").write(data)
wf = open(filename, "wb")
retval = bytearray()
while bytestoread > 0:
msize = min(bytestoread,pagesize)
data = self.mtk.daloader.peek(addr=addr+pos, length=msize)
if wf is not None:
wf.write(data)
else:
retval.extend(data)
pg.show_progress("Dump:",bytesread//pagesize,length//pagesize)
pos+=len(data)
bytesread+=len(data)
bytestoread-=len(data)
if filename is not None:
wf.close()
self.info(f"Successfully wrote data from {hex(addr)}, length {hex(length)} to {filename}")
else:
self.info(
f"Data read from {hex(addr)}, length: {hex(length)}:\n{hexlify(data).decode('utf-8')}\n")
f"Data read from {hex(addr)}, length: {hex(length)}:\n{hexlify(retval).decode('utf-8')}\n")
def da_poke(self, addr: int, data: str, filename: str):
if filename is not None:

View file

@ -865,7 +865,7 @@ class DALegacy(metaclass=LogBase):
skipdl = 0
self.usbwrite(pack(">I", skipdl))
elif hwcode == 0x6582:
newcombo = 0
newcombo = 1
self.usbwrite(pack(">I", newcombo))
time.sleep(0.350)
buffer = self.usbread(toread)
@ -1049,6 +1049,9 @@ class DALegacy(metaclass=LogBase):
self.daconfig.flashsize = self.sdc.m_sdmmc_ua_size
elif self.daconfig.flashtype == "nor":
self.daconfig.flashsize = self.nor.m_nor_flash_size
self.info("Connected to preloader")
speed = self.check_usb_cmd()
if speed[0] == 0: # 1 = USB High Speed, 2= USB Ultra high speed
self.info("Reconnecting to preloader")
self.set_usb_cmd()
self.mtk.port.close(reset=False)
@ -1056,7 +1059,6 @@ class DALegacy(metaclass=LogBase):
while not self.mtk.port.cdc.connect():
time.sleep(0.5)
self.info("Connected to preloader")
self.check_usb_cmd()
return True
return False
@ -1112,14 +1114,13 @@ class DALegacy(metaclass=LogBase):
if self.usbwrite(self.Cmd.USB_CHECK_STATUS): # 72
res = self.usbread(1)
if res == self.Rsp.ACK:
res = self.usbread(1)
if len(res) > 0:
return True
return False
speed = self.usbread(1)
return speed
return None
def set_usb_cmd(self):
if self.usbwrite(self.Cmd.USB_SETUP_PORT): # 72
if self.usbwrite(b"\x01"):
if self.usbwrite(b"\x01"): # USB_HIGH_SPEED
res = self.usbread(1)
if len(res) > 0:
if res[0] is self.Rsp.ACK[0]:

View file

@ -9,6 +9,15 @@ from struct import unpack, pack
from binascii import hexlify
from mtkclient.Library.utils import LogBase, logsetup
from mtkclient.Library.error import ErrorHandler
import time
USBDL_BIT_EN = 0x00000001 # 1: download bit enabled
USBDL_BROM = 0x00000002 # 0: usbdl by brom; 1: usbdl by bootloader
USBDL_TIMEOUT_MASK = 0x0000FFFC # 14-bit timeout: 0x0000~0x3FFE: second; 0x3FFFF: no timeout
USBDL_TIMEOUT_MAX = (USBDL_TIMEOUT_MASK >> 2) # maximum timeout indicates no timeout
USBDL_MAGIC = 0x444C0000 # Brom will check this magic number
MISC_LOCK_KEY_MAGIC = 0xAD98
def calc_xflash_checksum(data):
checksum = 0
@ -259,6 +268,33 @@ class Preloader(metaclass=LogBase):
value += b"\x00"
self.write32(addr + i, unpack("<I", value))
def reset_to_brom(self, en=True, timeout=0):
usbdlreg = 0
# if anything is wrong and caused wdt reset, enter bootrom download mode #
timeout = USBDL_TIMEOUT_MAX if timeout == 0 else timeout // 1000
timeout <<= 2
timeout &= USBDL_TIMEOUT_MASK # usbdl timeout cannot exceed max value
usbdlreg |= timeout
if en:
usbdlreg |= USBDL_BIT_EN
else:
usbdlreg &= ~USBDL_BIT_EN
usbdlreg &= ~USBDL_BROM
# Add magic number for MT6582
usbdlreg |= USBDL_MAGIC # | 0x444C0000
# set BOOT_MISC0 as watchdog resettable
RST_CON = self.config.chipconfig.misc_lock + 8
USBDL_FLAG = self.config.chipconfig.misc_lock - 0x20
self.write32(self.config.chipconfig.misc_lock, MISC_LOCK_KEY_MAGIC)
self.write32(RST_CON, 1)
self.write32(self.config.chipconfig.misc_lock, 0)
self.write32(USBDL_FLAG, usbdlreg)
return
def run_ext_cmd(self, cmd: bytes = b"\xB1"):
self.usbwrite(self.Cmd.CMD_C8.value)
assert self.usbread(1) == self.Cmd.CMD_C8.value
@ -502,7 +538,7 @@ class Preloader(metaclass=LogBase):
mode = 0
else:
mode = 1
self.mtk.port.echo(self.Cmd.brom_register_access.value)
if self.mtk.port.echo(self.Cmd.brom_register_access.value):
self.mtk.port.echo(pack(">I", mode))
self.mtk.port.echo(pack(">I", address))
self.mtk.port.echo(pack(">I", length))

View file

@ -291,7 +291,7 @@ class usb_class(metaclass=LogBase):
for itf in self.configuration:
if self.devclass == -1:
self.devclass = 2
if itf.bInterfaceClass == self.devclass:
if itf.bInterfaceClass in [self.devclass,0xFF]:
if self.interface == -1 or self.interface == itf.bInterfaceNumber:
self.interface = itf
self.EP_OUT = EP_OUT
@ -394,7 +394,7 @@ class usb_class(metaclass=LogBase):
self.verify_data(bytearray(command), "TX:")
return True
def usbread(self, resplen):
def usbread(self, resplen, maxtimeout=10):
if resplen <= 0:
self.info("Warning !")
res = bytearray()
@ -403,6 +403,7 @@ class usb_class(metaclass=LogBase):
epr = self.EP_IN.read
wMaxPacketSize = self.EP_IN.wMaxPacketSize
extend = res.extend
while len(res) < resplen:
try:
extend(epr(resplen))
@ -410,7 +411,7 @@ class usb_class(metaclass=LogBase):
error = str(e.strerror)
if "timed out" in error:
self.debug("Timed out")
if timeout == 10:
if timeout == maxtimeout:
return b""
timeout += 1
pass

View file

@ -346,7 +346,7 @@ class xflashext(metaclass=LogBase):
def custom_rpmb_init(self):
hwc = self.cryptosetup()
if self.config.chipconfig.meid_addr:
meid = self.custom_read(self.config.chipconfig.meid_addr, 16)
meid = self.custom_read(0x1008ec, 16)
if meid != b"":
self.config.set_meid(meid)
self.info("Generating sej rpmbkey...")
@ -542,8 +542,7 @@ class xflashext(metaclass=LogBase):
self.info("MEID : " + hexlify(meid).decode('utf-8'))
else:
try:
if self.config.chipconfig.meid_addr is not None:
meid = b"".join([pack("<I", val) for val in self.readmem(self.config.chipconfig.meid_addr, 4)])
meid = b"".join([pack("<I", val) for val in self.readmem(0x1008ec, 4)])
self.config.set_meid(meid)
self.info("MEID : " + hexlify(meid).decode('utf-8'))
retval["meid"]=hexlify(meid).decode('utf-8')
@ -554,8 +553,7 @@ class xflashext(metaclass=LogBase):
retval["socid"] = hexlify(socid).decode('utf-8')
else:
try:
if self.config.chipconfig.socid_addr is not None:
socid = b"".join([pack("<I", val) for val in self.readmem(self.config.chipconfig.socid_addr, 8)])
socid = b"".join([pack("<I", val) for val in self.readmem(0x100934, 8)])
self.config.set_socid(socid)
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
retval["socid"] = hexlify(socid).decode('utf-8')
@ -608,8 +606,7 @@ class xflashext(metaclass=LogBase):
val=json.loads(open("tee.json","r").read())
self.decrypt_tee(val["filename"],bytes.fromhex(val["data"]),bytes.fromhex(val["data2"]))
if meid == b"":
if self.config.chipconfig.meid_addr:
meid = self.custom_read(self.config.chipconfig.meid_addr, 16)
meid = self.custom_read(0x1008ec, 16)
if meid != b"":
self.config.set_meid(meid)
self.info("Generating sej rpmbkey...")

View file

@ -9,7 +9,7 @@ class chipconfig:
gcpu_base=None, ap_dma_mem=None, name="", description="", dacode=None,
meid_addr=None, socid_addr=None, blacklist=(), blacklist_count=None,
send_ptr=None, ctrl_buffer=(), cmd_handler=None, brom_register_access=None,
damode=damodes.DEFAULT, loader=None, prov_addr=None):
damode=damodes.DEFAULT, loader=None, prov_addr=None, misc_lock=None):
self.var1 = var1
self.watchdog = watchdog
self.uart = uart
@ -36,6 +36,7 @@ class chipconfig:
self.dacode = dacode
self.damode = damode
self.loader = loader
self.misc_lock = misc_lock
# Credits to cyrozap and Chaosmaster for some values
"""
@ -261,6 +262,7 @@ hwconfig = {
# cqdma_base
# ap_dma_mem
# blacklist
misc_lock=0x1000141C,
damode=damodes.DEFAULT, #
dacode=0x6571,
name="MT6571"),
@ -283,6 +285,7 @@ hwconfig = {
cmd_handler=0x40C5AF,
brom_register_access=(0x40bd48, 0x40befc),
meid_addr=0x11142C34,
misc_lock=0x1000141C,
damode=damodes.DEFAULT, #
dacode=0x6572,
name="MT6572",
@ -346,6 +349,7 @@ hwconfig = {
ctrl_buffer=0x00103060,
cmd_handler=0x0000C113,
brom_register_access=(0xb8e0, 0xba94),
misc_lock=0x10001838,
meid_addr=0x1030B4,
damode=damodes.DEFAULT,
dacode=0x6580,
@ -370,6 +374,7 @@ hwconfig = {
cmd_handler=0x0000B2E7,
brom_register_access=(0xa8d0, 0xaa84),
meid_addr=0x1030CC,
misc_lock=0x10002050,
damode=damodes.DEFAULT, #
dacode=0x6582,
name="MT6582/MT6574",
@ -386,6 +391,7 @@ hwconfig = {
# blacklist
cqdma_base=0x10212000, # This chip might not support cqdma
ap_dma_mem=0x11000000 + 0x320, # AP_DMA_I2C_0_RX_MEM_ADDR
misc_lock=0x10002050,
damode=damodes.DEFAULT,
dacode=0x6589,
name="MT6583/6589"),
@ -408,6 +414,7 @@ hwconfig = {
cmd_handler=0x0000B09F,
brom_register_access=(0xa838, 0xa9ec),
meid_addr=0x1030A8,
misc_lock=0x10002050,
dacode=0x6592,
damode=damodes.DEFAULT, #
name="MT6592",
@ -453,6 +460,7 @@ hwconfig = {
cmd_handler=0x0000A17F,
brom_register_access=(0x98cc, 0x9a94),
meid_addr=0x1030B0,
misc_lock=0x10001838,
damode=damodes.DEFAULT, #
dacode=0x6735,
name="MT6735/T",
@ -502,6 +510,7 @@ hwconfig = {
meid_addr=0x102AF8,
socid_addr=0x102b08,
prov_addr=0x10720C,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6739,
name="MT6739/MT6731",
@ -518,6 +527,7 @@ hwconfig = {
cqdma_base=0x10212C00,
ap_dma_mem=0x11000000 + 0x1A0, # AP_DMA_I2C_1_RX_MEM_ADDR
# blacklist
misc_lock=0x10001838,
damode=damodes.XFLASH,
dacode=0x6755,
name="MT6750"),
@ -557,6 +567,7 @@ hwconfig = {
meid_addr=0x1030B0,
damode=damodes.DEFAULT, #
dacode=0x6735,
misc_lock=0x10001838,
name="MT6753",
loader="mt6753_payload.bin"),
0x326: chipconfig(
@ -602,6 +613,7 @@ hwconfig = {
cmd_handler=0x0000A8FB,
brom_register_access=(0xa030, 0xa0e8),
meid_addr=0x1030B4,
misc_lock=0x10001838,
damode=damodes.XFLASH,
dacode=0x6757,
name="MT6757/MT6757D",
@ -679,6 +691,7 @@ hwconfig = {
meid_addr=0x102AF8,
socid_addr=0x102b08,
prov_addr=0x1054F4,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6761,
name="MT6761/MT6762/MT3369/MT8766B",
@ -705,6 +718,7 @@ hwconfig = {
meid_addr=0x102B78,
socid_addr=0x102b88,
prov_addr=0x106804,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6763,
name="MT6763",
@ -731,6 +745,7 @@ hwconfig = {
meid_addr=0x102AF8,
socid_addr=0x102b08,
prov_addr=0x1054F4,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6765,
name="MT6765/MT8768t",
@ -757,6 +772,7 @@ hwconfig = {
meid_addr=0x102AF8,
socid_addr=0x102b08,
prov_addr=0x1054F4,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6768,
name="MT6768",
@ -783,6 +799,7 @@ hwconfig = {
meid_addr=0x102B38,
socid_addr=0x102B48,
prov_addr=0x1065C0,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6771,
name="MT6771/MT8385/MT8183/MT8666",
@ -819,6 +836,7 @@ hwconfig = {
meid_addr=0x102B38,
socid_addr=0x102B48,
prov_addr=0x1065C0,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6779,
name="MT6779",
@ -870,6 +888,7 @@ hwconfig = {
meid_addr=0x102B38,
socid_addr=0x102B48,
prov_addr=0x1065C0,
misc_lock=0x1001a100,
damode=damodes.XFLASH,
dacode=0x6785,
name="MT6785",
@ -918,6 +937,7 @@ hwconfig = {
cmd_handler=0x0000AA3F,
brom_register_access=(0xa18c, 0xa354),
meid_addr=0x1030AC,
misc_lock=0x10002050,
damode=damodes.XFLASH,
dacode=0x6797,
name="MT6797/MT6767",
@ -994,6 +1014,7 @@ hwconfig = {
meid_addr=0x102b78,
socid_addr=0x102b88,
prov_addr=0x1066C0,
misc_lock=0x1001A100,
damode=damodes.XFLASH,
dacode=0x6853,
name="MT6853",
@ -1020,6 +1041,7 @@ hwconfig = {
meid_addr=0x102B78,
socid_addr=0x102B88,
prov_addr=0x1066C0,
misc_lock=0x1001A100,
damode=damodes.XFLASH,
dacode=0x6873,
name="MT6873",
@ -1073,6 +1095,7 @@ hwconfig = {
meid_addr=0x102B78,
socid_addr=0x102B88,
prov_addr=0x1066C0,
misc_lock=0x1001A100,
damode=damodes.XFLASH,
dacode=0x6885,
name="MT6885/MT6883/MT6889/MT6880/MT6890",
@ -1136,6 +1159,7 @@ hwconfig = {
cmd_handler=0x0000BDF3,
brom_register_access=(0xb58c, 0xb740),
meid_addr=0x1031CC,
misc_lock=0x10002050,
damode=damodes.DEFAULT, #
dacode=0x8127,
name="MT8127/MT3367",
@ -1183,6 +1207,7 @@ hwconfig = {
cmd_handler=0x0000CCB3,
brom_register_access=(0xc400, 0xc5c8),
meid_addr=0x1031C0,
misc_lock=0x10002050,
damode=damodes.DEFAULT, #
dacode=0x8163,
name="MT8163",
@ -1254,6 +1279,7 @@ hwconfig = {
cmd_handler=0x0000AC6B,
brom_register_access=(0xa3b8, 0xa580),
meid_addr=0x1230B0,
misc_lock=0x1202050,
damode=damodes.DEFAULT, #
dacode=0x8173,
name="MT8173",
@ -1304,6 +1330,7 @@ hwconfig = {
# brom_register_access
# meid_addr
# socid_addr
misc_lock=0x1001A100,
dacode=0x8195,
damode=damodes.XFLASH,
# description

View file

@ -74,6 +74,8 @@ class Mtk_Config(metaclass=LogBase):
def get_meid(self):
if self.meid is None and self.hwparam is not None:
self.meid = self.hwparam.loadsetting("meid")
elif self.meid is not None:
self.hwparam.writesetting("meid",hexlify(self.meid).decode('utf-8'))
return self.meid
def set_socid(self,socid):
@ -183,6 +185,11 @@ class Mtk_Config(metaclass=LogBase):
bmtflag = 1
bmtblockcount = 0xA8
bmtpartsize = 0x1500000
elif hwcode in [0x6582]:
if self.da.daconfig.flashtype == "emmc":
bmtflag = 2
bmtblockcount = 0xA8
bmtpartsize = 0x1500000
elif hwcode in [0x6572]:
if self.da.daconfig.flashtype == "nand":
bmtflag = 0