Merge pull request #993 from ColdWindScholar/main

Fix "OSError: Unable to find libfuse" on Windows and Optimized the code and fixed other bugs
This commit is contained in:
Bjoern Kerler 2024-05-12 11:26:46 +02:00 committed by GitHub
commit 491f930424
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 582 additions and 687 deletions

18
mtk
View file

@ -40,16 +40,6 @@ cmds = {
"script": "Run multiple commands using text script"
}
def showcommands():
print(info)
print("-----------------------------------\n")
print("Available commands are:\n")
for cmd in cmds:
print("%20s" % (cmd) + ":\t" + cmds[cmd])
print()
if __name__ == '__main__':
print(info)
print("")
@ -620,12 +610,12 @@ if __name__ == '__main__':
parser_ess.add_argument('--da_addr', help='Set a specific da payload addr')
parser_ess.add_argument('--brom_addr', help='Set a specific brom payload addr')
parser_ess.add_argument('--ptype',
help='Set the payload type ( "amonet","kamakiri","kamakiri2","carbonara" kamakiri2/da used by default)')
help='Set the payload type ( "amonet","kamakiri","kamakiri2","carbonara" kamakiri2/da used by default)')
parser_ess.add_argument('--preloader', help='Set the preloader filename for dram config')
parser_ess.add_argument('--verifystage2', help='Verify if stage2 data has been written correctly')
parser_ess.add_argument('--parttype', help='Partition type\n' +
'\t\tEMMC: [user, boot1, boot2, gp1, gp2, gp3, gp4, rpmb]' +
'\t\tUFS: [lu0, lu1, lu2, lu0_lu1]')
'\t\tEMMC: [user, boot1, boot2, gp1, gp2, gp3, gp4, rpmb]' +
'\t\tUFS: [lu0, lu1, lu2, lu0_lu1]')
parser_ess.add_argument('--filename', help='Optional filename')
parser_ess.add_argument('--crash', help='Enforce crash if device is in pl mode to enter brom mode')
parser_ess.add_argument('--socid', help='Read Soc ID')
@ -947,7 +937,7 @@ if __name__ == '__main__':
args = parser.parse_args()
cmd = args.cmd
if cmd not in cmds:
showcommands()
parser.print_help()
exit(0)
mtk = Main(args).run(parser)

View file

@ -8,7 +8,7 @@ block_cipher = None
a = Analysis(['mtk'],
pathex=[],
binaries=[],
datas=[('mtkclient/Windows/*', '.'), ('mtkclient/payloads', 'mtkclient/payloads'), ('mtkclient/Loader', 'mtkclient/Loader')],
datas=[('mtkclient/Windows/*', '.'), ('mtkclient/payloads', 'mtkclient/payloads'), ('mtkclient/Loader', 'mtkclient/Loader'), ('mtkclient/Library/Filesystem/bin', 'mtkclient/Library/Filesystem/bin')],
hiddenimports=[],
hookspath=[],
hooksconfig={},

111
mtk_gui
View file

@ -105,7 +105,7 @@ def load_translations(application):
locale = QLocale.system()
translator = QTranslator(application)
directory = os.path.dirname(__file__)
lang = 'mtkclient/gui/i18n/' + locale.name()
lang = f'mtkclient/gui/i18n/{locale.name()}'
if locale.name() == "en_NL":
lang = lang.replace("en_NL", "nl_NL")
# lang = 'mtkclient/gui/i18n/fr_FR'
@ -154,10 +154,7 @@ class MainWindow(QMainWindow):
global lock
lock.acquire()
doneBytes = 0
if "currentPartitionSizeDone" in self.Status:
curpartBytes = self.Status["currentPartitionSizeDone"]
else:
curpartBytes = self.Status["currentPartitionSize"]
curpartBytes = self.Status[f"currentPartitionSize{'Done' if 'currentPartitionSizeDone' in self.Status else ''}"]
if "allPartitions" in self.Status:
for partition in self.Status["allPartitions"]:
@ -168,11 +165,7 @@ class MainWindow(QMainWindow):
fullPercentageDone = int((doneBytes / totalBytes) * 100)
self.ui.fullProgress.setValue(fullPercentageDone)
timeinfototal = self.timeEstTotal.update(fullPercentageDone, 100)
self.ui.fullProgressText.setText("<table width='100%'><tr><td><b>Total:</b> " +
convert_size(doneBytes) + " / " + convert_size(totalBytes) +
"</td><td align='right'>" + timeinfototal +
QCoreApplication.translate("main", " left") +
"</td></tr></table>")
self.ui.fullProgressText.setText(f"<table width='100%'><tr><td><b>Total:</b> {convert_size(doneBytes)} / {convert_size(totalBytes)}</td><td align='right'>{timeinfototal}{QCoreApplication.translate('main', ' left')}</td></tr></table>")
else:
partBytes = self.Status["currentPartitionSize"]
doneBytes = self.Status["currentPartitionSizeDone"]
@ -244,21 +237,21 @@ class MainWindow(QMainWindow):
self.readflash.disableButtonsSignal.connect(self.disablebuttons)
self.ui.readpartitionsbtn.clicked.connect(self.readflash.dumpPartition)
self.ui.readselectallcheckbox.clicked.connect(self.readflash.selectAll)
self.ui.readpreloaderbtn.clicked.connect(self.on_readpreloader)
self.ui.readflashbtn.clicked.connect(self.on_readfullflash)
self.ui.readrpmbbtn.clicked.connect(self.on_readrpmb)
self.ui.readboot2btn.clicked.connect(self.on_readboot2)
self.ui.readpreloaderbtn.clicked.connect(lambda: self.readflash.dumpFlash("boot1"))
self.ui.readflashbtn.clicked.connect(lambda: self.readflash.dumpFlash("user"))
self.ui.readrpmbbtn.clicked.connect(lambda: self.readflash.dumpFlash("rpmb"))
self.ui.readboot2btn.clicked.connect(lambda: self.readflash.dumpFlash("boot2"))
def initkeys(self):
self.genkeys = generateKeysMenu(self.ui, self, self.devhandler.da_handler, self.sendToLog)
self.ui.generatekeybtn.clicked.connect(self.on_generatekeys)
self.ui.generatekeybtn.clicked.connect(self.genkeys.generateKeys)
self.genkeys.enableButtonsSignal.connect(self.enablebuttons)
self.genkeys.disableButtonsSignal.connect(self.disablebuttons)
def initunlock(self):
self.unlock = UnlockMenu(self.ui, self, self.devhandler.da_handler, self.sendToLog)
self.ui.unlockbutton.clicked.connect(self.on_unlock)
self.ui.lockbutton.clicked.connect(self.on_lock)
self.ui.unlockbutton.clicked.connect(lambda: self.unlock.unlock("unlock"))
self.ui.lockbutton.clicked.connect(lambda: self.unlock.unlock("lock"))
self.unlock.enableButtonsSignal.connect(self.enablebuttons)
self.unlock.disableButtonsSignal.connect(self.disablebuttons)
@ -267,21 +260,21 @@ class MainWindow(QMainWindow):
self.eraseflash.enableButtonsSignal.connect(self.enablebuttons)
self.eraseflash.disableButtonsSignal.connect(self.disablebuttons)
self.ui.eraseselectallpartitionscheckbox.clicked.connect(self.eraseflash.selectAll)
self.ui.erasepartitionsbtn.clicked.connect(self.on_erasepartflash)
self.ui.eraserpmbbtn.clicked.connect(self.on_eraserpmb)
self.ui.erasepreloaderbtn.clicked.connect(self.on_erasepreloader)
self.ui.eraseboot2btn.clicked.connect(self.on_eraseboot2)
self.ui.erasepartitionsbtn.clicked.connect(self.eraseflash.erasePartition)
self.ui.eraserpmbbtn.clicked.connect(lambda: self.eraseflash.eraseFlash("rpmb"))
self.ui.erasepreloaderbtn.clicked.connect(lambda: self.eraseflash.eraseFlash("boot1"))
self.ui.eraseboot2btn.clicked.connect(lambda: self.eraseflash.eraseFlash("boot2"))
def initwrite(self):
self.writeflash = WriteFlashWindow(self.ui, self, self.devhandler.da_handler, self.sendToLog)
self.writeflash.enableButtonsSignal.connect(self.enablebuttons)
self.writeflash.disableButtonsSignal.connect(self.disablebuttons)
self.ui.writeselectfromdir.clicked.connect(self.writeflash.selectFiles)
self.ui.writeflashbtn.clicked.connect(self.on_writefullflash)
self.ui.writepartbtn.clicked.connect(self.on_writepartflash)
self.ui.writeboot2btn.clicked.connect(self.on_writeboot2)
self.ui.writepreloaderbtn.clicked.connect(self.on_writepreloader)
self.ui.writerpmbbtn.clicked.connect(self.on_writerpmb)
self.ui.writeflashbtn.clicked.connect(lambda: self.writeflash.writeFlash("user"))
self.ui.writepartbtn.clicked.connect(self.writeflash.writePartition)
self.ui.writeboot2btn.clicked.connect(lambda: self.writeflash.writeFlash("boot2"))
self.ui.writepreloaderbtn.clicked.connect(lambda: self.writeflash.writeFlash("boot1"))
self.ui.writerpmbbtn.clicked.connect(lambda: self.writeflash.writeFlash("rpmb"))
@Slot(str)
def update_status_text(self, text):
@ -338,12 +331,7 @@ class MainWindow(QMainWindow):
def getpartitions(self):
data, guid_gpt = self.devhandler.da_handler.mtk.daloader.get_gpt()
if guid_gpt is None:
print("Error reading gpt")
self.ui.readtitle.setText(QCoreApplication.translate("main", "Error reading gpt"))
else:
self.ui.readtitle.setText(QCoreApplication.translate("main", "Select partitions to dump"))
self.ui.readtitle.setText(QCoreApplication.translate("main", "Error reading gpt" if guid_gpt is None else "Select partitions to dump"))
readpartitionListWidgetVBox = QVBoxLayout()
readpartitionListWidget = QWidget(self)
readpartitionListWidget.setLayout(readpartitionListWidgetVBox)
@ -421,65 +409,8 @@ class MainWindow(QMainWindow):
lineedit.setDisabled(False)
return fname
def on_writefullflash(self):
self.writeflash.writeFlash("user")
return
def on_writepreloader(self):
self.writeflash.writeFlash("boot1")
return
def on_writeboot2(self):
self.writeflash.writeFlash("boot2")
return
def on_writerpmb(self):
self.writeflash.writeFlash("rpmb")
return
def on_writepartflash(self):
self.writeflash.writePartition()
return
def on_erasepartflash(self):
self.eraseflash.erasePartition()
return
def on_eraseboot2(self):
self.eraseflash.eraseBoot2()
def on_erasepreloader(self):
self.eraseflash.erasePreloader()
def on_eraserpmb(self):
self.eraseflash.eraseRpmb()
def on_generatekeys(self):
self.genkeys.generateKeys()
def on_unlock(self):
self.unlock.unlock("unlock")
def on_lock(self):
self.unlock.unlock("lock")
def on_readpreloader(self):
self.readflash.dumpFlash("boot1")
def on_readboot2(self):
self.readflash.dumpFlash("boot2")
return
def on_readfullflash(self):
self.readflash.dumpFlash("user")
def on_readrpmb(self):
self.readflash.dumpFlash("rpmb")
return
def sendToLog(self, info):
t = time.localtime()
self.ui.logBox.appendPlainText(time.strftime("[%H:%M:%S", t) + "]: " + info)
self.ui.logBox.appendPlainText(time.strftime("[%H:%M:%S", time.localtime()) + "]: " + info)
self.ui.logBox.verticalScrollBar().setValue(self.ui.logBox.verticalScrollBar().maximum())
def sendToProgress(self, progress):

View file

@ -8,7 +8,7 @@ block_cipher = None
a = Analysis(['mtk_gui'],
pathex=[],
binaries=[],
datas=[('mtkclient/gui/images', 'mtkclient/gui/images'), ('mtkclient/Windows/*', '.'), ('mtkclient/payloads', 'mtkclient/payloads'), ('mtkclient/Loader', 'mtkclient/Loader')],
datas=[('mtkclient/gui/images', 'mtkclient/gui/images'), ('mtkclient/Windows/*', '.'), ('mtkclient/payloads', 'mtkclient/payloads'), ('mtkclient/Loader', 'mtkclient/Loader'), ('mtkclient/Library/Filesystem/bin', 'mtkclient/Library/Filesystem/bin')],
hiddenimports=[],
hookspath=[],
hooksconfig={},

View file

@ -88,7 +88,7 @@ class serial_class(DeviceClass):
for usbid in self.portconfig:
if port.pid == usbid[1] and port.vid == usbid[0]:
# portid = port.location[-1:]
print(f"Detected {hex(port.vid)}:{hex(port.pid)} device at: " + port.device)
print(f"Detected {hex(port.vid)}:{hex(port.pid)} device at: {port.device}")
ids.append(port.device)
return sorted(ids)

View file

@ -95,7 +95,8 @@ class CDC_CMDS:
class usb_class(DeviceClass):
def load_windows_dll(self):
@staticmethod
def load_windows_dll():
if os.name == 'nt':
windows_dir = None
try:
@ -142,10 +143,7 @@ class usb_class(DeviceClass):
self.backend = None
def set_fast_mode(self, enabled):
if enabled:
self.fast = True
else:
self.fast = False
self.fast = bool(enabled)
def verify_data(self, data, pre="RX:"):
if self.__logger.level == logging.DEBUG:
@ -207,7 +205,7 @@ class usb_class(DeviceClass):
if stopbits is not None:
if stopbits not in sbits.keys():
valid = ", ".join(str(k) for k in sorted(sbits.keys()))
raise ValueError("Valid stopbits are " + valid)
raise ValueError(f"Valid stopbits are {valid}")
self.stopbits = stopbits
else:
self.stopbits = 0
@ -215,7 +213,7 @@ class usb_class(DeviceClass):
if databits is not None:
if databits not in dbits:
valid = ", ".join(str(d) for d in sorted(dbits))
raise ValueError("Valid databits are " + valid)
raise ValueError(f"Valid databits are {valid}")
self.databits = databits
else:
self.databits = 0
@ -223,7 +221,7 @@ class usb_class(DeviceClass):
if parity is not None:
if parity not in pmodes:
valid = ", ".join(str(pm) for pm in sorted(pmodes))
raise ValueError("Valid parity modes are " + valid)
raise ValueError(f"Valid parity modes are {valid}")
self.parity = parity
else:
self.parity = 0
@ -234,7 +232,7 @@ class usb_class(DeviceClass):
dif = [abs(br - baudrate) for br in brs]
best = brs[dif.index(min(dif))]
raise ValueError(
"Invalid baudrates, nearest valid is {}".format(best))
f"Invalid baudrates, nearest valid is {best}")
self.baudrate = baudrate
linecode = [
@ -254,7 +252,7 @@ class usb_class(DeviceClass):
wlen = self.device.ctrl_transfer(
req_type, CDC_CMDS.SET_LINE_CODING,
data_or_wLength=data, wIndex=1)
self.debug("Linecoding set, {}b sent".format(wlen))
self.debug(f"Linecoding set, {wlen}b sent")
def setbreak(self):
txdir = 0 # 0:OUT, 1:IN
@ -264,7 +262,7 @@ class usb_class(DeviceClass):
wlen = self.device.ctrl_transfer(
bmRequestType=req_type, bRequest=CDC_CMDS.SEND_BREAK,
wValue=0, data_or_wLength=0, wIndex=1)
self.debug("Break set, {}b sent".format(wlen))
self.debug(f"Break set, {wlen}b sent")
def setcontrollinestate(self, RTS=None, DTR=None, isFTDI=False):
cmds = CDC_CMDS()
@ -284,7 +282,7 @@ class usb_class(DeviceClass):
wValue=ctrlstate,
wIndex=1,
data_or_wLength=0)
self.debug("Linecoding set, {}b sent".format(wlen))
self.debug(f"Linecoding set, {wlen}b sent")
def flush(self):
return
@ -348,7 +346,7 @@ class usb_class(DeviceClass):
self.debug("Detaching kernel driver")
self.device.detach_kernel_driver(0)
except Exception as err:
self.debug("No kernel driver supported: " + str(err))
self.debug(f"No kernel driver supported: {str(err)}")
try:
usb.util.claim_interface(self.device, 0)
except Exception:
@ -360,7 +358,7 @@ class usb_class(DeviceClass):
self.debug("Detaching kernel driver")
self.device.detach_kernel_driver(self.interface)
except Exception as err:
self.debug("No kernel driver supported: " + str(err))
self.debug(f"No kernel driver supported: {str(err)}")
try:
if self.interface != 0:
usb.util.claim_interface(self.device, self.interface)
@ -720,7 +718,7 @@ class Scsi:
ret_tag += self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, datasize)
if datasize > 0:
data = self.usb.read(datasize, timeout)
print("DATA: " + hexlify(data).decode('utf-8'))
print(f"DATA: {hexlify(data).decode('utf-8')}")
print("Sent HTC adb enable command")
def send_htc_ums_adbenable(self): # HTC10
@ -758,7 +756,7 @@ class Scsi:
ret_tag += self.send_mass_storage_command(lun, common_cmnd2, USB_DIR_IN, datasize)
if datasize > 0:
data = self.usb.read(datasize, timeout)
print("DATA: " + hexlify(data).decode('utf-8'))
print(f"DATA: {hexlify(data).decode('utf-8')}")
print("Send HTC adb enable command")
def send_fih_adbenable(self): # motorola xt560, nokia 3.1, #f_mass_storage.c
@ -780,7 +778,7 @@ class Scsi:
# ret_tag+=self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
if datasize > 0:
data = self.usb.read(datasize, timeout)
print("DATA: " + hexlify(data).decode('utf-8'))
print(f"DATA: {hexlify(data).decode('utf-8')}")
print("Sent FIH adb enable command")
self.usb.close()
@ -795,7 +793,7 @@ class Scsi:
self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
if datasize > 0:
data = self.usb.read(datasize, timeout)
print("DATA: " + hexlify(data).decode('utf-8'))
print(f"DATA: {hexlify(data).decode('utf-8')}")
print("Sent alcatel adb enable command")
self.usb.close()
@ -814,7 +812,7 @@ class Scsi:
ret_tag += self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
if datasize > 0:
data = self.usb.read(datasize, timeout)
print("DATA: " + hexlify(data).decode('utf-8'))
print(f"DATA: {hexlify(data).decode('utf-8')}")
print("Sent FIH root command")
self.usb.close()

View file

@ -8,7 +8,7 @@ from mtkclient.Library.Connection.usblib import Scsi
def main():
info = 'MassStorageBackdoor (c) B.Kerler 2019.'
parser = argparse.ArgumentParser(description=info)
print("\n" + info + "\n\n")
print(f"\n{info}\n\n")
parser.add_argument('-vid', metavar="<vid>", help='[Option] Specify vid, default=0x2e04)', default="0x2e04")
parser.add_argument('-pid', metavar="<pid>", help='[Option] Specify pid, default=0xc025)', default="0xc025")
parser.add_argument('-interface', metavar="<pid>", help='[Option] Specify interface number)', default="")

View file

@ -160,9 +160,9 @@ class DAconfig(metaclass=LogBase):
self.parse_da_loader(loader, self.dasetup)
else:
if not os.path.exists(loader):
self.warning("Couldn't open " + loader)
self.warning(f"Couldn't open {loader}")
else:
self.info("Using custom loader: " + loader)
self.info(f"Using custom loader: {loader}")
self.parse_da_loader(loader, self.dasetup)
def m_extract_emi(self, data):
@ -203,7 +203,7 @@ class DAconfig(metaclass=LogBase):
with open(preloader, "rb") as rf:
data = rf.read()
else:
self.error("Preloader : " + preloader + " doesn't exist. Aborting.")
self.error(f"Preloader : {preloader} doesn't exist. Aborting.")
exit(1)
try:
self.emiver, self.emi = self.m_extract_emi(data)
@ -211,17 +211,14 @@ class DAconfig(metaclass=LogBase):
self.emiver = 0
self.emi = None
def parse_da_loader(self, loader:str, dasetup:dict):
def parse_da_loader(self, loader: str, dasetup: dict):
try:
with open(loader, 'rb') as bootldr:
# data = bootldr.read()
# self.debug(hexlify(data).decode('utf-8'))
hdr = bootldr.read(0x68)
count_da = unpack("<I", bootldr.read(4))[0]
if b"MTK_DA_v6" in hdr:
v6 = True
else:
v6 = False
v6 = b"MTK_DA_v6" in hdr
for i in range(0, count_da):
bootldr.seek(0x6C + (i * 0xDC))
da = DA(bootldr.read(0xDC))
@ -245,7 +242,7 @@ class DAconfig(metaclass=LogBase):
dasetup[da.hw_code].append(da)
return True
except Exception as e:
self.error("Couldn't open loader: " + loader + ". Reason: " + str(e))
self.error(f"Couldn't open loader: {loader}. Reason: {str(e)}")
return False
def setup(self):

View file

@ -303,7 +303,7 @@ class DALegacy(metaclass=LogBase):
pdram[0] = draminfo[:9]
draminfo = draminfo[:4][::-1] + draminfo[4:8][::-1] + draminfo[8:12][::-1] + draminfo[12:16][::-1]
pdram[1] = draminfo[:9]
self.info("DRAM config needed for : " + hexlify(draminfo).decode('utf-8'))
self.info(f"DRAM config needed for : {hexlify(draminfo).decode('utf-8')}")
if self.daconfig.emi is None:
found = False
for root, dirs, files in os.walk(os.path.join(self.pathconfig.get_loader_path(), 'Preloader')):
@ -312,7 +312,7 @@ class DALegacy(metaclass=LogBase):
data = rf.read()
if pdram[0] in data or pdram[1] in data:
preloader = os.path.join(root, file)
print("Detected preloader: " + preloader)
print(f"Detected preloader: {preloader}")
self.daconfig.extract_emi(preloader)
found = True
break
@ -347,25 +347,25 @@ class DALegacy(metaclass=LogBase):
dramlength = len(self.daconfig.emi)
if self.daconfig.emiver in [0xF, 0x10, 0x11, 0x14, 0x15]:
dramlength = unpack(">I", self.usbread(0x4))[0] # 0x000000BC
self.info("RAM-Length: " + hex(dramlength))
self.info(f"RAM-Length: {hex(dramlength)}")
self.usbwrite(self.Rsp.ACK)
lendram = len(self.daconfig.emi)
if hwcode != 0x8127:
self.usbwrite(pack(">I", lendram))
elif self.daconfig.emiver in [0x0B]:
info = self.usbread(0x10) # 0x000000BC
self.info("RAM-Info: " + hexlify(info).decode('utf-8'))
self.info(f"RAM-Info: {hexlify(info).decode('utf-8')}")
dramlength = unpack(">I", self.usbread(0x4))[0]
self.usbwrite(self.Rsp.ACK)
elif self.daconfig.emiver in [0x0C, 0x0D]:
dramlength = unpack(">I", self.usbread(0x4))[0]
self.info("RAM-Length: " + hex(dramlength))
self.info(f"RAM-Length: {hex(dramlength)}")
self.usbwrite(self.Rsp.ACK)
self.daconfig.emi = self.daconfig.emi[:dramlength]
self.daconfig.emi = pack(">I", 0x100) + self.daconfig.emi[0x4:dramlength]
elif self.daconfig.emiver in [0x00]:
dramlength = unpack(">I", self.usbread(0x4))[0] # 0x000000B0
self.info("RAM-Length: " + hex(dramlength))
self.info(f"RAM-Length: {hex(dramlength)}")
self.usbwrite(self.Rsp.ACK)
lendram = len(self.daconfig.emi)
self.daconfig.emi = self.daconfig.emi[:dramlength]
@ -582,7 +582,7 @@ class DALegacy(metaclass=LogBase):
self.info("Reading nand info")
nandinfo = unpack(">I", self.usbread(4))[0]
self.debug("NAND_INFO: " + hex(nandinfo))
self.debug(f"NAND_INFO: {hex(nandinfo)}")
ids = unpack(">H", self.usbread(2))[0]
nandids = []
for i in range(0, ids):
@ -590,7 +590,7 @@ class DALegacy(metaclass=LogBase):
nandids.append(tmp)
self.info("Reading emmc info")
emmcinfolegacy = unpack(">I", self.usbread(4))[0]
self.debug("EMMC_INFO: " + hex(emmcinfolegacy))
self.debug(f"EMMC_INFO: {hex(emmcinfolegacy)}")
emmcids = []
for i in range(0, 4):
tmp = unpack(">I", self.usbread(4))[0]
@ -607,7 +607,7 @@ class DALegacy(metaclass=LogBase):
ackval = self.usbread(1)
ackval += self.usbread(1)
ackval += self.usbread(1)
self.info("ACK: " + hexlify(ackval).decode('utf-8'))
self.info(f"ACK: {hexlify(ackval).decode('utf-8')}")
self.info("Setting stage 2 config ...")
if self.set_stage2_config(self.config.hwcode):
self.info("Uploading stage 2...")
@ -791,7 +791,7 @@ class DALegacy(metaclass=LogBase):
buffer = self.usbread(1)
if buffer != self.Rsp.ACK:
self.error(
f"Error on sending brom stage {stage} addr {hex(address+pos)}: " + hexlify(buffer).decode('utf-8'))
f"Error on sending brom stage {stage} addr {hex(address+pos)}: {hexlify(buffer).decode('utf-8')}")
self.config.set_gui_status(self.config.tr("Error on sending brom stage"))
break
time.sleep(0.5)
@ -802,7 +802,7 @@ class DALegacy(metaclass=LogBase):
self.config.set_gui_status(self.config.tr(f"Successfully uploaded stage {stage}"))
return True
else:
self.error(f"Error on sending brom stage {stage} : " + hexlify(buffer).decode('utf-8'))
self.error(f"Error on sending brom stage {stage} : {hexlify(buffer).decode('utf-8')}")
self.config.set_gui_status(self.config.tr("Error on sending brom stage"))
return False

View file

@ -80,7 +80,8 @@ class legacyext(metaclass=LogBase):
self.warning("Legacy DA2 CMD F0 not patched.")
return da2patched
def fix_hash(self, da1, da2, da2sig_len, hashpos, hashmode):
@staticmethod
def fix_hash(da1, da2, da2sig_len, hashpos, hashmode):
da1 = bytearray(da1)
dahash = None
if hashmode == 1:
@ -245,26 +246,25 @@ class legacyext(metaclass=LogBase):
except Exception:
return
hwc = self.cryptosetup()
retval = {}
retval["hwcode"] = hex(self.config.hwcode)
retval = {"hwcode": hex(self.config.hwcode)}
meid = self.config.get_meid()
socid = self.config.get_socid()
hwcode = self.config.get_hwcode()
pubk = self.read_pubk()
if pubk is not None:
retval["pubkey"] = pubk.hex()
self.info("PUBK : " + pubk.hex())
self.info(f"PUBK : {pubk.hex()}")
self.config.hwparam.writesetting("pubkey", pubk.hex())
if meid is not None:
self.info("MEID : " + hexlify(meid).decode('utf-8'))
self.info(f"MEID : {hexlify(meid).decode('utf-8')}")
retval["meid"] = hexlify(meid).decode('utf-8')
self.config.hwparam.writesetting("meid", hexlify(meid).decode('utf-8'))
if socid is not None:
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
self.info(f"SOCID : {hexlify(socid).decode('utf-8')}")
retval["socid"] = hexlify(socid).decode('utf-8')
self.config.hwparam.writesetting("socid", hexlify(socid).decode('utf-8'))
if hwcode is not None:
self.info("HWCODE : " + hex(hwcode))
self.info(f"HWCODE : {hex(hwcode)}")
retval["hwcode"] = hex(hwcode)
self.config.hwparam.writesetting("hwcode", hex(hwcode))
if self.config.chipconfig.dxcc_base is not None:
@ -281,24 +281,24 @@ class legacyext(metaclass=LogBase):
# 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'))
self.info(f"RPMB : {hexlify(rpmbkey).decode('utf-8')}")
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
if rpmb2key is not None:
self.info("RPMB2 : " + hexlify(rpmb2key).decode('utf-8'))
self.info(f"RPMB2 : {hexlify(rpmb2key).decode('utf-8')}")
self.config.hwparam.writesetting("rpmb2key", hexlify(rpmb2key).decode('utf-8'))
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
if fdekey is not None:
self.info("FDE : " + hexlify(fdekey).decode('utf-8'))
self.info(f"FDE : {hexlify(fdekey).decode('utf-8')}")
self.config.hwparam.writesetting("fdekey", hexlify(fdekey).decode('utf-8'))
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
if ikey is not None:
self.info("iTrustee : " + hexlify(ikey).decode('utf-8'))
self.info(f"iTrustee : {hexlify(ikey).decode('utf-8')}")
self.config.hwparam.writesetting("kmkey", hexlify(ikey).decode('utf-8'))
retval["kmkey"] = hexlify(ikey).decode('utf-8')
if self.config.chipconfig.prov_addr:
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
self.info("PROV : " + hexlify(provkey).decode('utf-8'))
self.info(f"PROV : {hexlify(provkey).decode('utf-8')}")
self.config.hwparam.writesetting("provkey", hexlify(provkey).decode('utf-8'))
retval["provkey"] = hexlify(provkey).decode('utf-8')
"""
@ -311,7 +311,7 @@ class legacyext(metaclass=LogBase):
otp = self.config.get_otp()
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
if mtee3:
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
self.info(f"MTEE3 : {hexlify(mtee3).decode('utf-8')}")
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
return retval
@ -331,19 +331,19 @@ class legacyext(metaclass=LogBase):
self.setotp(hwc)
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
if rpmbkey:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
self.info(f"RPMB : {hexlify(rpmbkey).decode('utf-8')}")
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
self.info("Generating sej mtee...")
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
if mtee:
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
self.info(f"MTEE : {hexlify(mtee).decode('utf-8')}")
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
retval["mtee"] = hexlify(mtee).decode('utf-8')
self.info("Generating sej mtee3...")
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
if mtee3:
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
self.info(f"MTEE3 : {hexlify(mtee3).decode('utf-8')}")
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
else:
@ -353,7 +353,7 @@ class legacyext(metaclass=LogBase):
self.info("Generating gcpu mtee2 key...")
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
if mtee2 is not None:
self.info("MTEE2 : " + hexlify(mtee2).decode('utf-8'))
self.info(f"MTEE2 : {hexlify(mtee2).decode('utf-8')}")
self.config.hwparam.writesetting("mtee2", hexlify(mtee2).decode('utf-8'))
retval["mtee2"] = hexlify(mtee2).decode('utf-8')
self.config.hwparam.writesetting("hwcode", retval["hwcode"])

View file

@ -30,7 +30,8 @@ class DA_handler(metaclass=LogBase):
self.eh = ErrorHandler()
self.mtk = mtk
def close(self):
@staticmethod
def close():
sys.exit(0)
def dump_preloader_ram(self):
@ -91,7 +92,7 @@ class DA_handler(metaclass=LogBase):
if mtk.config.target_config["sbc"] and not mtk.config.is_brom and mtk.config.loader is None:
mtk = mtk.bypass_security()
self.mtk = mtk
if self.mtk.daloader.patch :
if self.mtk.daloader.patch:
self.info("Device was protected. Successfully bypassed security.")
else:
self.info("Device is still protected, trying to boot to brom")
@ -197,7 +198,7 @@ class DA_handler(metaclass=LogBase):
rpartition = gptentry
break
if rpartition is not None:
self.info(f"Dumping partition \"{rpartition.name}\"")
self.info(f'Dumping partition "{rpartition.name}"')
if self.mtk.daloader.readflash(addr=rpartition.sector * self.config.pagesize,
length=rpartition.sectors * self.config.pagesize,
filename=partfilename, parttype=parttype):
@ -645,7 +646,7 @@ class DA_handler(metaclass=LogBase):
elif cmd == "printgpt":
data, guid_gpt = mtk.daloader.get_gpt()
if not guid_gpt:
self.error("Error reading gpt, please read whole flash using \"mtk rf flash.bin\".")
self.error('Error reading gpt, please read whole flash using "mtk rf flash.bin".')
else:
guid_gpt.print()
elif cmd == "r":
@ -685,7 +686,8 @@ class DA_handler(metaclass=LogBase):
print(f"Failed to dump offset {hex(start)} with length {hex(length)} as {filename}.")
elif cmd == "fs":
print(f'Mounting FUSE fs at: {args.mountpoint}...')
fs = FUSE(MtkDaFS(self, rw=args.rw), mountpoint=args.mountpoint, foreground=True, allow_other=True, nothreads=True)
fs = FUSE(MtkDaFS(self, rw=args.rw), mountpoint=args.mountpoint, foreground=True, allow_other=True,
nothreads=True)
elif cmd == "footer":
filename = args.filename
self.da_footer(filename=filename)

View file

@ -89,7 +89,8 @@ class DAloader(metaclass=LogBase):
return idx, hashmode, hashlen
return idx, hashmode, hashlen
def find_da_hash_V6(self, da1, siglen):
@staticmethod
def find_da_hash_V6(da1, siglen):
pos = len(da1) - siglen - 0x30
hash = da1[pos:pos + 0x30]
if hash[-4:] == b"\x00\x00\x00\x00":
@ -110,7 +111,8 @@ class DAloader(metaclass=LogBase):
self.debug("Error: No hash found")
return -1, -1
def calc_da_hash(self, da1, da2):
@staticmethod
def calc_da_hash(da1, da2):
hashdigest = hashlib.sha1(da2).digest()
hashdigest256 = hashlib.sha256(da2).digest()
idx = da1.find(hashdigest)
@ -120,7 +122,8 @@ class DAloader(metaclass=LogBase):
hashmode = 2
return hashmode, idx
def fix_hash(self, da1, da2, hashpos, hashmode, hashlen):
@staticmethod
def fix_hash(da1, da2, hashpos, hashmode, hashlen):
da1 = bytearray(da1)
dahash = None
if hashmode == 1:
@ -226,7 +229,7 @@ class DAloader(metaclass=LogBase):
if self.mtk.config.chipconfig.damode == damodes.XFLASH:
self.da = DAXFlash(self.mtk, self.daconfig, self.loglevel)
if porttype not in ["off", "usb", "uart"]:
self.error("Only \"off\",\"usb\" or \"uart\" are allowed.")
self.error('Only "off","usb" or "uart" are allowed.')
if self.da.set_meta(porttype):
self.info(f"Successfully set meta mode to {porttype}")
return True

View file

@ -323,7 +323,7 @@ class xflashext(metaclass=LogBase):
return False
data = unpack("<I", val)[0]
if dwords == 1:
self.debug(f"RX: {hex(addr + (pos * 4))} -> " + hex(data))
self.debug(f"RX: {hex(addr + (pos * 4))} -> {hex(data)}")
return data
res.append(data)
else:
@ -460,7 +460,7 @@ class xflashext(metaclass=LogBase):
self.error("Couldn't read rpmb.")
return False
wf.write(data)
self.info("Done reading rpmb to " + filename)
self.info(f"Done reading rpmb to {filename}")
return True
return False
@ -658,22 +658,22 @@ class xflashext(metaclass=LogBase):
pubk = self.read_pubk()
if pubk is not None:
retval["pubkey"] = pubk.hex()
self.info("PUBK : " + pubk.hex())
self.info(f"PUBK : {pubk.hex()}")
self.config.hwparam.writesetting("pubkey", pubk.hex())
if meid is not None:
self.info("MEID : " + meid.hex())
self.info(f"MEID : {meid.hex()}")
retval["meid"] = meid.hex()
self.config.hwparam.writesetting("meid", meid.hex())
if socid is not None:
self.info("SOCID : " + socid.hex())
self.info(f"SOCID : {socid.hex()}")
retval["socid"] = socid.hex()
self.config.hwparam.writesetting("socid", socid.hex())
if hwcode is not None:
self.info("HWCODE : " + hex(hwcode))
self.info(f"HWCODE : {hex(hwcode)}")
retval["hwcode"] = hex(hwcode)
self.config.hwparam.writesetting("hwcode", hex(hwcode))
if cid is not None:
self.info("CID : " + cid)
self.info(f"CID : {cid}")
retval["cid"] = cid
if self.config.chipconfig.dxcc_base is not None:
self.info("Generating dxcc rpmbkey...")
@ -691,34 +691,34 @@ class xflashext(metaclass=LogBase):
# self.info("Provkey : " + provkey.hex())
# self.info("Platkey : " + platkey.hex())
if mirpmbkey is not None:
self.info("MIRPMB : " + mirpmbkey.hex())
self.info(f"MIRPMB : {mirpmbkey.hex()}")
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
retval["mirpmbkey"] = mirpmbkey.hex()
if rpmbkey is not None:
self.info("RPMB : " + rpmbkey.hex())
self.info(f"RPMB : {rpmbkey.hex()}")
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
retval["rpmbkey"] = rpmbkey.hex()
if rpmb2key is not None:
self.info("RPMB2 : " + rpmb2key.hex())
self.info(f"RPMB2 : {rpmb2key.hex()}")
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
retval["rpmb2key"] = rpmb2key.hex()
if fdekey is not None:
self.info("FDE : " + fdekey.hex())
self.info(f"FDE : {fdekey.hex()}")
self.config.hwparam.writesetting("fdekey", fdekey.hex())
retval["fdekey"] = fdekey.hex()
if ikey is not None:
self.info("iTrustee : " + ikey.hex())
self.info(f"iTrustee : {ikey.hex()}")
self.config.hwparam.writesetting("kmkey", ikey.hex())
retval["kmkey"] = ikey.hex()
if self.config.chipconfig.prov_addr:
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
self.info("PROV : " + provkey.hex())
self.info(f"PROV : {provkey.hex()}")
self.config.hwparam.writesetting("provkey", provkey.hex())
retval["provkey"] = provkey.hex()
hrid = self.xflash.get_hrid()
rid = self.xflash.get_random_id()
if hrid is not None:
self.info("HRID : " + hrid.hex())
self.info(f"HRID : {hrid.hex()}")
self.config.hwparam.writesetting("hrid", hrid.hex())
retval["hrid"] = hrid.hex()
else:
@ -727,19 +727,19 @@ class xflashext(metaclass=LogBase):
val += self.read_fuse(0xD)
val += self.read_fuse(0xE)
val += self.read_fuse(0xF)
self.info("HRID : " + val.hex())
self.info(f"HRID : {val.hex()}")
self.config.hwparam.writesetting("hrid", val.hex())
retval["hrid"] = val.hex()
if rid is not None:
self.info("RID : " + rid.hex())
self.info(f"RID : {rid.hex()}")
self.config.hwparam.writesetting("rid", rid.hex())
retval["rid"] = rid.hex()
if hwcode == 0x699 and self.config.chipconfig.sej_base is not None:
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
if mtee3:
self.config.hwparam.writesetting("mtee3", mtee3.hex())
self.info("MTEE3 : " + mtee3.hex())
self.info(f"MTEE3 : {mtee3.hex()}")
retval["mtee3"] = mtee3.hex()
return retval
elif self.config.chipconfig.sej_base is not None:
@ -754,19 +754,19 @@ class xflashext(metaclass=LogBase):
self.setotp(hwc)
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
if rpmbkey:
self.info("RPMB : " + rpmbkey.hex())
self.info(f"RPMB : {rpmbkey.hex()}")
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
retval["rpmbkey"] = rpmbkey.hex()
self.info("Generating sej mtee...")
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
if mtee:
self.config.hwparam.writesetting("mtee", mtee.hex())
self.info("MTEE : " + mtee.hex())
self.info(f"MTEE : {mtee.hex()}")
retval["mtee"] = mtee.hex()
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
if mtee3:
self.config.hwparam.writesetting("mtee3", mtee3.hex())
self.info("MTEE3 : " + mtee3.hex())
self.info(f"MTEE3 : {mtee3.hex()}")
retval["mtee3"] = mtee3.hex()
else:
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
@ -775,7 +775,7 @@ class xflashext(metaclass=LogBase):
self.info("Generating gcpu mtee2 key...")
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
if mtee2 is not None:
self.info("MTEE2 : " + mtee2.hex())
self.info(f"MTEE2 : {mtee2.hex()}")
self.config.hwparam.writesetting("mtee2", mtee2.hex())
retval["mtee2"] = mtee2.hex()
return retval

View file

@ -72,7 +72,8 @@ class DAXFlash(metaclass=LogBase):
except Exception:
self.carbonara = None
def usleep(self, usec):
@staticmethod
def usleep(usec):
time.sleep(usec / 100000)
def ack(self, rstatus=True):
@ -108,7 +109,7 @@ class DAXFlash(metaclass=LogBase):
hdr = self.usbread(4 + 4 + 4)
magic, datatype, length = unpack("<III", hdr)
except Exception as err:
self.error("xread error: " + str(err))
self.error(f"xread error: {str(err)}")
return -1
if magic != 0xFEEEEEEF:
self.error("xread error: Wrong magic")
@ -353,8 +354,7 @@ class DAXFlash(metaclass=LogBase):
if self.daconfig.flashtype == "emmc":
length = min(length, self.emmc.rpmb_size)
else:
self.error("Unknown parttype. Known parttypes are \"boot1\",\"boot2\",\"gp1\"," +
"\"gp2\",\"gp3\",\"gp4\",\"rpmb\"")
self.error('Unknown parttype. Known parttypes are "boot1","boot2","gp1","gp2","gp3","gp4","rpmb"')
return []
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
if parttype is None or parttype == "lu3" or parttype == "user": # USER
@ -370,7 +370,7 @@ class DAXFlash(metaclass=LogBase):
parttype = UFS_PartitionType.UFS_LU4
length = min(length, self.ufs.lu2_size)
else:
self.error("Unknown parttype. Known parttypes are \"lu1\",\"lu2\",\"lu3\",\"lu4\"")
self.error('Unknown parttype. Known parttypes are "lu1","lu2","lu3","lu4"')
return []
elif storage in [DaStorage.MTK_DA_STORAGE_NAND, DaStorage.MTK_DA_STORAGE_NAND_MLC,
DaStorage.MTK_DA_STORAGE_NAND_SLC, DaStorage.MTK_DA_STORAGE_NAND_TLC,
@ -1119,11 +1119,11 @@ class DAXFlash(metaclass=LogBase):
if self.daconfig.emi is None:
emmc_info = self.get_emmc_info(False)
if emmc_info is not None and emmc_info.user_size != 0:
self.info("DRAM config needed for : " + hexlify(emmc_info.cid[:8]).decode('utf-8'))
self.info(f"DRAM config needed for : {hexlify(emmc_info.cid[:8]).decode('utf-8')}")
else:
ufs_info = self.get_ufs_info()
if ufs_info is not None and ufs_info.block_size != 0:
self.info("DRAM config needed for : " + hexlify(ufs_info.cid).decode('utf-8'))
self.info(f"DRAM config needed for : {hexlify(ufs_info.cid).decode('utf-8')}")
self.info("No preloader given. Searching for preloader")
found = False
for root, dirs, files in os.walk(os.path.join(self.pathconfig.get_loader_path(), 'Preloader')):
@ -1188,7 +1188,7 @@ class DAXFlash(metaclass=LogBase):
self.error("Error on booting to da (xflash)")
return False
else:
self.error("Didn't get brom connection, got instead: " + hexlify(connagent).decode('utf-8'))
self.error(f"Didn't get brom connection, got instead: {hexlify(connagent).decode('utf-8')}")
return False

View file

@ -377,7 +377,7 @@ class xmlflashext(metaclass=LogBase):
self.error("Couldn't read rpmb.")
return False
wf.write(data)
self.info("Done reading rpmb to " + filename)
self.info(f"Done reading rpmb to {filename}")
return True
return False
@ -686,22 +686,22 @@ class xmlflashext(metaclass=LogBase):
pubk = self.read_pubk()
if pubk is not None:
retval["pubkey"] = pubk.hex()
self.info("PUBK : " + pubk.hex())
self.info(f"PUBK : {pubk.hex()}")
self.config.hwparam.writesetting("pubkey", pubk.hex())
if meid is not None:
self.info("MEID : " + meid.hex())
self.info(f"MEID : {meid.hex}")
retval["meid"] = meid.hex()
self.config.hwparam.writesetting("meid", meid.hex())
if socid is not None:
self.info("SOCID : " + socid.hex())
self.info(f"SOCID : {socid.hex()}")
retval["socid"] = socid.hex()
self.config.hwparam.writesetting("socid", socid.hex())
if hwcode is not None:
self.info("HWCODE : " + hex(hwcode))
self.info(f"HWCODE : {hex(hwcode)}")
retval["hwcode"] = hex(hwcode)
self.config.hwparam.writesetting("hwcode", hex(hwcode))
if cid is not None:
self.info("CID : " + cid)
self.info(f"CID : {cid}")
retval["cid"] = cid
if self.config.chipconfig.dxcc_base is not None:
self.info("Generating dxcc rpmbkey...")
@ -719,28 +719,28 @@ class xmlflashext(metaclass=LogBase):
# self.info("Provkey : " + provkey.hex())
# self.info("Platkey : " + platkey.hex())
if mirpmbkey is not None:
self.info("MIRPMB : " + mirpmbkey.hex())
self.info(f"MIRPMB : {mirpmbkey.hex()}")
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
retval["mirpmbkey"] = mirpmbkey.hex()
if rpmbkey is not None:
self.info("RPMB : " + rpmbkey.hex())
self.info(f"RPMB : {rpmbkey.hex()}")
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
retval["rpmbkey"] = rpmbkey.hex()
if rpmb2key is not None:
self.info("RPMB2 : " + rpmb2key.hex())
self.info(f"RPMB2 : {rpmb2key.hex()}")
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
retval["rpmb2key"] = rpmb2key.hex()
if fdekey is not None:
self.info("FDE : " + fdekey.hex())
self.info(f"FDE : {fdekey.hex()}")
self.config.hwparam.writesetting("fdekey", fdekey.hex())
retval["fdekey"] = fdekey.hex()
if ikey is not None:
self.info("iTrustee : " + ikey.hex())
self.info(f"iTrustee : {ikey.hex()}")
self.config.hwparam.writesetting("kmkey", ikey.hex())
retval["kmkey"] = ikey.hex()
if self.config.chipconfig.prov_addr:
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
self.info("PROV : " + provkey.hex())
self.info(f"PROV : {provkey.hex()}")
self.config.hwparam.writesetting("provkey", provkey.hex())
retval["provkey"] = provkey.hex()
@ -749,7 +749,7 @@ class xmlflashext(metaclass=LogBase):
val += self.read_fuse(0xD)
val += self.read_fuse(0xE)
val += self.read_fuse(0xF)
self.info("HRID : " + val.hex())
self.info(f"HRID : {val.hex()}")
self.config.hwparam.writesetting("hrid", val.hex())
retval["hrid"] = val.hex()
@ -757,7 +757,7 @@ class xmlflashext(metaclass=LogBase):
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
if mtee3:
self.config.hwparam.writesetting("mtee3", mtee3.hex())
self.info("MTEE3 : " + mtee3.hex())
self.info(f"MTEE3 : {mtee3.hex()}")
retval["mtee3"] = mtee3.hex()
return retval
elif self.config.chipconfig.sej_base is not None:
@ -772,19 +772,19 @@ class xmlflashext(metaclass=LogBase):
self.setotp(hwc)
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
if rpmbkey:
self.info("RPMB : " + rpmbkey.hex())
self.info(f"RPMB : {rpmbkey.hex()}")
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
retval["rpmbkey"] = rpmbkey.hex()
self.info("Generating sej mtee...")
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
if mtee:
self.config.hwparam.writesetting("mtee", mtee.hex())
self.info("MTEE : " + mtee.hex())
self.info(f"MTEE : {mtee.hex()}")
retval["mtee"] = mtee.hex()
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
if mtee3:
self.config.hwparam.writesetting("mtee3", mtee3.hex())
self.info("MTEE3 : " + mtee3.hex())
self.info(f"MTEE3 : {mtee3.hex()}")
retval["mtee3"] = mtee3.hex()
else:
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
@ -793,7 +793,7 @@ class xmlflashext(metaclass=LogBase):
self.info("Generating gcpu mtee2 key...")
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
if mtee2 is not None:
self.info("MTEE2 : " + mtee2.hex())
self.info(f"MTEE2 : {mtee2.hex()}")
self.config.hwparam.writesetting("mtee2", mtee2.hex())
retval["mtee2"] = mtee2.hex()
return retval

View file

@ -14,7 +14,8 @@ class XMLCmd(metaclass=LogBase):
self.mtk = mtk
self.MAGIC = 0xFEEEEEEF
def create_cmd(self, cmd: str, content: dict = None, version="1.0"):
@staticmethod
def create_cmd(cmd: str, content: dict = None, version="1.0"):
cmd = f"<?xml version=\"1.0\" encoding=\"utf-8\"?><da><version>{version}</version><command>CMD:{cmd}</command>"
if content is not None:
for item in content:
@ -323,11 +324,13 @@ class XMLCmd(metaclass=LogBase):
cmd = self.create_cmd("WRITE-REGISTER", content)
return cmd
def cmd_read_partition_name(self):
@staticmethod
def cmd_read_partition_name():
cmd = ""
return cmd
def cmd_debug_ufs(self):
@staticmethod
def cmd_debug_ufs():
cmd = ""
return cmd

View file

@ -708,7 +708,7 @@ class DAXML(metaclass=LogBase):
self.error("Couldn't find item key")
return data
def get_sys_property(self, key: int = "DA.SLA", length: int = 0x200000):
def get_sys_property(self, key: str = "DA.SLA", length: int = 0x200000):
self.send_command(self.Cmd.cmd_get_sys_property(key=key, length=length), noack=True)
cmd, result = self.get_command_result()
if type(result) is not upfile:
@ -783,8 +783,7 @@ class DAXML(metaclass=LogBase):
if self.daconfig.flashtype == "emmc":
length = min(length, self.emmc.gp1_size)
else:
self.error("Unknown parttype. Known parttypes are \"boot1\",\"boot2\",\"gp1\"," +
"\"gp2\",\"gp3\",\"gp4\",\"rpmb\"")
self.error('Unknown parttype. Known parttypes are "boot1","boot2","gp1","gp2","gp3","gp4","rpmb"')
return []
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
if parttype is None or parttype == "lu3" or parttype == "user": # USER

View file

@ -53,10 +53,7 @@ class Hashimoto(Exploitation, metaclass=LogBase):
if addr is None:
addr = self.chipconfig.da_payload_addr
if self.payload(payload, addr):
if dontack:
return ack
result = self.usbread(4)
if result == pack(">I", ack):
if dontack or self.usbread(4) == pack(">I", ack):
return ack
return None
@ -71,10 +68,7 @@ class Hashimoto(Exploitation, metaclass=LogBase):
if filename is None:
data = bytearray()
for addr in range(0x200000, 0x240000, 16):
if not self.chipconfig.blacklist:
data.extend(self.hwcrypto.cqdma.mem_read(addr, 16, True))
else:
data.extend(self.hwcrypto.cqdma.mem_read(addr, 16, False))
data.extend(self.hwcrypto.cqdma.mem_read(addr, 16, not self.chipconfig.blacklist))
return data, filename
else:
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
@ -86,10 +80,7 @@ class Hashimoto(Exploitation, metaclass=LogBase):
print_progress(prog, 100, prefix='Progress:', suffix='Complete, addr %08X' % addr,
bar_length=50)
old = round(prog, 1)
if not self.chipconfig.blacklist:
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, True))
else:
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, False))
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, not self.chipconfig.blacklist))
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
return True
@ -110,9 +101,6 @@ class Hashimoto(Exploitation, metaclass=LogBase):
print_progress(prog, 100, prefix='Progress:', suffix='Complete, addr %08X' % addr,
bar_length=50)
old = round(prog, 1)
if not self.chipconfig.blacklist:
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, True))
else:
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, False))
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, not self.chipconfig.blacklist))
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
return True

View file

@ -82,7 +82,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
self.mtk.preloader.display = False
if self.mtk.preloader.init(display=False):
self.mtk = self.mtk.crasher(display=False)
self.info("Bruteforce, testing " + hex(startaddr) + "...")
self.info(f"Bruteforce, testing {hex(startaddr)}...")
if self.linecode is None:
self.linecode = self.mtk.port.cdc.device.ctrl_transfer(0xA1, 0x21, 0, 0, 7) + array.array('B', [0])
found, startaddr = self.newbrute(startaddr)
@ -92,8 +92,8 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
cpu = ""
if self.mtk.config.cpu != "":
cpu = "_" + self.mtk.config.cpu
filename = "brom" + cpu + "_" + hex(self.mtk.config.hwcode)[2:] + ".bin"
self.info("Found " + hex(startaddr) + f", dumping bootrom to {filename}")
filename = f"brom{cpu}_{hex(self.mtk.config.hwcode)[2:]}.bin"
self.info(f"Found {hex(startaddr)}, dumping bootrom to {filename}")
self.dump_brom(filename, dump_ptr=startaddr)
break
else:
@ -110,7 +110,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
# noinspection PyProtectedMember
udev._ctx.managed_claim_interface = lambda *args, **kwargs: None
except AttributeError as e:
raise RuntimeError("libusb is not installed for port {}".format(udev.dev.port)) from e
raise RuntimeError(f"libusb is not installed for port {udev.dev.port}") from e
if dump:
try:
@ -135,7 +135,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
for address in range(dump_ptr, 0xffff, 4):
if address % 0x100 == 0:
self.info("Bruteforce, testing " + hex(address) + "...")
self.info(f"Bruteforce, testing {hex(address)}...")
for i in range(3):
self.kamakiri2(address - 5 + (3 - i))
try:
@ -143,7 +143,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
return True, address
except RuntimeError:
try:
self.info("Bruteforce, testing " + hex(address) + "...")
self.info(f"Bruteforce, testing {hex(address)}...")
self.mtk.preloader.read32(addr)
except Exception:
return False, address + 4
@ -212,7 +212,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
if result == pack(">I", ack):
return ack
else:
self.info("Error, payload answered instead: " + hexlify(result).decode('utf-8'))
self.info(f"Error, payload answered instead: {hexlify(result).decode('utf-8')}")
return None
def patchda1_and_da2(self):

Binary file not shown.

Binary file not shown.

View file

@ -1,38 +1,34 @@
from fuse import FuseOSError, Operations, LoggingMixIn
from pathlib import Path
import logging
import os
from stat import S_IFDIR, S_IFLNK, S_IFREG
from time import time
import mmap
import errno
from stat import S_IFDIR, S_IFREG
from tempfile import NamedTemporaryFile
from time import time
import sys
import os
if not os.environ.get('FUSE_LIBRARY_PATH') and os.name == 'nt':
os.environ.setdefault('FUSE_LIBRARY_PATH', os.path.join(os.path.dirname(__file__), r"bin\winfsp-%s.dll" % ("x64" if sys.maxsize > 0xffffffff else "x86")))
from fuse import Operations, LoggingMixIn
class MtkDaFS(LoggingMixIn, Operations):
def __init__(self, da_handler, rw=False):
self.da_handler = da_handler
self.rw = rw
self.files = {}
self.files['/'] = dict(
self.files = {'/': dict(
st_mode=(S_IFDIR | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2)
self.files['/emmc_user.bin'] = dict(
st_nlink=2), '/emmc_user.bin': dict(
st_mode=(S_IFREG | 0o777) if self.rw else (S_IFREG | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2,
st_size = self.da_handler.mtk.daloader.daconfig.flashsize)
self.files['/partitions'] = dict(
st_size=self.da_handler.mtk.daloader.daconfig.flashsize), '/partitions': dict(
st_mode=(S_IFDIR | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2)
st_nlink=2)}
for part in self.da_handler.mtk.daloader.get_partition_data():
self.files[f'/partitions/{part.name}'] = dict(
@ -41,35 +37,36 @@ class MtkDaFS(LoggingMixIn, Operations):
st_mtime=time(),
st_atime=time(),
st_nlink=2,
st_size = part.sectors*self.da_handler.mtk.daloader.daconfig.pagesize,
offset=part.sector*self.da_handler.mtk.daloader.daconfig.pagesize)
st_size=part.sectors * self.da_handler.mtk.daloader.daconfig.pagesize,
offset=part.sector * self.da_handler.mtk.daloader.daconfig.pagesize)
def readdir(self, path, fh):
return ['.', '..'] + [ x.removeprefix(path).removeprefix('/') for x in self.files if x.startswith(path) and x != path]
return ['.', '..'] + [x.removeprefix(path).removeprefix('/') for x in self.files if
x.startswith(path) and x != path]
def read(self, path, size, offset, fh):
if size+offset > self.files[path]['st_size']:
if size + offset > self.files[path]['st_size']:
return b''
file_offset = 0
if 'offset' in self.files[path]:
file_offset = self.files[path]['offset']
data = self.da_handler.da_ro(start=file_offset+offset, length=size, filename='', parttype=None)
data = self.da_handler.da_ro(start=file_offset + offset, length=size, filename='', parttype=None)
return bytes(data)
def write(self, path, data, offset, fh):
if not self.rw:
return 0
if offset+len(data) > self.files[path]['st_size']:
if offset + len(data) > self.files[path]['st_size']:
return b''
file_offset = 0
if 'offset' in self.files[path]:
file_offset = self.files[path]['offset']
with NamedTemporaryFile('rb+', buffering=0) as f_write:
f_write.write(data)
self.da_handler.da_wo(start=file_offset+offset, length=len(data), filename=f_write.name, parttype=None)
self.da_handler.da_wo(start=file_offset + offset, length=len(data), filename=f_write.name, parttype=None)
return len(data)
def getattr(self, path, fh=None):

View file

@ -108,7 +108,7 @@ class hwcrypto(metaclass=LogBase):
elif mode == "sha256":
return self.dxcc.generate_sha256(data=data)
else:
self.error("Unknown aes_hwcrypt type: " + btype)
self.error(f"Unknown aes_hwcrypt type: {btype}")
self.error("aes_hwcrypt supported types are: sej")
return bytearray()

View file

@ -1050,7 +1050,8 @@ class dxcc(metaclass=LogBase):
def sasi_paldmaunmap(self, value1):
return
def sasi_paldmamap(self, value1):
@staticmethod
def sasi_paldmamap(value1):
# value2=value1
return value1
@ -1305,12 +1306,14 @@ class dxcc(metaclass=LogBase):
self.sasi_sb_adddescsequence(xdesc)
return self.SB_HalWaitDescCompletion() == 0
def mtee_decrypt(self, data):
@staticmethod
def mtee_decrypt(data):
key = bytes.fromhex("B936C14D95A99585073E5607784A51F7444B60D6BFD6110F76D004CCB7E1950E")
skey = hashlib.sha256(key).digest()
return AES.new(key=skey[:16], iv=skey[16:], mode=AES.MODE_CBC).decrypt(data)
def descramble(self, data):
@staticmethod
def descramble(data):
key = bytes.fromhex("5C0E349A27DC46034C7B6744A378BD17")
iv = bytes.fromhex("A0B0924686447109F2D51DCDDC93458A")
ctr = Counter.new(128, initial_value=bytes_to_long(iv))

View file

@ -642,7 +642,7 @@ class GCpu(metaclass=LogBase):
self.aes_setup_cbc(addr, data)
def mtk_crypto_hmac_sha256_by_devkey_using_seed(self, seed, data):
dev_key = bytearray("\x00" * 16)
dev_key = bytearray(16)
self.init()
if not self.load_hw_key(0x30):
self.memptr_set(0x12, seed)
@ -667,7 +667,7 @@ class GCpu(metaclass=LogBase):
def mtk_crypto_hmac_sha256_by_devkey(self, data: bytearray, seed: bytearray):
if seed is None:
seed = bytearray("\x00" * 16)
seed = bytearray(16)
dev_val = self.get_devinfo_with_index(12)
seed = xor_data(seed, dev_val, 4)
dev_val = self.get_devinfo_with_index(13)
@ -675,7 +675,8 @@ class GCpu(metaclass=LogBase):
self.info("seed: " + hexlify(seed[:16]).decode('utf-8'))
return self.mtk_crypto_hmac_sha256_by_devkey_using_seed(seed, data)
def byteswap(self, data):
@staticmethod
def byteswap(data):
data = bytearray(data)
for i in range(0, len(data) // 2):
j = len(data) - i - 1

View file

@ -184,7 +184,8 @@ class sej(metaclass=LogBase):
else:
self.__logger.setLevel(logging.INFO)
def uffs(self, x):
@staticmethod
def uffs(x):
v1 = x
if x & 0xFFFF:
result = 1
@ -669,7 +670,8 @@ class sej(metaclass=LogBase):
hw_key = self.sej_do_aes(True, iv, swkey, 32)
self.sej_set_key(AES_HW_WRAP_KEY, AES_KEY_256, hw_key)
def sej_sec_cfg_sw(self, data, encrypt=True):
@staticmethod
def sej_sec_cfg_sw(data, encrypt=True):
"""
Left for reference - hw implementation
--------------------------------------

View file

@ -116,7 +116,7 @@ class Port(metaclass=LogBase):
sys.stdout.flush()
except Exception as serr:
print("Handshake: " + str(serr))
print(f"Handshake: {str(serr)}")
if "access denied" in str(serr):
self.warning(str(serr))
self.debug(str(serr))
@ -194,13 +194,13 @@ class Port(metaclass=LogBase):
else:
cmdrsp = self.usbread(dlen)
if cmdrsp[0] is not value[0]:
self.error("Cmd error :" + hexlify(cmdrsp).decode('utf-8'))
self.error(f"Cmd error :{hexlify(cmdrsp).decode('utf-8')}")
return -1
if bytestoread > 0:
resp = self.usbread(bytestoread)
return resp
else:
self.warning("Couldn't send :" + hexlify(value).decode('utf-8'))
self.warning(f"Couldn't send :{hexlify(value).decode('utf-8')}")
return resp
def echo(self, data):

View file

@ -7,7 +7,8 @@ from capstone import (Cs, CS_MODE_BIG_ENDIAN, CS_MODE_LITTLE_ENDIAN,
CS_MODE_ARM, CS_MODE_THUMB, CS_MODE_V8, CS_MODE_V9,
CS_MODE_MCLASS, CS_MODE_MICRO, CS_MODE_MIPS32, CS_MODE_MIPS64,
CS_MODE_MIPS32R6, CS_MODE_16, CS_MODE_32, CS_MODE_64)
from keystone import (Ks, KS_MODE_BIG_ENDIAN, KS_MODE_LITTLE_ENDIAN, KS_ARCH_ARM, KS_MODE_THUMB, KS_MODE_ARM, KS_MODE_V8,
from keystone import (Ks, KS_MODE_BIG_ENDIAN, KS_MODE_LITTLE_ENDIAN, KS_ARCH_ARM, KS_MODE_THUMB, KS_MODE_ARM,
KS_MODE_V8,
KS_ARCH_ARM64, KS_ARCH_MIPS, KS_MODE_MICRO, KS_MODE_MIPS3, KS_MODE_MIPS32R6,
KS_MODE_MIPS32, KS_MODE_MIPS64, KS_MODE_16, KS_MODE_32, KS_MODE_64, KS_ARCH_X86,
KS_ARCH_PPC, KS_MODE_PPC32, KS_MODE_PPC64, KS_MODE_QPX,
@ -21,7 +22,7 @@ def asm(code, cpu, mode, bigendian):
little = KS_MODE_BIG_ENDIAN # big-endian mode
else:
little = KS_MODE_LITTLE_ENDIAN # little-endian mode (default mode)
print("CPU: %s, MODE: %s" % (cpu, mode))
print(f"CPU: {cpu}, MODE: {mode}")
ks = None
if cpu == "arm":
# ARM architecture (including Thumb, Thumb-2)
@ -142,10 +143,8 @@ def disasm(code, cpu, mode, bigendian, size):
print("CPU and/or mode not supported!")
exit(0)
instr = []
for i in cs.disasm(code, size):
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
instr.append("%s\t%s" % (i.mnemonic, i.op_str))
instr = [f"{i.mnemonic}\t{i.op_str}" for i in cs.disasm(code, size)]
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
return instr
@ -193,7 +192,7 @@ def main():
print("[asmtools] Usage: -asm cpu,mode or -disasm cpu,mode")
exit(0)
if (args.infile == '' and args.inp == ''):
if not args.infile == '' and args.inp == '':
print("[asmtools] I must have an infile to work on (-in) or a string input (--inp")
exit(0)
@ -251,4 +250,5 @@ def main():
'''
main()
if __name__ == '__main__':
main()

View file

@ -76,7 +76,8 @@ class cryptutils:
class aes:
# GF(2^128) defined by 1 + a + a^2 + a^7 + a^128
# Please note the MSB is x0 and LSB is x127
def gf_2_128_mul(self, x, y):
@staticmethod
def gf_2_128_mul(x, y):
assert x < (1 << 128)
assert y < (1 << 128)
res = 0
@ -88,7 +89,7 @@ class cryptutils:
class AES_GCM:
# Galois/Counter Mode with AES-128 and 96-bit IV
'''
"""
Example:
master_key = 0x0ADAABC70895E008147A48C27791F654 #54F69177C2487A1408E09508C7ABDA0A
init_value = 0x2883B4173F9A838437C1CD86CCFAA5ED #EDA5FACC86CDC13784839A3F17B48328
@ -122,7 +123,7 @@ class cryptutils:
b"\xA0\x62\x9E\xF9\xF4\xE7\xE8\x65"
my_gcm = AES_GCM(master_key)
decrypted = my_gcm.decrypt(init_value, ciphertext, auth_tag)
'''
"""
def __init__(self, master_key):
self.change_key(master_key)
@ -248,7 +249,8 @@ class cryptutils:
return plaintext
def aes_gcm(self, input, nounce, aes_key, hdr, tag_auth, decrypt=True):
@staticmethod
def aes_gcm(input, nounce, aes_key, hdr, tag_auth, decrypt=True):
cipher = AES.new(aes_key, AES.MODE_GCM, nounce)
if hdr is not None:
cipher.update(hdr)
@ -268,30 +270,30 @@ class cryptutils:
ciphertext, tag_auth = cipher.encrypt_and_digest(input)
return ciphertext, tag_auth
def aes_cbc(self, key, iv, data, decrypt=True):
@staticmethod
def aes_cbc(key, iv, data, decrypt=True):
if decrypt:
return AES.new(key, AES.MODE_CBC, IV=iv).decrypt(data)
else:
return AES.new(key, AES.MODE_CBC, IV=iv).encrypt(data)
def aes_ecb(self, key, data, decrypt=True):
@staticmethod
def aes_ecb(key, data, decrypt=True):
if decrypt:
return AES.new(key, AES.MODE_ECB).decrypt(data)
else:
return AES.new(key, AES.MODE_ECB).encrypt(data)
def aes_ctr(self, key, counter, enc_data, decrypt=True):
@staticmethod
def aes_ctr(key, counter, enc_data, decrypt=True):
ctr = Counter.new(128, initial_value=counter)
# Create the AES cipher object and decrypt the ciphertext, basically this here is just aes ctr 256 :)
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
data = b""
if decrypt:
data = cipher.decrypt(enc_data)
else:
data = cipher.encrypt(enc_data)
data = cipher.decrypt(enc_data) if decrypt else cipher.encrypt(enc_data)
return data
def aes_ccm(self, key, nounce, tag_auth, data, decrypt=True):
@staticmethod
def aes_ccm(key, nounce, tag_auth, data, decrypt=True):
cipher = AES.new(key, AES.MODE_CCM, nounce)
if decrypt:
plaintext = cipher.decrypt(data)
@ -304,6 +306,7 @@ class cryptutils:
ciphertext = cipher.encrypt(data)
return ciphertext
@staticmethod
def aes_cmac_verify(key, plain, compare):
ctx = CMAC.new(key, ciphermod=AES)
ctx.update(plain)
@ -347,12 +350,13 @@ class cryptutils:
else:
print("Test failed.")
def i2osp(self, x, x_len):
'''Converts the integer x to its big-endian representation of length
@staticmethod
def i2osp(x, x_len):
"""Converts the integer x to its big-endian representation of length
x_len.
'''
"""
if x > 256 ** x_len:
raise ("Integer Too Large")
raise "Integer Too Large"
h = hex(x)[2:]
if h[-1] == 'L':
h = h[:-1]
@ -361,12 +365,12 @@ class cryptutils:
x = bytes.fromhex(h)
return b'\x00' * int(x_len - len(x)) + x
def os2ip(self, x):
'''Converts the byte string x representing an integer reprented using the
@staticmethod
def os2ip(x):
"""Converts the byte string x representing an integer reprented using the
big-endian convient to an integer.
'''
h = hexlify(x)
return int(h, 16)
"""
return int(hexlify(x), 16)
# def os2ip(self, X):
# return int.from_bytes(X, byteorder='big')
@ -374,13 +378,14 @@ class cryptutils:
def mgf1(self, input, length):
counter = 0
output = b''
while (len(output) < length):
while len(output) < length:
C = self.i2osp(counter, 4)
output += self.hash(input + C)
counter += 1
return output[:length]
def assert_int(self, var: int, name: str):
@staticmethod
def assert_int(var: int, name: str):
if isinstance(var, int):
return
raise TypeError('%s should be an integer, not %s' % (name, var.__class__))
@ -428,7 +433,8 @@ class cryptutils:
return self.sign(tosign, D, N, emBits)
# 6B1EAA2042A5C8DA8B1B4A8320111A70A0CBA65233D1C6E418EF8156E82A8F96BD843F047FF25AB9702A6582C8387298753E628F23448B4580E09CBD2A483C623B888F47C4BD2C5EFF09013C6DFF67DB59BAB3037F0BEE05D5660264D28CC6251631FE75CE106D931A04FA032FEA31259715CE0FAB1AE0E2F8130807AF4019A61B9C060ECE59104F22156FEE8108F17DC80D7C2F8397AFB9780994F7C5A0652F93D1B48010B0B248AB9711235787D797FBA4D10A29BCF09628585D405640A866B15EE9D7526A2703E72A19811EF447F6E5C43F915B3808EBC79EA4BCF78903DBDE32E47E239CFB5F2B5986D0CBBFBE6BACDC29B2ADE006D23D0B90775B1AE4DD
def ceil_div(self, a, b):
@staticmethod
def ceil_div(a, b):
(q, r) = divmod(a, b)
if r:
return q + 1
@ -494,10 +500,12 @@ class cryptutils:
return False
return maskedDB
def sha1(self, msg):
@staticmethod
def sha1(msg):
return hashlib.sha1(msg).digest()
def sha256(self, msg):
@staticmethod
def sha256(msg):
return hashlib.sha256(msg).digest()

View file

@ -989,9 +989,9 @@ class ErrorHandler:
def status(self, status):
if status in self.ec:
return self.ec[status] + " (" + hex(status) + ")"
return f"{self.ec[status]} ({hex(status)})"
if status in self.xec:
return self.xec[status] + " (" + hex(status) + ")"
return f"{self.xec[status]} ({hex(status)})"
if status in self.lec:
return self.lec[status] + " (" + hex(status) + ")"
return "Unknown: " + hex(status)
return f"{self.lec[status]} ({hex(status)})"
return f"Unknown: {hex(status)}"

View file

@ -328,9 +328,8 @@ class gpt(metaclass=LogBase):
def print_gptfile(self, filename):
try:
filesize = os.stat(filename).st_size
with open(filename, "rb") as rf:
size = min(32 * 4096, filesize)
size = min(32 * 4096, os.stat(filename).st_size)
data = rf.read(size)
for sectorsize in [512, 4096]:
result = self.parse(data, sectorsize)

View file

@ -59,7 +59,7 @@ class Mtk(metaclass=LogBase):
idx = -1
else:
data[idx:idx + len(patchval)] = patchval
self.info(f"Patched \"{patchval[2]}\" in preloader")
self.info(f'Patched "{patchval[2]}" in preloader')
patched = True
else:
pattern = bytes.fromhex(patchval[0])
@ -67,7 +67,7 @@ class Mtk(metaclass=LogBase):
if idx != -1:
patch = bytes.fromhex(patchval[1])
data[idx:idx + len(patch)] = patch
self.info(f"Patched \"{patchval[2]}\" in preloader")
self.info(f'Patched "{patchval[2]}" in preloader')
patched = True
# break
i += 1
@ -101,7 +101,7 @@ class Mtk(metaclass=LogBase):
if idx != -1:
patch = bytes.fromhex(patchval[1])
data[idx:idx + len(patch)] = patch
self.info(f"Patched \"{patchval[2]}\" in preloader")
self.info(f'Patched "{patchval[2]}" in preloader')
patched = True
# break
i += 1

View file

@ -166,7 +166,8 @@ class Main(metaclass=LogBase):
if not os.path.exists("logs"):
os.mkdir("logs")
def close(self):
@staticmethod
def close():
sys.exit(0)
def cmd_stage(self, mtk, filename, stage2addr, stage2file, verifystage2):
@ -561,7 +562,7 @@ class Main(metaclass=LogBase):
for pos in range(offset, offset + length, rlen):
print("Reading pos %08X" % pos)
res = mtk.preloader.read32(pos, rlen // 4)
if res == []:
if not res:
break
print(hexlify(b"".join([pack("<I", val) for val in res])).decode('utf-8'))
@ -665,7 +666,7 @@ class Main(metaclass=LogBase):
if logs != b"":
with open(filename, "wb") as wf:
wf.write(logs)
self.info(f"Successfully wrote logs to \"{filename}\"")
self.info(f'Successfully wrote logs to "{filename}"')
else:
self.info("No logs found.")

View file

@ -1311,7 +1311,8 @@ class Preloader(metaclass=LogBase):
self.config.is_brom = False
return b""
def prepare_data(self, data, sigdata=b"", maxsize=0):
@staticmethod
def prepare_data(data, sigdata=b"", maxsize=0):
gen_chksum = 0
data = (data[:maxsize] + sigdata)
if len(data + sigdata) % 2 != 0:

View file

@ -61,7 +61,7 @@ class Partition(metaclass=LogBase):
pm.sectors = partinfo.size // self.config.pagesize
pm.type = 1
pm.flags = partinfo.mask_flags
partitions.add(pm)
partitions.append(pm)
return data, partitions
return b"", None
@ -116,7 +116,7 @@ class Partition(metaclass=LogBase):
return data, guid_gpt
def get_backup_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba,
parttype="user") -> bytearray:
parttype="user") -> bytes:
data = self.readflash(addr=0, length=2 * self.config.pagesize, filename="", parttype=parttype, display=False)
if data == b"":
return data

View file

@ -76,7 +76,7 @@ class PLTools(metaclass=LogBase):
ack = self.exploit.runpayload(payload, ack, addr, dontack)
if ack == ack:
self.info("Successfully sent payload: " + filename)
self.info(f"Successfully sent payload: {filename}")
self.mtk.daloader.patch = True
return True
elif ack == b"\xc1\xc2\xc3\xc4":
@ -87,20 +87,20 @@ class PLTools(metaclass=LogBase):
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
for pos in range(0, 0x40000, 64):
wf.write(self.mtk.port.usbread(64))
self.info("Preloader dumped as: " + "preloader.bin")
self.info("Preloader dumped as: preloader.bin")
return True
else:
with open("out.bin", 'wb') as wf:
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
for pos in range(0, 0x20000, 64):
wf.write(self.mtk.port.usbread(64))
self.info("Bootrom dumped as: " + "out.bin")
self.info("Bootrom dumped as: out.bin")
return True
self.error("Error on sending payload: " + filename)
self.error(f"Error on sending payload: {filename}")
return False
else:
self.error("Error on sending payload: " + filename)
self.error("Error, payload answered instead: " + hexlify(ack).decode('utf-8'))
self.error(f"Error on sending payload: {filename}")
self.error(f"Error, payload answered instead: {hexlify(ack).decode('utf-8')}")
return False
def runbrute(self, args):
@ -138,16 +138,16 @@ class PLTools(metaclass=LogBase):
self.info("Kamakiri / DA Run")
if self.runpayload(filename=pfilename, ack=0xC1C2C3C4, offset=0):
if self.exploit.dump_brom(filename):
self.info("Dumped as: " + filename)
self.info(f"Dumped as:{filename} ")
return True
else:
self.error("Error on sending payload: " + filename)
self.error(f"Error on sending payload: {filename}")
else:
if self.exploit.dump_brom(filename, length=length):
self.info("Dumped as: " + filename)
self.info(f"Dumped as: {filename}")
return True
else:
self.error("Error on sending payload: " + pfilename)
self.error(f"Error on sending payload: {pfilename}")
return False
def run_dump_preloader(self, filename):
@ -158,11 +158,11 @@ class PLTools(metaclass=LogBase):
data, filename = self.exploit.dump_preloader()
return data, filename
else:
self.error("Error on sending payload: " + pfilename)
self.error(f"Error on sending payload: {pfilename}")
return None, None
else:
if self.exploit.dump_brom(filename):
self.info("Preloader dumped as: " + filename)
self.info(f"Preloader dumped as: {filename}")
return True
else:
self.error("Error on dumping preloader")

View file

@ -1,21 +1,22 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2023
import sys
import codecs
import copy
import datetime as dt
import io
import logging
import logging.config
import codecs
import struct
import os
import shutil
import stat
import colorama
import copy
import struct
import sys
import time
import io
import datetime as dt
from struct import unpack, pack
from io import BytesIO
from struct import unpack, pack
import colorama
try:
from capstone import Cs, CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN
@ -154,10 +155,11 @@ class progress:
else:
self.guiprogress = None
def calcProcessTime(self, starttime, cur_iter, max_iter):
@staticmethod
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
if telapsed > 0 and cur_iter > 0:
testimated = (telapsed / cur_iter) * (max_iter)
testimated = (telapsed / cur_iter) * max_iter
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated - telapsed # in seconds
@ -207,21 +209,22 @@ class progress:
if lefttime > 0:
sec = lefttime
if sec > 60:
min = sec // 60
minutes = sec // 60
sec = sec % 60
if min > 60:
h = min // 24
min = min % 24
hinfo = "%02dh:%02dm:%02ds left" % (h, min, sec)
if minutes > 60:
h = minutes // 24
minutes = minutes % 24
hinfo = "%02dh:%02dm:%02ds left" % (h, minutes, sec)
else:
hinfo = "%02dm:%02ds left" % (min, sec)
hinfo = "%02dm:%02ds left" % (minutes, sec)
else:
hinfo = "%02ds left" % sec
print_progress(prog, 100, prefix='Progress:',
suffix=prefix + f' (Sector 0x%X of 0x%X, {hinfo}) %0.2f MB/s' % (pos // self.pagesize,
total // self.pagesize,
throughput), bar_length=50)
throughput),
bar_length=50)
self.prog = prog
self.progpos = pos
self.progtime = t0
@ -301,7 +304,7 @@ def do_tcp_server(client, arguments, handler):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = int(arguments.tcpport)
server_address = ('localhost', port)
print('starting up on %s port %s' % server_address)
print(f'starting up on {server_address[0]} port {port}')
sock.bind(server_address)
sock.listen(1)
response = None
@ -314,24 +317,20 @@ def do_tcp_server(client, arguments, handler):
data = connection.recv(4096).decode('utf-8')
if data == '':
break
print('received %s' % data)
print(f'received {data}')
if data:
print('handling request')
lines = data.split("\n")
for line in lines:
if ":" in line:
cmd = line.split(":")[0]
marguments = line.split(":")[1]
try:
opts = parse_args(cmd, marguments, arguments)
opts = parse_args(cmd, line.split(":")[1], arguments)
except Exception:
response = "Wrong arguments\n<NAK>\n"
opts = None
if opts is not None:
if handler(cmd, opts):
response = "<ACK>\n"
else:
response = "<NAK>\n"
response = "<ACK>\n" if handler(cmd, opts) else "<NAK>\n"
connection.sendall(bytes(response, 'utf-8'))
finally:
connection.close()
@ -339,11 +338,7 @@ def do_tcp_server(client, arguments, handler):
def parse_args(cmd, args, mainargs):
options = {}
opts = None
if "," in args:
opts = args.split(",")
else:
opts = [args]
opts = args.split(",") if "," in args else [args]
for arg in mainargs:
if "--" in arg:
options[arg] = mainargs[arg]
@ -488,8 +483,8 @@ class LogBase(type):
def __init__(cls, *args):
super().__init__(*args)
logger_attribute_name = '_' + cls.__name__ + '__logger'
logger_debuglevel_name = '_' + cls.__name__ + '__debuglevel'
logger_attribute_name = f'_{cls.__name__}__logger'
logger_debuglevel_name = f'_{cls.__name__}__debuglevel'
logger_name = '.'.join([c.__name__ for c in cls.mro()[-2::-1]])
LOG_CONFIG = {
"version": 1,
@ -603,7 +598,7 @@ class elf:
elif self.elfclass == 2: # 64Bit
start = 0x34
else:
print("Error on parsing " + self.filename)
print(f"Error on parsing {self.filename}")
return ['', '']
elfheadersize, programheaderentrysize, programheaderentrycount = struct.unpack("<HHH",
self.data[start:start + 3 * 2])
@ -625,7 +620,8 @@ class patchtools:
def __init__(self, bdebug=False):
self.bDebug = bdebug
def has_bad_uart_chars(self, data):
@staticmethod
def has_bad_uart_chars(data):
badchars = [b'\x00', b'\n', b'\r', b'\x08', b'\x7f', b'\x20', b'\x09']
for idx, c in enumerate(data):
c = bytes([c])
@ -642,7 +638,7 @@ class patchtools:
badchars = self.has_bad_uart_chars(data)
if not badchars:
badchars = self.has_bad_uart_chars(data2)
if not (badchars):
if not badchars:
return div
div += 4
@ -665,19 +661,17 @@ class patchtools:
abase = ((offset + div) & 0xFFFF0000) >> 16
a = ((offset + div) & 0xFFFF)
strasm = ""
strasm += f"# {hex(offset)}\n"
strasm += f"mov {reg}, #{hex(a)};\n"
strasm += f"movk {reg}, #{hex(abase)}, LSL#16;\n"
if div > 0:
strasm += "# " + hex(offset) + "\n"
strasm += "mov " + reg + ", #" + hex(a) + ";\n"
strasm += "movk " + reg + ", #" + hex(abase) + ", LSL#16;\n"
strasm += "sub " + reg + ", " + reg + ", #" + hex(div) + ";\n"
strasm += f"sub {reg}, {reg}, #{hex(div)};\n"
else:
strasm += "# " + hex(offset) + "\n"
strasm += "mov " + reg + ", #" + hex(a) + ";\n"
strasm += "movk " + reg + ", #" + hex(abase) + ", LSL#16;\n"
strasm += "add " + reg + ", " + reg + ", #" + hex(-div) + ";\n"
strasm += f"add {reg}, {reg}, #{hex(-div)};\n"
return strasm
def uart_valid_sc(self, sc):
@staticmethod
def uart_valid_sc(sc):
badchars = [b'\x00', b'\n', b'\r', b'\x08', b'\x7f', b'\x20', b'\x09']
for idx, c in enumerate(sc):
c = bytes([c])
@ -687,12 +681,11 @@ class patchtools:
return False
return True
def disasm(self, code, size):
@staticmethod
def disasm(code, size):
cs = Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
instr = []
for i in cs.disasm(code, size):
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
instr.append("%s\t%s" % (i.mnemonic, i.op_str))
instr = [f"{i.mnemonic}\t{i.op_str}" for i in cs.disasm(code, size)]
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
return instr
def assembler(self, code):
@ -735,7 +728,8 @@ class patchtools:
return out
def find_binary(self, data, strf, pos=0):
@staticmethod
def find_binary(data, strf, pos=0):
t = strf.split(b".")
pre = 0
offsets = []
@ -752,7 +746,7 @@ class patchtools:
continue
rt += 1
prep = data[rt:].find(t[i])
if (prep != 0):
if prep != 0:
error = 1
break
rt += len(t[i])
@ -766,7 +760,7 @@ class patchtools:
return None
def read_object(data: object, definition: object) -> object:
def read_object(data: object, definition) -> dict:
"""
Unpacks a structure using the given data and definition.
"""
@ -820,7 +814,7 @@ def print_progress(iteration, total, prefix='', suffix='', decimals=1, bar_lengt
filled_length = int(round(bar_length * iteration / float(total)))
bar = '' * filled_length + '-' * (bar_length - filled_length)
sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix))
sys.stdout.write(f'\r{prefix} |{bar}| {percents}% {suffix}')
if iteration == total:
sys.stdout.write('\n')

View file

@ -48,7 +48,7 @@ def ldr_lit(curpc, instr):
def ldr_imm(instr):
simm5 = (instr >> 6) & 0x1F
sRt = (instr) & 0x7
sRt = instr & 0x7
sRn = (instr >> 3) & 0x7
return simm5, sRt, sRn
@ -59,28 +59,27 @@ def main():
sys.exit(0)
with open(sys.argv[1], "rb") as rf:
print()
print("Using : " + sys.argv[1])
print(f"Using : {sys.argv[1]}")
data = rf.read()
base = 0
mpos = find_binary(data, b"\xA0\x0A\x50\x05.\x00\x00\x00", 0)
usbdl_get_dword=None
usbdl_put_dword=None
usbdl_put_word=None
usbdl_get_dword = None
usbdl_put_dword = None
if mpos is not None:
usbdl_put_data = unpack("<I", data[mpos - 0xC:mpos - 0xC + 4])[0]
base = (((usbdl_put_data >> 16) & 0xFFFFF)<<16)
base = (((usbdl_put_data >> 16) & 0xFFFFF) << 16)
usbdl_get_data = unpack("<I", data[mpos - 0x10:mpos - 0x10 + 4])[0]
usbdl_put_dword = unpack("<I", data[mpos - 0x14:mpos - 0x14 + 4])[0]
usbdl_get_dword = unpack("<I", data[mpos - 0x18:mpos - 0x18 + 4])[0]
usbdl_put_word = unpack("<I", data[mpos - 0x1C:mpos - 0x1C + 4])[0]
else:
usbdl_get_data = find_binary(data,"2DE9F04780460F46")
usbdl_put_data = find_binary(data,"10B5064AD4689368")
usbdl_get_data = find_binary(data, "2DE9F04780460F46")
usbdl_put_data = find_binary(data, "10B5064AD4689368")
usbdl_put_word = find_binary(data, b"\x2D\xE9\xF8\x4F\x80\x46\x8a\x46.\x48")
usbdl_ptr = None
if usbdl_put_word:
mpos=(usbdl_put_word&0xFFFFF)+7
mpos = (usbdl_put_word & 0xFFFFF) + 7
offset, Rn = ldr_lit(mpos,
unpack("<H", data[mpos:mpos + 2])[0])
usbdl_ptr = (base | offset)
@ -96,82 +95,82 @@ def main():
pos -= 0x4
if pos is not None:
pos += 1
send_usb_response=base|pos
send_usb_response = base | pos
pos = find_binary(data, b"\x10\xB5.\xF0...\x46", 0)
if pos is None:
pos = find_binary(data, b"\xB5.\xF0...\x49", 0)
if pos is not None:
pos-=1
pos -= 1
else:
pos2 = find_binary(data, "46FFF7", pos + 8)
if pos2 != None:
if pos2 is not None:
if pos2 - pos < 0x20:
pos = pos
else:
pos = pos2 - 1
posr = -1
startpos = 0
while posr != None:
while posr is not None:
posr = find_binary(data, "2DE9F047", startpos)
if posr == None:
if posr is None:
break
if data[posr + 7] == 0x46 and data[posr + 8] == 0x92:
break
startpos = posr + 2
pattern = b"\xB5.\xF0"
sla=None
sla = None
if pos is not None:
sbcpos = pos
print("sbc:\t\t\t\t\t\t0x%08X" % (base|pos))
print("sbc:\t\t\t\t\t\t0x%08X" % (base | pos))
pos = find_binary(data, pattern, pos + 8)
if pos is not None:
pos -= 1
print("sla:\t\t\t\t\t\t0x%08X" % (base|pos))
sla=pos
print("sla:\t\t\t\t\t\t0x%08X" % (base | pos))
sla = pos
if pos is not None:
pos = find_binary(data, pattern, ((base|pos) + 2))
pos = find_binary(data, pattern, ((base | pos) + 2))
if pos is not None:
pos -= 1
print("daa:\t\t\t\t\t\t0x%08X" % (base|pos))
sec_mode=None
sec_sbc=None
print("daa:\t\t\t\t\t\t0x%08X" % (base | pos))
sec_mode = None
sec_sbc = None
if sla is not None:
if data[sla+9]&0xF0==0x60:
if data[sla + 9] & 0xF0 == 0x60:
offset, Rn = ldr_lit(sla + 6,
unpack("<H", data[sla + 6:sla + 6 + 2])[0])
sec_sbc=unpack("<I",data[offset:offset+4])[0]
if data[sla+8]==0x51:
sec_sbc+=4
sec_mode=0
sec_sbc = unpack("<I", data[offset:offset + 4])[0]
if data[sla + 8] == 0x51:
sec_sbc += 4
sec_mode = 0
else:
mpos = find_binary(data, "48C16809B1", 0)
if mpos is not None:
mpos-=1
mpos -= 1
sec_mode = 1
offset, Rn = ldr_lit(mpos,
unpack("<H", data[mpos:mpos+2])[0])
rbase=unpack("<I",data[offset:offset+4])[0]
simm5, sRt, sRn = ldr_imm(unpack("<H", data[mpos+2:mpos + 4])[0])
sec_sbc = (rbase+(simm5*4))
instr=unpack("<H", data[sla+0x12:sla+0x12+2])[0]
offset, Rn = ldr_lit(sla+0x12,instr)
rbase=unpack("<I",data[offset:offset+4])[0]
simm5, sRt, sRn = ldr_imm(unpack("<H", data[sla+0x12+2:sla+0x12 + 4])[0])
unpack("<H", data[mpos:mpos + 2])[0])
rbase = unpack("<I", data[offset:offset + 4])[0]
simm5, sRt, sRn = ldr_imm(unpack("<H", data[mpos + 2:mpos + 4])[0])
sec_sbc = (rbase + (simm5 * 4))
instr = unpack("<H", data[sla + 0x12:sla + 0x12 + 2])[0]
offset, Rn = ldr_lit(sla + 0x12, instr)
rbase = unpack("<I", data[offset:offset + 4])[0]
simm5, sRt, sRn = ldr_imm(unpack("<H", data[sla + 0x12 + 2:sla + 0x12 + 4])[0])
sec_sla = (rbase + (simm5 * 4))
func_wdt=None
func_acm=None
func_wdt = None
func_acm = None
pos = find_binary(data, "70B50646A648", 0)
if pos is not None:
pos += 1
func_acm = base|pos
func_acm = base | pos
pos = find_binary(data, "0F4941F6", 0)
if pos is None:
pos = find_binary(data, "124941F6", 0)
if pos is not None:
pos += 1
func_wdt=base|pos
func_wdt = base | pos
pos = find_binary(data, "F8B50024", 0)
if pos is None:
@ -187,8 +186,8 @@ def main():
usb_buffer = unpack("<I", data[offset:offset + 4])[0]
break
vulnaddr=None
var1=None
vulnaddr = None
var1 = None
pos = find_binary(data, b"\xA1..\xD0\x21", 0)
if pos is not None:
for i in range(0, 0x100, 2):
@ -209,7 +208,8 @@ def main():
unpack("<H", data[vuln_ctrl_handler + i:vuln_ctrl_handler + i + 2])[0])
vulnaddr = unpack("<I", data[offset:offset + 4])[0]
if data[vuln_ctrl_handler + i + 1] == 0x6A and usb_buffer != 0:
simm5, sRt, sRn = ldr_imm(unpack("<H", data[vuln_ctrl_handler + i:vuln_ctrl_handler + i + 2])[0])
simm5, sRt, sRn = ldr_imm(
unpack("<H", data[vuln_ctrl_handler + i:vuln_ctrl_handler + i + 2])[0])
vulnoff = (simm5 * 4)
var1 = (usb_buffer - vulnaddr - vulnoff) / 0x34
if int(var1) != var1:
@ -225,19 +225,19 @@ def main():
pos = find_binary(data, b"\x10\xB5..\xF4.\x00\x21", 0)
if pos is not None:
pos += 1
cmd_handler=base|pos
cmd_handler = base | pos
uart_info = None
pos = find_binary(data, "10B5114A")
if pos is not None:
uart_info=pos
uart_info = pos
uart_addr = None
pos = find_binary(data, "315F454E930F0E00")
if pos is None:
pos = find_binary(data, "0070315F454E00")
if pos is not None:
pos+=6
pos += 6
uart_addr = unpack("<I", data[pos:pos + 4])[0]
else:
pos += 8
@ -266,8 +266,8 @@ def main():
pos += 8
instr = unpack("<H", data[pos:pos + 2])[0]
offset, Rn = ldr_lit(pos, instr)
blacklist_ptr = unpack("<I", data[offset:offset + 4])[0]&0xFFFFF
blacklist = unpack("<I", data[blacklist_ptr-4:blacklist_ptr-4 + 4])[0]
blacklist_ptr = unpack("<I", data[offset:offset + 4])[0] & 0xFFFFF
blacklist = unpack("<I", data[blacklist_ptr - 4:blacklist_ptr - 4 + 4])[0]
else:
pos += 10
else:
@ -282,16 +282,16 @@ def main():
pos = find_binary(data, b"\x02\x4A\x02\x60")
if pos is not None:
pos += 4
blacklistcount = unpack("<H", data[pos:pos + 2])[0]&0xF
blacklistcount = unpack("<H", data[pos:pos + 2])[0] & 0xF
blacklist2 = None
pos = find_binary(data, b"\x10\xB5..\xD2\xF8\x90\x30\x10\x32")
if pos is not None:
pos+=2
pos += 2
instr = unpack("<H", data[pos:pos + 2])[0]
offset, Rn = ldr_lit(pos, instr)
bl2 = unpack("<I", data[offset:offset + 4])[0]
blacklist2 = bl2+0x90
blacklist2 = bl2 + 0x90
pos = 0
memread = None
@ -314,14 +314,13 @@ def main():
payload_addr = unpack("<I", data[pos:pos + 4])[0]
break
coffs=(usbdl_put_data&0xFFFFF)+1
coffs = (usbdl_put_data & 0xFFFFF) + 1
try:
offset, Rn = ldr_lit(coffs,
unpack("<H", data[coffs:coffs + 2])[0])
unpack("<H", data[coffs:coffs + 2])[0])
except:
print("Err:"+sys.argv[1])
send_ptr_offset=offset
send_ptr=unpack("<I",data[offset:offset+4])[0]+8
print("Err:" + sys.argv[1])
send_ptr = unpack("<I", data[offset:offset + 4])[0] + 8
send_ptr_offset = base | offset
ctrl_addr = None
pos = find_binary(data, "41434D2043")
@ -329,7 +328,6 @@ def main():
pos -= 0x10
ctrl_addr = unpack("<I", data[pos:pos + 4])[0]
socid_addr = None
pos = find_binary(data, "10B501212020FF")
if pos is not None:
@ -346,18 +344,18 @@ def main():
offset, Rn = ldr_lit(pos, instr)
meid_addr = unpack("<I", data[offset:offset + 4])[0]
brom_register_access=None
brom_register_access_ptr=None
brom_register_access = None
brom_register_access_ptr = None
pos2 = find_binary(data, "2DE9F04100244FF001")
if pos2 is not None:
brom_register_access = base|pos2
brom_register_access = base | pos2
pos = find_binary(data, b"\xA9\x07.\x48", pos2)
if pos is not None:
pos += 2
instr = unpack("<H", data[pos:pos + 2])[0]
offset, Rn = ldr_lit(pos, instr)
brom_register_access_ptr=base|pos2
brom_register_access_ptr_offset=base|offset
brom_register_access_ptr = base | pos2
brom_register_access_ptr_offset = base | offset
else:
pos = find_binary(data, "194D1B49", pos2)
if pos is not None:
@ -379,7 +377,7 @@ def main():
print("*sec_mode:\t\t\t\t\t0x%08X" % sec_mode)
if sec_sbc:
print("*sec_sbc:\t\t\t\t\t0x%08X" % sec_sbc)
if sec_mode==1:
if sec_mode == 1:
print("*sec_sla:\t\t\t\t\t0x%08X" % sec_sla)
print("*func_usb_buffer:\t\t\t0x%08X" % (func_usb_buffer + 1 | base))
print("usb_buffer:\t\t\t\t\t0x%08X" % usb_buffer)
@ -394,7 +392,7 @@ def main():
if usbdl_ptr:
print("usbdl_ptr:\t\t\t\t\t\t0x%08X" % usbdl_ptr)
else:
print("Uhoh: "+sys.argv[1])
print("Uhoh: " + sys.argv[1])
if memread:
print("memread:\t\t\t\t\t0x%08X" % memread)
if payload_addr:
@ -422,26 +420,27 @@ def main():
if cmd_handler:
print("*cmd_handler:\t\t\t\t0x%08X" % cmd_handler)
if brom_register_access_ptr:
print(f"brom_register_access_ptr:\t\t\t\t\t({hex(brom_register_access_ptr)},{hex(brom_register_access_ptr_offset)}),")
print(
f"brom_register_access_ptr:\t\t\t\t\t({hex(brom_register_access_ptr)},{hex(brom_register_access_ptr_offset)}),")
if meid_addr:
print(f"meid_addr:\t\t\t\t\t{hex(meid_addr)}")
if socid_addr:
print(f"socid_addr:\t\t\t\t\t{hex(socid_addr)}")
print("da_range:\t\t\t\t\t0x%08X" % offset)
if sec_mode==1:
sec_offset=0x28
if sec_mode == 1:
sec_offset = 0x28
else:
sec_offset=0x40
sec_sla=0
sec_offset = 0x40
sec_sla = 0
if blacklist2 is None:
blacklist2 = 0
import os
socname=os.path.basename(sys.argv[1]).replace(".bin","")[:6]
socname = os.path.basename(sys.argv[1]).replace(".bin", "")[:6]
try:
if usbdl_ptr:
header =f"""
header = f"""
#include <inttypes.h>
#define PAYLOAD_2_0
char SOC_NAME[] = "{socname}";
@ -455,7 +454,7 @@ volatile uint32_t **SEC_REG2=(volatile uint32_t **){hex(sec_sla)};
volatile uint32_t SEC_OFFSET={hex(sec_offset)};
volatile uint32_t *bladdr=(volatile uint32_t *){hex(blacklist)};
volatile uint32_t *bladdr2=(volatile uint32_t *){hex(blacklist2)};
volatile uint32_t *uart_reg0 = (volatile uint32_t*){hex(uart_addr+0x14)};
volatile uint32_t *uart_reg0 = (volatile uint32_t*){hex(uart_addr + 0x14)};
volatile uint32_t *uart_reg1 = (volatile uint32_t*){hex(uart_addr)};
int (*cmd_handler)() = (void*){hex(cmd_handler)};
@ -464,9 +463,10 @@ int (*cmd_handler)() = (void*){hex(cmd_handler)};
print(header)
if not os.path.exists("headers"):
os.mkdir("headers")
open(os.path.join("headers",socname+".h"),"w").write(header)
open(os.path.join("headers", socname + ".h"), "w").write(header)
except:
print(sys.argv[1])
if __name__ == "__main__":
main()

View file

@ -6,6 +6,7 @@ from struct import unpack
from mtkclient.config.payloads import pathconfig
from mtkclient.Library.utils import read_object
from mtkclient.Library.utils import find_binary
entry_region = [
('m_buf', 'I'),
('m_len', 'I'),
@ -27,7 +28,8 @@ DA = [
# vector<entry_region> LoadRegion
]
efusedb={}
efusedb = {}
def main():
da_setup = []
@ -54,7 +56,8 @@ def main():
da.append(entry_tmp)
da_setup.append(da)
print(f"Loader: {os.path.basename(loader)}")
dadb[da[0]["hw_code"]]=[("da_payload_addr",da[2]["m_start_addr"]),("pl_payload_addr", da[3]["m_start_addr"])]
dadb[da[0]["hw_code"]] = [("da_payload_addr", da[2]["m_start_addr"]),
("pl_payload_addr", da[3]["m_start_addr"])]
print("hwcode: 0x%04X" % da[0]["hw_code"])
print("hw_sub_code: 0x%04X" % da[0]["hw_sub_code"])
print("hw_version: 0x%04X" % da[0]["hw_version"])
@ -62,56 +65,60 @@ def main():
print("Reserved1: 0x%04X" % da[0]["reserved1"])
print("Reserved3: 0x%04X" % da[0]["reserved3"])
for i in range(da[0]["entry_region_count"]):
entry=da[i+1]
print(f"\t{i}: "+hex(entry['m_start_addr']))
mbuf=da[3]["m_buf"]
m_len=da[3]["m_len"]
startaddr=da[3]["m_start_addr"]
with open(loader,"rb") as rf:
entry = da[i + 1]
print(f"\t{i}: {hex(entry['m_start_addr'])}")
mbuf = da[3]["m_buf"]
m_len = da[3]["m_len"]
startaddr = da[3]["m_start_addr"]
with open(loader, "rb") as rf:
rf.seek(mbuf)
da2data=rf.read(m_len)
fname=os.path.join("loaders",hex(da[0]["hw_code"])[2:]+"_"+hex(startaddr)[2:]+os.path.basename(loader))
open(fname,"wb").write(da2data)
mbuf=da[2]["m_buf"]
m_len=da[2]["m_len"]
startaddr=da[2]["m_start_addr"]
da2data = rf.read(m_len)
fname = os.path.join("loaders",
hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename(
loader))
open(fname, "wb").write(da2data)
mbuf = da[2]["m_buf"]
m_len = da[2]["m_len"]
startaddr = da[2]["m_start_addr"]
sys.stdout.flush()
with open(loader,"rb") as rf:
with open(loader, "rb") as rf:
rf.seek(mbuf)
data=rf.read(m_len)
hashidx=data.find(int.to_bytes(0xC0070004,4,'little'))
if hashidx!=-1:
data = rf.read(m_len)
hashidx = data.find(int.to_bytes(0xC0070004, 4, 'little'))
if hashidx != -1:
print("Hash check found.")
else:
hashidx = data.find(b"\xCC\xF2\x07\x09") # => b"\x4F\xF0\x00\x09""
hashidx = data.find(b"\xCC\xF2\x07\x09") # => b"\x4F\xF0\x00\x09""
if hashidx != -1:
print("Hash check 2 found.")
else:
hashidx = find_binary(data,b"\x14\x2C\xF6.\xFE\xE7") # => b"\x14\x2C\xF6\xD1\x00\x00"
hashidx = find_binary(data, b"\x14\x2C\xF6.\xFE\xE7") # => b"\x14\x2C\xF6\xD1\x00\x00"
if hashidx is not None:
print("Hash check 3 found.")
else:
print("HASH ERROR !!!!")
fname=os.path.join("loaders",hex(da[0]["hw_code"])[2:]+"_"+hex(startaddr)[2:]+os.path.basename(loader))
open(fname,"wb").write(data)
fname = os.path.join("loaders",
hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename(
loader))
open(fname, "wb").write(data)
print(f"Offset: {hex(mbuf)}")
print(f"Length: {hex(m_len)}")
print(f"Addr: {hex(startaddr)}")
bootldr.seek(da[2]["m_buf"])
tt=bootldr.read(da[2]["m_len"])
tt = bootldr.read(da[2]["m_len"])
idx = tt.find(bytes.fromhex("70BB442D27D244A7"))
#idx = tt.find(bytes.fromhex("01279360D36013615361"))
if idx!=-1:
if idx != -1:
print("V3 Enabled")
bootldr.seek(da[3]["m_buf"])
tt=bootldr.read(da[3]["m_len"])
tt = bootldr.read(da[3]["m_len"])
idx2 = tt.find(bytes.fromhex("03 29 0D D9 07 4B 1B 68 03 60"))
if idx2!=-1:
efusedb[da[0]["hw_code"]]=hex(int.from_bytes(tt[idx2+0x24:idx2+0x28],'little')&0xFFFFF000)
if idx2 != -1:
efusedb[da[0]["hw_code"]] = hex(int.from_bytes(tt[idx2 + 0x24:idx2 + 0x28], 'little') & 0xFFFFF000)
else:
if not da[0]["hw_code"] in efusedb:
efusedb[da[0]["hw_code"]]="None"
efusedb[da[0]["hw_code"]] = "None"
print()
sorted_dict = dict(sorted(efusedb.items()))
@ -135,5 +142,6 @@ def main():
print(str(idx)+" "+name+": "+hex(fields[2]))
"""
if __name__=="__main__":
main()
if __name__ == "__main__":
main()

View file

@ -1,2 +1,2 @@
#!/bin/bash
for i in `find ./bootrom -name "*.bin"|sort`;do ./mtkclient/Tools/brom_to_offs $i;done
for i in $(find ./bootrom -name "*.bin"|sort);do ./mtkclient/Tools/brom_to_offs "$i";done

View file

@ -334,7 +334,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
elif address == 0x11020000:
r0 = uc.reg_read(UC_ARM_REG_R0)
if r0 == 0xa:
print("UART: " + buffer.decode('utf-8'))
print(f"UART: {buffer.decode('utf-8')}")
data += buffer.decode('utf-8')
buffer = bytearray()
else:
@ -343,7 +343,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
elif address == 0x11050000:
r0 = uc.reg_read(UC_ARM_REG_R0)
if r0 == 0xd:
print("UART: " + buffer.decode('utf-8'))
print(f"UART: {buffer.decode('utf-8')}")
data += buffer.decode('utf-8')
buffer = bytearray()
else:
@ -352,7 +352,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
elif address == 0x11002000:
r0 = uc.reg_read(UC_ARM_REG_R0)
if r0 == 0xa:
print("UART: " + buffer.decode('utf-8'))
print(f"UART: {buffer.decode('utf-8')}")
data += buffer.decode('utf-8')
buffer = bytearray()
else:
@ -361,7 +361,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
elif address == 0x11003000:
r0 = uc.reg_read(UC_ARM_REG_R0)
if r0 == 0xa:
print("UART: " + buffer.decode('utf-8'))
print(f"UART: {buffer.decode('utf-8')}")
data += buffer.decode('utf-8')
buffer = bytearray()
else:
@ -370,7 +370,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
elif address == 0x11005000:
r0 = uc.reg_read(UC_ARM_REG_R0)
if r0 == 0xa:
print("UART: " + buffer.decode('utf-8'))
print(f"UART: {buffer.decode('utf-8')}")
data += buffer.decode('utf-8')
buffer = bytearray()
else:
@ -389,61 +389,61 @@ def hook_code(uc, access, address, size):
keyslot0 = uc.mem_read(0x701953CC, 0x20)
keyslot1 = uc.mem_read(0x701953EC, 0x20)
keyslot2 = uc.mem_read(0x7019540C, 0x20)
print("Keyslot0: " + hexlify(keyslot0).decode('utf-8'))
print("Keyslot1: " + hexlify(keyslot1).decode('utf-8'))
print("Keyslot2: " + hexlify(keyslot2).decode('utf-8'))
print(f"Keyslot0: {hexlify(keyslot0).decode('utf-8')}")
print(f"Keyslot1: {hexlify(keyslot1).decode('utf-8')}")
print(f"Keyslot2: {hexlify(keyslot2).decode('utf-8')}")
elif pc == 0x70094A5C: # sha256_write
lr = uc.reg_read(UC_ARM_REG_LR)
r1 = uc.reg_read(UC_ARM_REG_R1)
r2 = uc.reg_read(UC_ARM_REG_R2)
s1 = uc.mem_read(r1, r2)
print("sha256_write")
print("lr: " + hex(lr))
print(f"r1: {hex(r1)} " + hexlify(s1).decode('utf-8'))
print("r2: " + hex(r2) + "\n")
print(f"lr: {hex(lr)}")
print(f"r1: {hex(r1)} {hexlify(s1).decode('utf-8')}")
print(f"r2: {hex(r2)}\n")
elif pc == 0x70094E3C: # kdflib_get_huk
lr = uc.reg_read(UC_ARM_REG_LR)
r0 = uc.reg_read(UC_ARM_REG_R0)
print("kdflib_get_huk")
print("klr: " + hex(lr))
print("kr0: " + hex(r0))
print(f"klr: {hex(lr)}")
print(f"kr0: {hex(r0)}")
elif pc == 0x70095240:
lr = uc.reg_read(UC_ARM_REG_LR)
r0 = uc.reg_read(UC_ARM_REG_R0)
r4 = uc.reg_read(UC_ARM_REG_R4)
print("hmac_sha256")
print("hlr: " + hex(lr))
print("hr0: " + hex(r0))
print("hr4: " + hex(r4))
print(f"hlr: {hex(lr)}")
print(f"hr0: {hex(r0)}")
print(f"hr4: {hex(r4)}")
elif pc == 0x70087430: # memcpy
lr = uc.reg_read(UC_ARM_REG_LR)
r0 = uc.reg_read(UC_ARM_REG_R0)
r1 = uc.reg_read(UC_ARM_REG_R0)
r2 = uc.reg_read(UC_ARM_REG_R0)
print("memcpy")
print("lr: " + hex(lr))
print("r0: " + hex(r0))
print("r1: " + hex(r1))
print("r2: " + hex(r2))
print(f"lr: {hex(lr)}")
print(f"r0: {hex(r0)}")
print(f"r1: {hex(r1)}")
print(f"r2: {hex(r2)}")
elif pc == 0x70095084:
lr = uc.reg_read(UC_ARM_REG_LR)
print("hmac_init")
print("lr: " + hex(lr))
print(f"lr: {hex(lr)}")
elif pc == 0x70094CF8:
lr = uc.reg_read(UC_ARM_REG_LR)
r1 = uc.reg_read(UC_ARM_REG_R1)
debug = r1
print("sha_finish")
print("lr: " + hex(lr))
print("r1: " + hex(r1))
print(f"lr: {hex(lr)}")
print(f"r1: {hex(r1)}")
elif pc == 0x70094DB8:
lr = uc.reg_read(UC_ARM_REG_LR)
r1 = debug
s1 = uc.mem_read(r1, 0x20)
print("sha_finish2")
print("lr: " + hex(lr))
print("r1: " + hex(r1))
print("s1: " + hexlify(s1).decode('utf-8'))
print(f"lr: {hex(lr)}")
print(f"r1: {hex(r1)}")
print(f"s1: {hexlify(s1).decode('utf-8')}")
# print("PC %08X" % pc)
return True

View file

@ -96,18 +96,6 @@ class EraseFlashWindow(QObject):
thread.wait()
self.enableButtonsSignal.emit()
def eraseBoot2(self):
self.eraseFlash("boot2")
return
def erasePreloader(self):
self.eraseFlash("boot1")
return
def eraseRpmb(self):
self.eraseFlash("rpmb")
return
def erasePartitionAsync(self, toolkit, parameters):
self.parent.timeEst.init()
self.parent.timeEstTotal.init()

View file

@ -314,13 +314,13 @@ class Ui_MainWindow(object):
self.gridLayout_2 = QGridLayout(self.keytab)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.keytable = QTableWidget(self.keytab)
if (self.keytable.columnCount() < 2):
if self.keytable.columnCount() < 2:
self.keytable.setColumnCount(2)
__qtablewidgetitem = QTableWidgetItem()
self.keytable.setHorizontalHeaderItem(0, __qtablewidgetitem)
__qtablewidgetitem1 = QTableWidgetItem()
self.keytable.setHorizontalHeaderItem(1, __qtablewidgetitem1)
if (self.keytable.rowCount() < 7):
if self.keytable.rowCount() < 7:
self.keytable.setRowCount(7)
__qtablewidgetitem2 = QTableWidgetItem()
self.keytable.setVerticalHeaderItem(0, __qtablewidgetitem2)

View file

@ -10,14 +10,14 @@ from mtkclient.config.payloads import pathconfig
class TimeEstim:
def calcProcessTime(self, starttime, cur_iter, max_iter):
@staticmethod
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
if telapsed > 0 and cur_iter > 0:
testimated = (telapsed / cur_iter) * max_iter
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated - telapsed # in seconds
return int(telapsed), int(lefttime), finishtime
return int(telapsed), int(testimated - telapsed), finishtime
else:
return 0, 0, ""
@ -34,14 +34,14 @@ class TimeEstim:
if lefttime > 0:
sec = lefttime
if sec > 60:
min = sec // 60
minutes = sec // 60
sec = sec % 60
if min > 60:
h = min // 24
min = min % 24
hinfo = "%02dh:%02dm:%02ds" % (h, min, sec)
if minutes > 60:
h = minutes // 24
minutes = minutes % 24
hinfo = "%02dh:%02dm:%02ds" % (h, minutes, sec)
else:
hinfo = "%02dm:%02ds" % (min, sec)
hinfo = "%02dm:%02ds" % (minutes, sec)
else:
hinfo = "%02ds" % sec
@ -97,7 +97,7 @@ def convert_size(size_bytes):
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])
return f"{s} {size_name[i]}"
class asyncThread(QThread):
@ -116,7 +116,7 @@ class asyncThread(QThread):
self.function(self, self.parameters)
class FDialog():
class FDialog:
def __init__(self, parent):
pc = pathconfig()
self.parent = parent

View file

@ -9,3 +9,5 @@ mock >= 4.0.3
pyserial >= 3.5
flake8
fusepy
unicorn
capstone

240
stage2
View file

@ -17,6 +17,7 @@ from mtkclient.Library.Hardware.hwcrypto import crypto_setup, hwcrypto
from mtkclient.config.mtk_config import Mtk_Config
from mtkclient.config.usb_ids import default_ids
class Stage2(metaclass=LogBase):
def __init__(self, args, loglevel=logging.INFO):
self.__logger = self.__logger
@ -40,8 +41,8 @@ class Stage2(metaclass=LogBase):
self.__logger.setLevel(logging.INFO)
self.cdc = usb_class(portconfig=default_ids, loglevel=loglevel, devclass=10)
self.usbread=self.cdc.usbread
self.usbwrite=self.cdc.usbwrite
self.usbread = self.cdc.usbread
self.usbwrite = self.cdc.usbwrite
def preinit(self):
try:
@ -98,11 +99,10 @@ class Stage2(metaclass=LogBase):
return result
def cmd_C8(self, val) -> bool:
'Clear cache func'
"""Clear cache func"""
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x5000))
ack = self.usbread(4)
if ack == b"\xD0\xD0\xD0\xD0":
if self.usbread(4) == b"\xD0\xD0\xD0\xD0":
return True
return False
@ -115,8 +115,7 @@ class Stage2(metaclass=LogBase):
self.usbwrite(pack(">I", addr + (pos * 4)))
self.usbwrite(pack(">I", 4))
self.usbwrite(pack("<I", dwords[pos]))
ack = self.usbread(4)
if ack == b"\xD0\xD0\xD0\xD0":
if self.usbread(4) == b"\xD0\xD0\xD0\xD0":
continue
else:
return False
@ -130,7 +129,7 @@ class Stage2(metaclass=LogBase):
if self.cdc.connected:
self.cdc.close()
def readflash(self, type: int, start, length, display=False, filename: str = None):
def readflash(self, type_: int, start, length, display=False, filename: str = None):
if not self.emmc_inited:
self.init_emmc()
wf = None
@ -144,7 +143,7 @@ class Stage2(metaclass=LogBase):
# emmc_switch(1)
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x1002))
self.usbwrite(pack(">I", type))
self.usbwrite(pack(">I", type_))
# kick-wdt
# self.usbwrite(pack(">I", 0xf00dd00d))
@ -160,7 +159,7 @@ class Stage2(metaclass=LogBase):
self.usbwrite(pack(">I", sectors))
if display:
pg.show_progress(prefix="Progress:",pos=0,total=sectors)
pg.show_progress(prefix="Progress:", pos=0, total=sectors)
for sector in range(sectors):
tmp = self.usbread(0x200)
@ -183,14 +182,13 @@ class Stage2(metaclass=LogBase):
else:
return buffer[start % 0x200:(start % 0x200) + length]
def userdata(self, start=0, length=32*0x200, filename="data.bin"):
def userdata(self, start=0, length=32 * 0x200, filename="data.bin"):
sectors = 0
if length != 0:
sectors = (length // 0x200) + (1 if length % 0x200 else 0)
self.info("Reading user data...")
if self.cdc.connected:
self.readflash(type=0, start=start, length=length, display=True, filename=filename)
self.readflash(type_=0, start=start, length=length, display=True, filename=filename)
def preloader(self, start, length, filename):
sectors = 0
@ -201,7 +199,7 @@ class Stage2(metaclass=LogBase):
self.info("Reading preloader...")
if self.cdc.connected:
if sectors == 0:
buffer = self.readflash(type=1, start=0, length=0x4000, display=False)
buffer = self.readflash(type_=1, start=0, length=0x4000, display=False)
if len(buffer) != 0x4000:
print("Error on reading boot1 area.")
return
@ -212,7 +210,7 @@ class Stage2(metaclass=LogBase):
st = buffer[start:start + 4]
if st == b"MMM\x01":
length = unpack("<I", buffer[start + 0x20:start + 0x24])[0]
data = self.readflash(type=1, start=0, length=start + length, display=True)
data = self.readflash(type_=1, start=0, length=start + length, display=True)
if len(data) != start + length:
print("Warning, please rerun command, length doesn't match.")
idx = data.find(b"MTK_BLOADER_INFO")
@ -220,19 +218,19 @@ class Stage2(metaclass=LogBase):
filename = data[idx + 0x1B:idx + 0x3D].rstrip(b"\x00").decode('utf-8')
with open(os.path.join("logs", filename), "wb") as wf:
wf.write(data[start:start + length])
print("Done writing to " + os.path.join("logs", filename))
print(f"Done writing to {os.path.join('logs', filename)}")
with open(os.path.join("logs", "hdr_" + filename), "wb") as wf:
wf.write(data[:start])
print("Done writing to " + os.path.join("logs", "hdr_" + filename))
print(f"Done writing to {os.path.join('logs', 'hdr_' + filename)}")
return
else:
length = 0x40000
self.readflash(type=1, start=0, length=length, display=True, filename=filename)
self.readflash(type_=1, start=0, length=length, display=True, filename=filename)
print("Done")
print("Error on getting preloader info, aborting.")
else:
self.readflash(type=1, start=start, length=length, display=True, filename=filename)
self.readflash(type_=1, start=start, length=length, display=True, filename=filename)
print("Done")
def boot2(self, start, length, filename):
@ -244,10 +242,10 @@ class Stage2(metaclass=LogBase):
self.info("Reading boot2...")
if self.cdc.connected:
if sectors == 0:
self.readflash(type=2, start=0, length=0x40000, display=True, filename=filename)
self.readflash(type_=2, start=0, length=0x40000, display=True, filename=filename)
print("Done")
else:
self.readflash(type=1, start=start, length=length, display=True, filename=filename)
self.readflash(type_=1, start=start, length=length, display=True, filename=filename)
print("Done")
def memread(self, start, length, filename=None):
@ -269,7 +267,7 @@ class Stage2(metaclass=LogBase):
wf.write(self.usbread(size))
bytestoread -= size
pos += size
self.info(f"{hex(start)}: " + hexlify(data).decode('utf-8'))
self.info(f"{hex(start)}: {hexlify(data).decode('utf-8')}")
if filename is not None:
wf.close()
return data
@ -318,8 +316,8 @@ class Stage2(metaclass=LogBase):
start = 0
else:
start = (start // 0x100)
if start>0xFFFF:
start=0xFFFF
if start > 0xFFFF:
start = 0xFFFF
if length == 0:
sectors = 16 * 1024 * 1024 // 0x100
else:
@ -339,8 +337,8 @@ class Stage2(metaclass=LogBase):
bytestoread = sectors * 0x100
count = sectors
pg = progress(pagesize=0x200)
if sectors>0xFFFF:
count=0xFFFF
if sectors > 0xFFFF:
count = 0xFFFF
with open(filename, "wb") as wf:
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x2000))
@ -353,145 +351,135 @@ class Stage2(metaclass=LogBase):
if len(tmp) != 0x100:
self.error("Error on getting data")
return
pg.show_progress(prefix="Progress:",pos=sector,total=sectors)
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
bytesread += 0x100
size = min(bytestoread, len(tmp))
wf.write(tmp[:size])
bytestoread -= size
while bytestoread>0:
while bytestoread > 0:
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x2000))
self.usbwrite(pack(">H", sector+1))
self.usbwrite(pack(">H", sector + 1))
self.usbwrite(pack(">H", 1))
tmp = self.usbread(0x100)
size = min(bytestoread, len(tmp))
wf.write(tmp[:size])
bytestoread -= size
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
sector+=1
sector += 1
pg.show_progress(prefix="Progress:", pos=sectors, total=sectors)
print("Done")
def keys(self, data=b"", otp=None, mode="dxcc"):
# self.hwcrypto.disable_range_blacklist("cqdma",self.cmd_C8)
keyinfo=""
keyinfo = ""
retval = {}
meid = self.config.get_meid()
socid = self.config.get_socid()
if meid is not None:
self.info("MEID : " + hexlify(meid).decode('utf-8'))
self.info(f"MEID : {hexlify(meid).decode('utf-8')}")
else:
try:
if self.config.chipconfig.meid_addr is not None:
meid = self.memread(self.config.chipconfig.meid_addr, 16)
self.config.set_meid(meid)
self.info("MEID : " + hexlify(meid).decode('utf-8'))
self.info(f"MEID : {hexlify(meid).decode('utf-8')}")
retval["meid"] = hexlify(meid).decode('utf-8')
except Exception as err:
pass
if socid is not None:
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
self.info(f"SOCID : {hexlify(socid).decode('utf-8')}")
retval["socid"] = socid
else:
try:
if self.config.chipconfig.socid_addr is not None:
socid = self.memread(self.config.chipconfig.socid_addr, 32)
self.config.set_socid(socid)
self.info("SOCID : " + hexlify(socid).decode('utf-8'))
self.info(f"SOCID : {hexlify(socid).decode('utf-8')}")
retval["socid"] = hexlify(socid).decode('utf-8')
except Exception as err:
pass
if self.setup.dxcc_base is not None and mode not in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt","dxcc_sha256"]:
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="rpmb")
if self.setup.dxcc_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
"sej_sst_encrypt", "dxcc_sha256"]:
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb")
rpmb2key = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb2")
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="fde")
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="itrustee")
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="prov")
keyinfo+="\nKeys :\n-----------------------------------------\n"
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')+"\n"
keyinfo+="RPMB2: " + hexlify(rpmb2key).decode('utf-8') + "\n"
keyinfo+="FDE : " + hexlify(fdekey).decode('utf-8')+"\n"
keyinfo+="iTrustee: " + hexlify(ikey).decode('utf-8')+"\n"
keyinfo+="Platform: " + hexlify(platkey).decode('utf-8')+"\n"
keyinfo+="Provisioning: " + hexlify(provkey).decode('utf-8')+"\n"
keyinfo+="\n"
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="fde")
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="itrustee")
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="prov")
keyinfo += "\nKeys :\n-----------------------------------------\n"
keyinfo += f"RPMB: {hexlify(rpmbkey).decode('utf-8')}\n"
keyinfo += f"RPMB2: {hexlify(rpmb2key).decode('utf-8')}\n"
keyinfo += f"FDE : {hexlify(fdekey).decode('utf-8')}\n"
keyinfo += f"iTrustee: {hexlify(ikey).decode('utf-8')}\n"
keyinfo += f"Platform: {hexlify(platkey).decode('utf-8')}\n"
keyinfo += f"Provisioning: {hexlify(provkey).decode('utf-8')}\n"
keyinfo += "\n"
if rpmbkey is not None:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
self.config.hwparam.writesetting("rpmbkey",hexlify(rpmbkey).decode('utf-8'))
self.info(f"RPMB : {hexlify(rpmbkey).decode('utf-8')}")
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
if rpmb2key is not None:
self.info("RPMB2 : " + hexlify(rpmb2key).decode('utf-8'))
self.config.hwparam.writesetting("rpmb2key",hexlify(rpmb2key).decode('utf-8'))
self.info(f"RPMB2 : {hexlify(rpmb2key).decode('utf-8')}")
self.config.hwparam.writesetting("rpmb2key", hexlify(rpmb2key).decode('utf-8'))
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
if fdekey is not None:
self.info("FDE : " + hexlify(fdekey).decode('utf-8'))
self.config.hwparam.writesetting("fdekey",hexlify(fdekey).decode('utf-8'))
self.info(f"FDE : {hexlify(fdekey).decode('utf-8')}")
self.config.hwparam.writesetting("fdekey", hexlify(fdekey).decode('utf-8'))
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
if ikey is not None:
self.info("iTrustee : " + hexlify(ikey).decode('utf-8'))
self.info(f"iTrustee : {hexlify(ikey).decode('utf-8')}")
self.config.hwparam.writesetting("kmkey", hexlify(ikey).decode('utf-8'))
retval["kmkey"] = hexlify(ikey).decode('utf-8')
if self.config.chipconfig.prov_addr:
provkey = self.memread(self.config.chipconfig.prov_addr, 16)
self.info("PROV : " + hexlify(provkey).decode('utf-8'))
self.info(f"PROV : {hexlify(provkey).decode('utf-8')}")
self.config.hwparam.writesetting("provkey", hexlify(provkey).decode('utf-8'))
retval["provkey"] = hexlify(provkey).decode('utf-8')
return retval, keyinfo
elif self.setup.sej_base is not None and mode not in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt","dxcc_sha256"]:
retval={}
elif self.setup.sej_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
"sej_sst_encrypt", "dxcc_sha256"]:
retval = {}
rpmbkey = self.hwcrypto.aes_hwcrypt(mode="rpmb", data=meid, otp=otp, btype="sej")
if rpmbkey:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
self.info(f"RPMB : {hexlify(rpmbkey).decode('utf-8')}")
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
self.info("Generating sej mtee...")
mtee = self.hwcrypto.aes_hwcrypt(mode="mtee", otp=otp, btype="sej")
if mtee:
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
self.info(f"MTEE : {hexlify(mtee).decode('utf-8')}")
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
retval["mtee"] = hexlify(mtee).decode('utf-8')
mtee3 = self.hwcrypto.aes_hwcrypt(mode="mtee3", otp=otp, btype="sej")
if mtee3:
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
self.info(f"MTEE3 : {hexlify(mtee3).decode('utf-8')}")
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
keyinfo+="\nKeys :\n-----------------------------------------\n"
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')
keyinfo+="\n"
keyinfo += "MTEE: " + hexlify(mtee).decode('utf-8')
keyinfo += "\n"
keyinfo += "\nKeys :\n-----------------------------------------\n"
keyinfo += f"RPMB: {hexlify(rpmbkey).decode('utf-8')}\n"
keyinfo += f"MTEE: {hexlify(mtee).decode('utf-8')}\n"
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
return retval, keyinfo
if mode == "sej_aes_decrypt":
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
keyinfo+="\n"
keyinfo += f"\nData: {hexlify(dec_data).decode('utf-8')}\n"
return dec_data, keyinfo
elif mode == "sej_aes_encrypt":
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(enc_data).decode('utf-8')
keyinfo+="\n"
keyinfo += f"\nData: {hexlify(enc_data).decode('utf-8')}\n"
return enc_data, keyinfo
elif mode == "sej_sst_decrypt":
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
keyinfo+="\n"
keyinfo += f"\nData: {hexlify(dec_data).decode('utf-8')}\n"
return dec_data, keyinfo
elif mode == "sej_sst_encrypt":
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True, otp=otp)
keyinfo += "\n"
keyinfo += "Data: " + hexlify(enc_data).decode('utf-8')
keyinfo += "\n"
keyinfo += f"\nData: {hexlify(enc_data).decode('utf-8')}\n"
return enc_data, keyinfo
elif mode == "dxcc_sha256":
sha256val = self.hwcrypto.aes_hwcrypt(mode="sha256", data=data, btype="dxcc")
keyinfo+="\n"
keyinfo+="SHA256: " + hexlify(sha256val).decode('utf-8')
keyinfo+="\n"
keyinfo += f"\nSHA256: {hexlify(sha256val).decode('utf-8')}\n"
return sha256val, keyinfo
return None, ""
@ -501,7 +489,6 @@ class Stage2(metaclass=LogBase):
self.usbwrite(pack(">I", 0x3000))
def getint(valuestr):
if valuestr == '':
return None
@ -533,86 +520,78 @@ cmds = {
info = "MTK Stage2 client (c) B.Kerler 2021"
def showcommands():
print(info)
print("-----------------------------------\n")
print("Available commands are:\n")
for cmd in cmds:
print("%20s" % (cmd) + ":\t" + cmds[cmd])
print()
def main():
parser = argparse.ArgumentParser(description=info)
subparsers = parser.add_subparsers(dest="cmd", help='Valid commands are: rpmb, preloader, data, boot2, memread, memwrite, keys')
subparsers = parser.add_subparsers(dest="cmd",
help='Valid commands are: rpmb, preloader, data, boot2, memread, memwrite, keys')
parser_rpmb = subparsers.add_parser("rpmb", help="Dump the rpmb")
parser_rpmb.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_rpmb.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_rpmb.add_argument('--reverse', dest='reverse', action="store_true",
help='Reverse byte order (example: rpmb command)')
help='Reverse byte order (example: rpmb command)')
parser_rpmb.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_preloader = subparsers.add_parser("preloader", help="Dump the preloader")
parser_preloader.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_preloader.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_preloader.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_data = subparsers.add_parser("data", help="Read the mmc")
parser_data.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_data.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_data.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_boot2 = subparsers.add_parser("boot2", help="Dump boot2")
parser_boot2.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_boot2.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_boot2.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_memread = subparsers.add_parser("memread", help="Read memory")
parser_memread.add_argument(dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_memread.add_argument(dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_memread.add_argument('--filename', dest='filename', type=str,
help='Save to filename')
help='Save to filename')
parser_memwrite = subparsers.add_parser("memwrite", help="Write memory")
parser_memwrite.add_argument(dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_memwrite.add_argument('data', type=str,
help='Data to write [hexstring, dword or filename]')
help='Data to write [hexstring, dword or filename]')
parser_reboot = subparsers.add_parser("reboot", help="Reboot device")
parser_seccfg = subparsers.add_parser("seccfg", help="Generate seccfg")
parser_seccfg.add_argument('flag', type=str,
help='Option for generating: unlock or lock')
help='Option for generating: unlock or lock')
parser_seccfg.add_argument('--sw', dest='sw', action="store_true",
help='Option for generating: sw or hw')
help='Option for generating: sw or hw')
parser_keys = subparsers.add_parser("keys", help="Write memory")
parser_keys.add_argument('--otp', dest='otp', type=str,
help='OTP for keys (dxcc,sej,gcpu)')
help='OTP for keys (dxcc,sej,gcpu)')
parser_keys.add_argument('--mode', dest='mode', default=None, type=str,
help='keymode (dxcc,sej,gcpu,sej_aes_decrypt,sej_aes_decrypt,sej_sst_decrypt,sej_sst_encrypt')
help='keymode (dxcc,sej,gcpu,sej_aes_decrypt,sej_aes_decrypt,sej_sst_decrypt,sej_sst_encrypt')
parser_keys.add_argument('--data', dest='data', default=None, type=str,
help='data')
help='data')
args = parser.parse_args()
cmd = args.cmd
if cmd not in cmds:
showcommands()
parser.print_help()
exit(0)
if not os.path.exists("logs"):
@ -673,35 +652,35 @@ def main():
exit(0)
start = getint(args.start)
if os.path.exists(args.data):
filename=args.data
data=None
filename = args.data
data = None
else:
if "0x" in args.data:
data=getint(args.data)
data = getint(args.data)
else:
data=args.data
filename=None
data = args.data
filename = None
if st2.memwrite(start, data, filename):
print(f"Successfully wrote data to {hex(start)}.")
else:
print(f"Failed to write data to {hex(start)}.")
elif cmd == "keys":
keyinfo=""
data=b""
if args.mode in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt"]:
keyinfo = ""
data = b""
if args.mode in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt", "sej_sst_encrypt"]:
if not args.data:
print("Option --data is needed")
exit(0)
data = bytes.fromhex(args.data)
# otp_hisense=bytes.fromhex("486973656E736500000000000000000000000000000000000000000000000000")
# st2.jump(0x223449)
keys, keyinfo=st2.keys(data=data, mode=args.mode, otp=args.otp)
keys, keyinfo = st2.keys(data=data, mode=args.mode, otp=args.otp)
print(keyinfo)
print("Wrote keys to logs/hwparam.json")
elif cmd == "reboot":
st2.reboot()
elif cmd == "seccfg":
if args.flag not in ["unlock","lock"]:
if args.flag not in ["unlock", "lock"]:
print("Valid flags are: unlock, lock")
sys.exit(1)
"""
@ -720,15 +699,15 @@ def main():
SBOOT_RUNTIME_OFF = 0
SBOOT_RUNTIME_ON = 1
"""
if args.flag=="unlock":
if args.flag == "unlock":
lock_state = 3
critical_lock_state = 1
elif args.flag=="lock":
elif args.flag == "lock":
lock_state = 1
critical_lock_state = 0
with open("seccfg.bin", "wb") as wf:
seccfg_ver = 4
seccfg_size = 0x3C
seccfg_size = 0x3C
sboot_runtime = 0
seccfg_data = pack("<IIIIIII", 0x4D4D4D4D, seccfg_ver, seccfg_size, lock_state,
critical_lock_state, sboot_runtime, 0x45454545)
@ -736,12 +715,13 @@ def main():
if args.sw:
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_sw(dec_hash, True)
else:
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_hw(dec_hash,True)
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_hw(dec_hash, True)
data = seccfg_data + enc_hash
data += b"\x00" * (0x200 - len(data))
wf.write(data)
print("Successfully wrote seccfg to seccfg.bin. You need to write seccfg.bin to partition seccfg.")
st2.close()
if __name__ == "__main__":
main()