mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-12-02 20:26:57 -05:00
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:
commit
491f930424
46 changed files with 582 additions and 687 deletions
18
mtk
18
mtk
|
@ -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)
|
||||
|
|
|
@ -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
111
mtk_gui
|
@ -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):
|
||||
|
|
|
@ -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={},
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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="")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
BIN
mtkclient/Library/Filesystem/bin/winfsp-x64.dll
Normal file
BIN
mtkclient/Library/Filesystem/bin/winfsp-x64.dll
Normal file
Binary file not shown.
BIN
mtkclient/Library/Filesystem/bin/winfsp-x86.dll
Normal file
BIN
mtkclient/Library/Filesystem/bin/winfsp-x86.dll
Normal file
Binary file not shown.
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
--------------------------------------
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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)}"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,3 +9,5 @@ mock >= 4.0.3
|
|||
pyserial >= 3.5
|
||||
flake8
|
||||
fusepy
|
||||
unicorn
|
||||
capstone
|
||||
|
|
240
stage2
240
stage2
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue