mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-12-03 12:46:56 -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"
|
"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__':
|
if __name__ == '__main__':
|
||||||
print(info)
|
print(info)
|
||||||
print("")
|
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('--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('--brom_addr', help='Set a specific brom payload addr')
|
||||||
parser_ess.add_argument('--ptype',
|
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('--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('--verifystage2', help='Verify if stage2 data has been written correctly')
|
||||||
parser_ess.add_argument('--parttype', help='Partition type\n' +
|
parser_ess.add_argument('--parttype', help='Partition type\n' +
|
||||||
'\t\tEMMC: [user, boot1, boot2, gp1, gp2, gp3, gp4, rpmb]' +
|
'\t\tEMMC: [user, boot1, boot2, gp1, gp2, gp3, gp4, rpmb]' +
|
||||||
'\t\tUFS: [lu0, lu1, lu2, lu0_lu1]')
|
'\t\tUFS: [lu0, lu1, lu2, lu0_lu1]')
|
||||||
parser_ess.add_argument('--filename', help='Optional filename')
|
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('--crash', help='Enforce crash if device is in pl mode to enter brom mode')
|
||||||
parser_ess.add_argument('--socid', help='Read Soc ID')
|
parser_ess.add_argument('--socid', help='Read Soc ID')
|
||||||
|
@ -947,7 +937,7 @@ if __name__ == '__main__':
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
cmd = args.cmd
|
cmd = args.cmd
|
||||||
if cmd not in cmds:
|
if cmd not in cmds:
|
||||||
showcommands()
|
parser.print_help()
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
mtk = Main(args).run(parser)
|
mtk = Main(args).run(parser)
|
||||||
|
|
|
@ -8,7 +8,7 @@ block_cipher = None
|
||||||
a = Analysis(['mtk'],
|
a = Analysis(['mtk'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[],
|
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=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
|
|
111
mtk_gui
111
mtk_gui
|
@ -105,7 +105,7 @@ def load_translations(application):
|
||||||
locale = QLocale.system()
|
locale = QLocale.system()
|
||||||
translator = QTranslator(application)
|
translator = QTranslator(application)
|
||||||
directory = os.path.dirname(__file__)
|
directory = os.path.dirname(__file__)
|
||||||
lang = 'mtkclient/gui/i18n/' + locale.name()
|
lang = f'mtkclient/gui/i18n/{locale.name()}'
|
||||||
if locale.name() == "en_NL":
|
if locale.name() == "en_NL":
|
||||||
lang = lang.replace("en_NL", "nl_NL")
|
lang = lang.replace("en_NL", "nl_NL")
|
||||||
# lang = 'mtkclient/gui/i18n/fr_FR'
|
# lang = 'mtkclient/gui/i18n/fr_FR'
|
||||||
|
@ -154,10 +154,7 @@ class MainWindow(QMainWindow):
|
||||||
global lock
|
global lock
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
doneBytes = 0
|
doneBytes = 0
|
||||||
if "currentPartitionSizeDone" in self.Status:
|
curpartBytes = self.Status[f"currentPartitionSize{'Done' if 'currentPartitionSizeDone' in self.Status else ''}"]
|
||||||
curpartBytes = self.Status["currentPartitionSizeDone"]
|
|
||||||
else:
|
|
||||||
curpartBytes = self.Status["currentPartitionSize"]
|
|
||||||
|
|
||||||
if "allPartitions" in self.Status:
|
if "allPartitions" in self.Status:
|
||||||
for partition in self.Status["allPartitions"]:
|
for partition in self.Status["allPartitions"]:
|
||||||
|
@ -168,11 +165,7 @@ class MainWindow(QMainWindow):
|
||||||
fullPercentageDone = int((doneBytes / totalBytes) * 100)
|
fullPercentageDone = int((doneBytes / totalBytes) * 100)
|
||||||
self.ui.fullProgress.setValue(fullPercentageDone)
|
self.ui.fullProgress.setValue(fullPercentageDone)
|
||||||
timeinfototal = self.timeEstTotal.update(fullPercentageDone, 100)
|
timeinfototal = self.timeEstTotal.update(fullPercentageDone, 100)
|
||||||
self.ui.fullProgressText.setText("<table width='100%'><tr><td><b>Total:</b> " +
|
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>")
|
||||||
convert_size(doneBytes) + " / " + convert_size(totalBytes) +
|
|
||||||
"</td><td align='right'>" + timeinfototal +
|
|
||||||
QCoreApplication.translate("main", " left") +
|
|
||||||
"</td></tr></table>")
|
|
||||||
else:
|
else:
|
||||||
partBytes = self.Status["currentPartitionSize"]
|
partBytes = self.Status["currentPartitionSize"]
|
||||||
doneBytes = self.Status["currentPartitionSizeDone"]
|
doneBytes = self.Status["currentPartitionSizeDone"]
|
||||||
|
@ -244,21 +237,21 @@ class MainWindow(QMainWindow):
|
||||||
self.readflash.disableButtonsSignal.connect(self.disablebuttons)
|
self.readflash.disableButtonsSignal.connect(self.disablebuttons)
|
||||||
self.ui.readpartitionsbtn.clicked.connect(self.readflash.dumpPartition)
|
self.ui.readpartitionsbtn.clicked.connect(self.readflash.dumpPartition)
|
||||||
self.ui.readselectallcheckbox.clicked.connect(self.readflash.selectAll)
|
self.ui.readselectallcheckbox.clicked.connect(self.readflash.selectAll)
|
||||||
self.ui.readpreloaderbtn.clicked.connect(self.on_readpreloader)
|
self.ui.readpreloaderbtn.clicked.connect(lambda: self.readflash.dumpFlash("boot1"))
|
||||||
self.ui.readflashbtn.clicked.connect(self.on_readfullflash)
|
self.ui.readflashbtn.clicked.connect(lambda: self.readflash.dumpFlash("user"))
|
||||||
self.ui.readrpmbbtn.clicked.connect(self.on_readrpmb)
|
self.ui.readrpmbbtn.clicked.connect(lambda: self.readflash.dumpFlash("rpmb"))
|
||||||
self.ui.readboot2btn.clicked.connect(self.on_readboot2)
|
self.ui.readboot2btn.clicked.connect(lambda: self.readflash.dumpFlash("boot2"))
|
||||||
|
|
||||||
def initkeys(self):
|
def initkeys(self):
|
||||||
self.genkeys = generateKeysMenu(self.ui, self, self.devhandler.da_handler, self.sendToLog)
|
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.enableButtonsSignal.connect(self.enablebuttons)
|
||||||
self.genkeys.disableButtonsSignal.connect(self.disablebuttons)
|
self.genkeys.disableButtonsSignal.connect(self.disablebuttons)
|
||||||
|
|
||||||
def initunlock(self):
|
def initunlock(self):
|
||||||
self.unlock = UnlockMenu(self.ui, self, self.devhandler.da_handler, self.sendToLog)
|
self.unlock = UnlockMenu(self.ui, self, self.devhandler.da_handler, self.sendToLog)
|
||||||
self.ui.unlockbutton.clicked.connect(self.on_unlock)
|
self.ui.unlockbutton.clicked.connect(lambda: self.unlock.unlock("unlock"))
|
||||||
self.ui.lockbutton.clicked.connect(self.on_lock)
|
self.ui.lockbutton.clicked.connect(lambda: self.unlock.unlock("lock"))
|
||||||
self.unlock.enableButtonsSignal.connect(self.enablebuttons)
|
self.unlock.enableButtonsSignal.connect(self.enablebuttons)
|
||||||
self.unlock.disableButtonsSignal.connect(self.disablebuttons)
|
self.unlock.disableButtonsSignal.connect(self.disablebuttons)
|
||||||
|
|
||||||
|
@ -267,21 +260,21 @@ class MainWindow(QMainWindow):
|
||||||
self.eraseflash.enableButtonsSignal.connect(self.enablebuttons)
|
self.eraseflash.enableButtonsSignal.connect(self.enablebuttons)
|
||||||
self.eraseflash.disableButtonsSignal.connect(self.disablebuttons)
|
self.eraseflash.disableButtonsSignal.connect(self.disablebuttons)
|
||||||
self.ui.eraseselectallpartitionscheckbox.clicked.connect(self.eraseflash.selectAll)
|
self.ui.eraseselectallpartitionscheckbox.clicked.connect(self.eraseflash.selectAll)
|
||||||
self.ui.erasepartitionsbtn.clicked.connect(self.on_erasepartflash)
|
self.ui.erasepartitionsbtn.clicked.connect(self.eraseflash.erasePartition)
|
||||||
self.ui.eraserpmbbtn.clicked.connect(self.on_eraserpmb)
|
self.ui.eraserpmbbtn.clicked.connect(lambda: self.eraseflash.eraseFlash("rpmb"))
|
||||||
self.ui.erasepreloaderbtn.clicked.connect(self.on_erasepreloader)
|
self.ui.erasepreloaderbtn.clicked.connect(lambda: self.eraseflash.eraseFlash("boot1"))
|
||||||
self.ui.eraseboot2btn.clicked.connect(self.on_eraseboot2)
|
self.ui.eraseboot2btn.clicked.connect(lambda: self.eraseflash.eraseFlash("boot2"))
|
||||||
|
|
||||||
def initwrite(self):
|
def initwrite(self):
|
||||||
self.writeflash = WriteFlashWindow(self.ui, self, self.devhandler.da_handler, self.sendToLog)
|
self.writeflash = WriteFlashWindow(self.ui, self, self.devhandler.da_handler, self.sendToLog)
|
||||||
self.writeflash.enableButtonsSignal.connect(self.enablebuttons)
|
self.writeflash.enableButtonsSignal.connect(self.enablebuttons)
|
||||||
self.writeflash.disableButtonsSignal.connect(self.disablebuttons)
|
self.writeflash.disableButtonsSignal.connect(self.disablebuttons)
|
||||||
self.ui.writeselectfromdir.clicked.connect(self.writeflash.selectFiles)
|
self.ui.writeselectfromdir.clicked.connect(self.writeflash.selectFiles)
|
||||||
self.ui.writeflashbtn.clicked.connect(self.on_writefullflash)
|
self.ui.writeflashbtn.clicked.connect(lambda: self.writeflash.writeFlash("user"))
|
||||||
self.ui.writepartbtn.clicked.connect(self.on_writepartflash)
|
self.ui.writepartbtn.clicked.connect(self.writeflash.writePartition)
|
||||||
self.ui.writeboot2btn.clicked.connect(self.on_writeboot2)
|
self.ui.writeboot2btn.clicked.connect(lambda: self.writeflash.writeFlash("boot2"))
|
||||||
self.ui.writepreloaderbtn.clicked.connect(self.on_writepreloader)
|
self.ui.writepreloaderbtn.clicked.connect(lambda: self.writeflash.writeFlash("boot1"))
|
||||||
self.ui.writerpmbbtn.clicked.connect(self.on_writerpmb)
|
self.ui.writerpmbbtn.clicked.connect(lambda: self.writeflash.writeFlash("rpmb"))
|
||||||
|
|
||||||
@Slot(str)
|
@Slot(str)
|
||||||
def update_status_text(self, text):
|
def update_status_text(self, text):
|
||||||
|
@ -338,12 +331,7 @@ class MainWindow(QMainWindow):
|
||||||
|
|
||||||
def getpartitions(self):
|
def getpartitions(self):
|
||||||
data, guid_gpt = self.devhandler.da_handler.mtk.daloader.get_gpt()
|
data, guid_gpt = self.devhandler.da_handler.mtk.daloader.get_gpt()
|
||||||
if guid_gpt is None:
|
self.ui.readtitle.setText(QCoreApplication.translate("main", "Error reading gpt" if guid_gpt is None else "Select partitions to dump"))
|
||||||
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"))
|
|
||||||
|
|
||||||
readpartitionListWidgetVBox = QVBoxLayout()
|
readpartitionListWidgetVBox = QVBoxLayout()
|
||||||
readpartitionListWidget = QWidget(self)
|
readpartitionListWidget = QWidget(self)
|
||||||
readpartitionListWidget.setLayout(readpartitionListWidgetVBox)
|
readpartitionListWidget.setLayout(readpartitionListWidgetVBox)
|
||||||
|
@ -421,65 +409,8 @@ class MainWindow(QMainWindow):
|
||||||
lineedit.setDisabled(False)
|
lineedit.setDisabled(False)
|
||||||
return fname
|
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):
|
def sendToLog(self, info):
|
||||||
t = time.localtime()
|
self.ui.logBox.appendPlainText(time.strftime("[%H:%M:%S", time.localtime()) + "]: " + info)
|
||||||
self.ui.logBox.appendPlainText(time.strftime("[%H:%M:%S", t) + "]: " + info)
|
|
||||||
self.ui.logBox.verticalScrollBar().setValue(self.ui.logBox.verticalScrollBar().maximum())
|
self.ui.logBox.verticalScrollBar().setValue(self.ui.logBox.verticalScrollBar().maximum())
|
||||||
|
|
||||||
def sendToProgress(self, progress):
|
def sendToProgress(self, progress):
|
||||||
|
|
|
@ -8,7 +8,7 @@ block_cipher = None
|
||||||
a = Analysis(['mtk_gui'],
|
a = Analysis(['mtk_gui'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[],
|
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=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
|
|
|
@ -88,7 +88,7 @@ class serial_class(DeviceClass):
|
||||||
for usbid in self.portconfig:
|
for usbid in self.portconfig:
|
||||||
if port.pid == usbid[1] and port.vid == usbid[0]:
|
if port.pid == usbid[1] and port.vid == usbid[0]:
|
||||||
# portid = port.location[-1:]
|
# 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)
|
ids.append(port.device)
|
||||||
return sorted(ids)
|
return sorted(ids)
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,8 @@ class CDC_CMDS:
|
||||||
|
|
||||||
class usb_class(DeviceClass):
|
class usb_class(DeviceClass):
|
||||||
|
|
||||||
def load_windows_dll(self):
|
@staticmethod
|
||||||
|
def load_windows_dll():
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
windows_dir = None
|
windows_dir = None
|
||||||
try:
|
try:
|
||||||
|
@ -142,10 +143,7 @@ class usb_class(DeviceClass):
|
||||||
self.backend = None
|
self.backend = None
|
||||||
|
|
||||||
def set_fast_mode(self, enabled):
|
def set_fast_mode(self, enabled):
|
||||||
if enabled:
|
self.fast = bool(enabled)
|
||||||
self.fast = True
|
|
||||||
else:
|
|
||||||
self.fast = False
|
|
||||||
|
|
||||||
def verify_data(self, data, pre="RX:"):
|
def verify_data(self, data, pre="RX:"):
|
||||||
if self.__logger.level == logging.DEBUG:
|
if self.__logger.level == logging.DEBUG:
|
||||||
|
@ -207,7 +205,7 @@ class usb_class(DeviceClass):
|
||||||
if stopbits is not None:
|
if stopbits is not None:
|
||||||
if stopbits not in sbits.keys():
|
if stopbits not in sbits.keys():
|
||||||
valid = ", ".join(str(k) for k in sorted(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
|
self.stopbits = stopbits
|
||||||
else:
|
else:
|
||||||
self.stopbits = 0
|
self.stopbits = 0
|
||||||
|
@ -215,7 +213,7 @@ class usb_class(DeviceClass):
|
||||||
if databits is not None:
|
if databits is not None:
|
||||||
if databits not in dbits:
|
if databits not in dbits:
|
||||||
valid = ", ".join(str(d) for d in sorted(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
|
self.databits = databits
|
||||||
else:
|
else:
|
||||||
self.databits = 0
|
self.databits = 0
|
||||||
|
@ -223,7 +221,7 @@ class usb_class(DeviceClass):
|
||||||
if parity is not None:
|
if parity is not None:
|
||||||
if parity not in pmodes:
|
if parity not in pmodes:
|
||||||
valid = ", ".join(str(pm) for pm in sorted(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
|
self.parity = parity
|
||||||
else:
|
else:
|
||||||
self.parity = 0
|
self.parity = 0
|
||||||
|
@ -234,7 +232,7 @@ class usb_class(DeviceClass):
|
||||||
dif = [abs(br - baudrate) for br in brs]
|
dif = [abs(br - baudrate) for br in brs]
|
||||||
best = brs[dif.index(min(dif))]
|
best = brs[dif.index(min(dif))]
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Invalid baudrates, nearest valid is {}".format(best))
|
f"Invalid baudrates, nearest valid is {best}")
|
||||||
self.baudrate = baudrate
|
self.baudrate = baudrate
|
||||||
|
|
||||||
linecode = [
|
linecode = [
|
||||||
|
@ -254,7 +252,7 @@ class usb_class(DeviceClass):
|
||||||
wlen = self.device.ctrl_transfer(
|
wlen = self.device.ctrl_transfer(
|
||||||
req_type, CDC_CMDS.SET_LINE_CODING,
|
req_type, CDC_CMDS.SET_LINE_CODING,
|
||||||
data_or_wLength=data, wIndex=1)
|
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):
|
def setbreak(self):
|
||||||
txdir = 0 # 0:OUT, 1:IN
|
txdir = 0 # 0:OUT, 1:IN
|
||||||
|
@ -264,7 +262,7 @@ class usb_class(DeviceClass):
|
||||||
wlen = self.device.ctrl_transfer(
|
wlen = self.device.ctrl_transfer(
|
||||||
bmRequestType=req_type, bRequest=CDC_CMDS.SEND_BREAK,
|
bmRequestType=req_type, bRequest=CDC_CMDS.SEND_BREAK,
|
||||||
wValue=0, data_or_wLength=0, wIndex=1)
|
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):
|
def setcontrollinestate(self, RTS=None, DTR=None, isFTDI=False):
|
||||||
cmds = CDC_CMDS()
|
cmds = CDC_CMDS()
|
||||||
|
@ -284,7 +282,7 @@ class usb_class(DeviceClass):
|
||||||
wValue=ctrlstate,
|
wValue=ctrlstate,
|
||||||
wIndex=1,
|
wIndex=1,
|
||||||
data_or_wLength=0)
|
data_or_wLength=0)
|
||||||
self.debug("Linecoding set, {}b sent".format(wlen))
|
self.debug(f"Linecoding set, {wlen}b sent")
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
return
|
return
|
||||||
|
@ -348,7 +346,7 @@ class usb_class(DeviceClass):
|
||||||
self.debug("Detaching kernel driver")
|
self.debug("Detaching kernel driver")
|
||||||
self.device.detach_kernel_driver(0)
|
self.device.detach_kernel_driver(0)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.debug("No kernel driver supported: " + str(err))
|
self.debug(f"No kernel driver supported: {str(err)}")
|
||||||
try:
|
try:
|
||||||
usb.util.claim_interface(self.device, 0)
|
usb.util.claim_interface(self.device, 0)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -360,7 +358,7 @@ class usb_class(DeviceClass):
|
||||||
self.debug("Detaching kernel driver")
|
self.debug("Detaching kernel driver")
|
||||||
self.device.detach_kernel_driver(self.interface)
|
self.device.detach_kernel_driver(self.interface)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.debug("No kernel driver supported: " + str(err))
|
self.debug(f"No kernel driver supported: {str(err)}")
|
||||||
try:
|
try:
|
||||||
if self.interface != 0:
|
if self.interface != 0:
|
||||||
usb.util.claim_interface(self.device, self.interface)
|
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)
|
ret_tag += self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, datasize)
|
||||||
if datasize > 0:
|
if datasize > 0:
|
||||||
data = self.usb.read(datasize, timeout)
|
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")
|
print("Sent HTC adb enable command")
|
||||||
|
|
||||||
def send_htc_ums_adbenable(self): # HTC10
|
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)
|
ret_tag += self.send_mass_storage_command(lun, common_cmnd2, USB_DIR_IN, datasize)
|
||||||
if datasize > 0:
|
if datasize > 0:
|
||||||
data = self.usb.read(datasize, timeout)
|
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")
|
print("Send HTC adb enable command")
|
||||||
|
|
||||||
def send_fih_adbenable(self): # motorola xt560, nokia 3.1, #f_mass_storage.c
|
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)
|
# ret_tag+=self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
|
||||||
if datasize > 0:
|
if datasize > 0:
|
||||||
data = self.usb.read(datasize, timeout)
|
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")
|
print("Sent FIH adb enable command")
|
||||||
self.usb.close()
|
self.usb.close()
|
||||||
|
|
||||||
|
@ -795,7 +793,7 @@ class Scsi:
|
||||||
self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
|
self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
|
||||||
if datasize > 0:
|
if datasize > 0:
|
||||||
data = self.usb.read(datasize, timeout)
|
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")
|
print("Sent alcatel adb enable command")
|
||||||
self.usb.close()
|
self.usb.close()
|
||||||
|
|
||||||
|
@ -814,7 +812,7 @@ class Scsi:
|
||||||
ret_tag += self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
|
ret_tag += self.send_mass_storage_command(lun, common_cmnd, USB_DIR_IN, 0x600)
|
||||||
if datasize > 0:
|
if datasize > 0:
|
||||||
data = self.usb.read(datasize, timeout)
|
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")
|
print("Sent FIH root command")
|
||||||
self.usb.close()
|
self.usb.close()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ from mtkclient.Library.Connection.usblib import Scsi
|
||||||
def main():
|
def main():
|
||||||
info = 'MassStorageBackdoor (c) B.Kerler 2019.'
|
info = 'MassStorageBackdoor (c) B.Kerler 2019.'
|
||||||
parser = argparse.ArgumentParser(description=info)
|
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('-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('-pid', metavar="<pid>", help='[Option] Specify pid, default=0xc025)', default="0xc025")
|
||||||
parser.add_argument('-interface', metavar="<pid>", help='[Option] Specify interface number)', default="")
|
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)
|
self.parse_da_loader(loader, self.dasetup)
|
||||||
else:
|
else:
|
||||||
if not os.path.exists(loader):
|
if not os.path.exists(loader):
|
||||||
self.warning("Couldn't open " + loader)
|
self.warning(f"Couldn't open {loader}")
|
||||||
else:
|
else:
|
||||||
self.info("Using custom loader: " + loader)
|
self.info(f"Using custom loader: {loader}")
|
||||||
self.parse_da_loader(loader, self.dasetup)
|
self.parse_da_loader(loader, self.dasetup)
|
||||||
|
|
||||||
def m_extract_emi(self, data):
|
def m_extract_emi(self, data):
|
||||||
|
@ -203,7 +203,7 @@ class DAconfig(metaclass=LogBase):
|
||||||
with open(preloader, "rb") as rf:
|
with open(preloader, "rb") as rf:
|
||||||
data = rf.read()
|
data = rf.read()
|
||||||
else:
|
else:
|
||||||
self.error("Preloader : " + preloader + " doesn't exist. Aborting.")
|
self.error(f"Preloader : {preloader} doesn't exist. Aborting.")
|
||||||
exit(1)
|
exit(1)
|
||||||
try:
|
try:
|
||||||
self.emiver, self.emi = self.m_extract_emi(data)
|
self.emiver, self.emi = self.m_extract_emi(data)
|
||||||
|
@ -211,17 +211,14 @@ class DAconfig(metaclass=LogBase):
|
||||||
self.emiver = 0
|
self.emiver = 0
|
||||||
self.emi = None
|
self.emi = None
|
||||||
|
|
||||||
def parse_da_loader(self, loader:str, dasetup:dict):
|
def parse_da_loader(self, loader: str, dasetup: dict):
|
||||||
try:
|
try:
|
||||||
with open(loader, 'rb') as bootldr:
|
with open(loader, 'rb') as bootldr:
|
||||||
# data = bootldr.read()
|
# data = bootldr.read()
|
||||||
# self.debug(hexlify(data).decode('utf-8'))
|
# self.debug(hexlify(data).decode('utf-8'))
|
||||||
hdr = bootldr.read(0x68)
|
hdr = bootldr.read(0x68)
|
||||||
count_da = unpack("<I", bootldr.read(4))[0]
|
count_da = unpack("<I", bootldr.read(4))[0]
|
||||||
if b"MTK_DA_v6" in hdr:
|
v6 = b"MTK_DA_v6" in hdr
|
||||||
v6 = True
|
|
||||||
else:
|
|
||||||
v6 = False
|
|
||||||
for i in range(0, count_da):
|
for i in range(0, count_da):
|
||||||
bootldr.seek(0x6C + (i * 0xDC))
|
bootldr.seek(0x6C + (i * 0xDC))
|
||||||
da = DA(bootldr.read(0xDC))
|
da = DA(bootldr.read(0xDC))
|
||||||
|
@ -245,7 +242,7 @@ class DAconfig(metaclass=LogBase):
|
||||||
dasetup[da.hw_code].append(da)
|
dasetup[da.hw_code].append(da)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
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
|
return False
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
|
|
@ -303,7 +303,7 @@ class DALegacy(metaclass=LogBase):
|
||||||
pdram[0] = draminfo[:9]
|
pdram[0] = draminfo[:9]
|
||||||
draminfo = draminfo[:4][::-1] + draminfo[4:8][::-1] + draminfo[8:12][::-1] + draminfo[12:16][::-1]
|
draminfo = draminfo[:4][::-1] + draminfo[4:8][::-1] + draminfo[8:12][::-1] + draminfo[12:16][::-1]
|
||||||
pdram[1] = draminfo[:9]
|
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:
|
if self.daconfig.emi is None:
|
||||||
found = False
|
found = False
|
||||||
for root, dirs, files in os.walk(os.path.join(self.pathconfig.get_loader_path(), 'Preloader')):
|
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()
|
data = rf.read()
|
||||||
if pdram[0] in data or pdram[1] in data:
|
if pdram[0] in data or pdram[1] in data:
|
||||||
preloader = os.path.join(root, file)
|
preloader = os.path.join(root, file)
|
||||||
print("Detected preloader: " + preloader)
|
print(f"Detected preloader: {preloader}")
|
||||||
self.daconfig.extract_emi(preloader)
|
self.daconfig.extract_emi(preloader)
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
|
@ -347,25 +347,25 @@ class DALegacy(metaclass=LogBase):
|
||||||
dramlength = len(self.daconfig.emi)
|
dramlength = len(self.daconfig.emi)
|
||||||
if self.daconfig.emiver in [0xF, 0x10, 0x11, 0x14, 0x15]:
|
if self.daconfig.emiver in [0xF, 0x10, 0x11, 0x14, 0x15]:
|
||||||
dramlength = unpack(">I", self.usbread(0x4))[0] # 0x000000BC
|
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)
|
self.usbwrite(self.Rsp.ACK)
|
||||||
lendram = len(self.daconfig.emi)
|
lendram = len(self.daconfig.emi)
|
||||||
if hwcode != 0x8127:
|
if hwcode != 0x8127:
|
||||||
self.usbwrite(pack(">I", lendram))
|
self.usbwrite(pack(">I", lendram))
|
||||||
elif self.daconfig.emiver in [0x0B]:
|
elif self.daconfig.emiver in [0x0B]:
|
||||||
info = self.usbread(0x10) # 0x000000BC
|
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]
|
dramlength = unpack(">I", self.usbread(0x4))[0]
|
||||||
self.usbwrite(self.Rsp.ACK)
|
self.usbwrite(self.Rsp.ACK)
|
||||||
elif self.daconfig.emiver in [0x0C, 0x0D]:
|
elif self.daconfig.emiver in [0x0C, 0x0D]:
|
||||||
dramlength = unpack(">I", self.usbread(0x4))[0]
|
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.usbwrite(self.Rsp.ACK)
|
||||||
self.daconfig.emi = self.daconfig.emi[:dramlength]
|
self.daconfig.emi = self.daconfig.emi[:dramlength]
|
||||||
self.daconfig.emi = pack(">I", 0x100) + self.daconfig.emi[0x4:dramlength]
|
self.daconfig.emi = pack(">I", 0x100) + self.daconfig.emi[0x4:dramlength]
|
||||||
elif self.daconfig.emiver in [0x00]:
|
elif self.daconfig.emiver in [0x00]:
|
||||||
dramlength = unpack(">I", self.usbread(0x4))[0] # 0x000000B0
|
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)
|
self.usbwrite(self.Rsp.ACK)
|
||||||
lendram = len(self.daconfig.emi)
|
lendram = len(self.daconfig.emi)
|
||||||
self.daconfig.emi = self.daconfig.emi[:dramlength]
|
self.daconfig.emi = self.daconfig.emi[:dramlength]
|
||||||
|
@ -582,7 +582,7 @@ class DALegacy(metaclass=LogBase):
|
||||||
|
|
||||||
self.info("Reading nand info")
|
self.info("Reading nand info")
|
||||||
nandinfo = unpack(">I", self.usbread(4))[0]
|
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]
|
ids = unpack(">H", self.usbread(2))[0]
|
||||||
nandids = []
|
nandids = []
|
||||||
for i in range(0, ids):
|
for i in range(0, ids):
|
||||||
|
@ -590,7 +590,7 @@ class DALegacy(metaclass=LogBase):
|
||||||
nandids.append(tmp)
|
nandids.append(tmp)
|
||||||
self.info("Reading emmc info")
|
self.info("Reading emmc info")
|
||||||
emmcinfolegacy = unpack(">I", self.usbread(4))[0]
|
emmcinfolegacy = unpack(">I", self.usbread(4))[0]
|
||||||
self.debug("EMMC_INFO: " + hex(emmcinfolegacy))
|
self.debug(f"EMMC_INFO: {hex(emmcinfolegacy)}")
|
||||||
emmcids = []
|
emmcids = []
|
||||||
for i in range(0, 4):
|
for i in range(0, 4):
|
||||||
tmp = unpack(">I", self.usbread(4))[0]
|
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)
|
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 ...")
|
self.info("Setting stage 2 config ...")
|
||||||
if self.set_stage2_config(self.config.hwcode):
|
if self.set_stage2_config(self.config.hwcode):
|
||||||
self.info("Uploading stage 2...")
|
self.info("Uploading stage 2...")
|
||||||
|
@ -791,7 +791,7 @@ class DALegacy(metaclass=LogBase):
|
||||||
buffer = self.usbread(1)
|
buffer = self.usbread(1)
|
||||||
if buffer != self.Rsp.ACK:
|
if buffer != self.Rsp.ACK:
|
||||||
self.error(
|
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"))
|
self.config.set_gui_status(self.config.tr("Error on sending brom stage"))
|
||||||
break
|
break
|
||||||
time.sleep(0.5)
|
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}"))
|
self.config.set_gui_status(self.config.tr(f"Successfully uploaded stage {stage}"))
|
||||||
return True
|
return True
|
||||||
else:
|
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"))
|
self.config.set_gui_status(self.config.tr("Error on sending brom stage"))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ class legacyext(metaclass=LogBase):
|
||||||
self.warning("Legacy DA2 CMD F0 not patched.")
|
self.warning("Legacy DA2 CMD F0 not patched.")
|
||||||
return da2patched
|
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)
|
da1 = bytearray(da1)
|
||||||
dahash = None
|
dahash = None
|
||||||
if hashmode == 1:
|
if hashmode == 1:
|
||||||
|
@ -245,26 +246,25 @@ class legacyext(metaclass=LogBase):
|
||||||
except Exception:
|
except Exception:
|
||||||
return
|
return
|
||||||
hwc = self.cryptosetup()
|
hwc = self.cryptosetup()
|
||||||
retval = {}
|
retval = {"hwcode": hex(self.config.hwcode)}
|
||||||
retval["hwcode"] = hex(self.config.hwcode)
|
|
||||||
meid = self.config.get_meid()
|
meid = self.config.get_meid()
|
||||||
socid = self.config.get_socid()
|
socid = self.config.get_socid()
|
||||||
hwcode = self.config.get_hwcode()
|
hwcode = self.config.get_hwcode()
|
||||||
pubk = self.read_pubk()
|
pubk = self.read_pubk()
|
||||||
if pubk is not None:
|
if pubk is not None:
|
||||||
retval["pubkey"] = pubk.hex()
|
retval["pubkey"] = pubk.hex()
|
||||||
self.info("PUBK : " + pubk.hex())
|
self.info(f"PUBK : {pubk.hex()}")
|
||||||
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
||||||
if meid is not None:
|
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')
|
retval["meid"] = hexlify(meid).decode('utf-8')
|
||||||
self.config.hwparam.writesetting("meid", hexlify(meid).decode('utf-8'))
|
self.config.hwparam.writesetting("meid", hexlify(meid).decode('utf-8'))
|
||||||
if socid is not None:
|
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')
|
retval["socid"] = hexlify(socid).decode('utf-8')
|
||||||
self.config.hwparam.writesetting("socid", hexlify(socid).decode('utf-8'))
|
self.config.hwparam.writesetting("socid", hexlify(socid).decode('utf-8'))
|
||||||
if hwcode is not None:
|
if hwcode is not None:
|
||||||
self.info("HWCODE : " + hex(hwcode))
|
self.info(f"HWCODE : {hex(hwcode)}")
|
||||||
retval["hwcode"] = hex(hwcode)
|
retval["hwcode"] = hex(hwcode)
|
||||||
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
||||||
if self.config.chipconfig.dxcc_base is not None:
|
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("Provkey : " + hexlify(provkey).decode('utf-8'))
|
||||||
# self.info("Platkey : " + hexlify(platkey).decode('utf-8'))
|
# self.info("Platkey : " + hexlify(platkey).decode('utf-8'))
|
||||||
if rpmbkey is not None:
|
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'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
if rpmb2key is not None:
|
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'))
|
self.config.hwparam.writesetting("rpmb2key", hexlify(rpmb2key).decode('utf-8'))
|
||||||
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
|
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
|
||||||
if fdekey is not None:
|
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'))
|
self.config.hwparam.writesetting("fdekey", hexlify(fdekey).decode('utf-8'))
|
||||||
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
|
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
|
||||||
if ikey is not None:
|
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'))
|
self.config.hwparam.writesetting("kmkey", hexlify(ikey).decode('utf-8'))
|
||||||
retval["kmkey"] = hexlify(ikey).decode('utf-8')
|
retval["kmkey"] = hexlify(ikey).decode('utf-8')
|
||||||
if self.config.chipconfig.prov_addr:
|
if self.config.chipconfig.prov_addr:
|
||||||
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
|
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'))
|
self.config.hwparam.writesetting("provkey", hexlify(provkey).decode('utf-8'))
|
||||||
retval["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()
|
otp = self.config.get_otp()
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
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'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
||||||
return retval
|
return retval
|
||||||
|
@ -331,19 +331,19 @@ class legacyext(metaclass=LogBase):
|
||||||
self.setotp(hwc)
|
self.setotp(hwc)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
if rpmbkey:
|
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'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
||||||
if mtee:
|
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'))
|
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
||||||
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
||||||
self.info("Generating sej mtee3...")
|
self.info("Generating sej mtee3...")
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
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'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
||||||
else:
|
else:
|
||||||
|
@ -353,7 +353,7 @@ class legacyext(metaclass=LogBase):
|
||||||
self.info("Generating gcpu mtee2 key...")
|
self.info("Generating gcpu mtee2 key...")
|
||||||
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
||||||
if mtee2 is not None:
|
if mtee2 is not None:
|
||||||
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'))
|
self.config.hwparam.writesetting("mtee2", hexlify(mtee2).decode('utf-8'))
|
||||||
retval["mtee2"] = hexlify(mtee2).decode('utf-8')
|
retval["mtee2"] = hexlify(mtee2).decode('utf-8')
|
||||||
self.config.hwparam.writesetting("hwcode", retval["hwcode"])
|
self.config.hwparam.writesetting("hwcode", retval["hwcode"])
|
||||||
|
|
|
@ -30,7 +30,8 @@ class DA_handler(metaclass=LogBase):
|
||||||
self.eh = ErrorHandler()
|
self.eh = ErrorHandler()
|
||||||
self.mtk = mtk
|
self.mtk = mtk
|
||||||
|
|
||||||
def close(self):
|
@staticmethod
|
||||||
|
def close():
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def dump_preloader_ram(self):
|
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:
|
if mtk.config.target_config["sbc"] and not mtk.config.is_brom and mtk.config.loader is None:
|
||||||
mtk = mtk.bypass_security()
|
mtk = mtk.bypass_security()
|
||||||
self.mtk = mtk
|
self.mtk = mtk
|
||||||
if self.mtk.daloader.patch :
|
if self.mtk.daloader.patch:
|
||||||
self.info("Device was protected. Successfully bypassed security.")
|
self.info("Device was protected. Successfully bypassed security.")
|
||||||
else:
|
else:
|
||||||
self.info("Device is still protected, trying to boot to brom")
|
self.info("Device is still protected, trying to boot to brom")
|
||||||
|
@ -197,7 +198,7 @@ class DA_handler(metaclass=LogBase):
|
||||||
rpartition = gptentry
|
rpartition = gptentry
|
||||||
break
|
break
|
||||||
if rpartition is not None:
|
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,
|
if self.mtk.daloader.readflash(addr=rpartition.sector * self.config.pagesize,
|
||||||
length=rpartition.sectors * self.config.pagesize,
|
length=rpartition.sectors * self.config.pagesize,
|
||||||
filename=partfilename, parttype=parttype):
|
filename=partfilename, parttype=parttype):
|
||||||
|
@ -645,7 +646,7 @@ class DA_handler(metaclass=LogBase):
|
||||||
elif cmd == "printgpt":
|
elif cmd == "printgpt":
|
||||||
data, guid_gpt = mtk.daloader.get_gpt()
|
data, guid_gpt = mtk.daloader.get_gpt()
|
||||||
if not guid_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:
|
else:
|
||||||
guid_gpt.print()
|
guid_gpt.print()
|
||||||
elif cmd == "r":
|
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}.")
|
print(f"Failed to dump offset {hex(start)} with length {hex(length)} as {filename}.")
|
||||||
elif cmd == "fs":
|
elif cmd == "fs":
|
||||||
print(f'Mounting FUSE fs at: {args.mountpoint}...')
|
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":
|
elif cmd == "footer":
|
||||||
filename = args.filename
|
filename = args.filename
|
||||||
self.da_footer(filename=filename)
|
self.da_footer(filename=filename)
|
||||||
|
|
|
@ -89,7 +89,8 @@ class DAloader(metaclass=LogBase):
|
||||||
return idx, hashmode, hashlen
|
return idx, hashmode, hashlen
|
||||||
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
|
pos = len(da1) - siglen - 0x30
|
||||||
hash = da1[pos:pos + 0x30]
|
hash = da1[pos:pos + 0x30]
|
||||||
if hash[-4:] == b"\x00\x00\x00\x00":
|
if hash[-4:] == b"\x00\x00\x00\x00":
|
||||||
|
@ -110,7 +111,8 @@ class DAloader(metaclass=LogBase):
|
||||||
self.debug("Error: No hash found")
|
self.debug("Error: No hash found")
|
||||||
return -1, -1
|
return -1, -1
|
||||||
|
|
||||||
def calc_da_hash(self, da1, da2):
|
@staticmethod
|
||||||
|
def calc_da_hash(da1, da2):
|
||||||
hashdigest = hashlib.sha1(da2).digest()
|
hashdigest = hashlib.sha1(da2).digest()
|
||||||
hashdigest256 = hashlib.sha256(da2).digest()
|
hashdigest256 = hashlib.sha256(da2).digest()
|
||||||
idx = da1.find(hashdigest)
|
idx = da1.find(hashdigest)
|
||||||
|
@ -120,7 +122,8 @@ class DAloader(metaclass=LogBase):
|
||||||
hashmode = 2
|
hashmode = 2
|
||||||
return hashmode, idx
|
return hashmode, idx
|
||||||
|
|
||||||
def fix_hash(self, da1, da2, hashpos, hashmode, hashlen):
|
@staticmethod
|
||||||
|
def fix_hash(da1, da2, hashpos, hashmode, hashlen):
|
||||||
da1 = bytearray(da1)
|
da1 = bytearray(da1)
|
||||||
dahash = None
|
dahash = None
|
||||||
if hashmode == 1:
|
if hashmode == 1:
|
||||||
|
@ -226,7 +229,7 @@ class DAloader(metaclass=LogBase):
|
||||||
if self.mtk.config.chipconfig.damode == damodes.XFLASH:
|
if self.mtk.config.chipconfig.damode == damodes.XFLASH:
|
||||||
self.da = DAXFlash(self.mtk, self.daconfig, self.loglevel)
|
self.da = DAXFlash(self.mtk, self.daconfig, self.loglevel)
|
||||||
if porttype not in ["off", "usb", "uart"]:
|
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):
|
if self.da.set_meta(porttype):
|
||||||
self.info(f"Successfully set meta mode to {porttype}")
|
self.info(f"Successfully set meta mode to {porttype}")
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -323,7 +323,7 @@ class xflashext(metaclass=LogBase):
|
||||||
return False
|
return False
|
||||||
data = unpack("<I", val)[0]
|
data = unpack("<I", val)[0]
|
||||||
if dwords == 1:
|
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
|
return data
|
||||||
res.append(data)
|
res.append(data)
|
||||||
else:
|
else:
|
||||||
|
@ -460,7 +460,7 @@ class xflashext(metaclass=LogBase):
|
||||||
self.error("Couldn't read rpmb.")
|
self.error("Couldn't read rpmb.")
|
||||||
return False
|
return False
|
||||||
wf.write(data)
|
wf.write(data)
|
||||||
self.info("Done reading rpmb to " + filename)
|
self.info(f"Done reading rpmb to {filename}")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -658,22 +658,22 @@ class xflashext(metaclass=LogBase):
|
||||||
pubk = self.read_pubk()
|
pubk = self.read_pubk()
|
||||||
if pubk is not None:
|
if pubk is not None:
|
||||||
retval["pubkey"] = pubk.hex()
|
retval["pubkey"] = pubk.hex()
|
||||||
self.info("PUBK : " + pubk.hex())
|
self.info(f"PUBK : {pubk.hex()}")
|
||||||
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
||||||
if meid is not None:
|
if meid is not None:
|
||||||
self.info("MEID : " + meid.hex())
|
self.info(f"MEID : {meid.hex()}")
|
||||||
retval["meid"] = meid.hex()
|
retval["meid"] = meid.hex()
|
||||||
self.config.hwparam.writesetting("meid", meid.hex())
|
self.config.hwparam.writesetting("meid", meid.hex())
|
||||||
if socid is not None:
|
if socid is not None:
|
||||||
self.info("SOCID : " + socid.hex())
|
self.info(f"SOCID : {socid.hex()}")
|
||||||
retval["socid"] = socid.hex()
|
retval["socid"] = socid.hex()
|
||||||
self.config.hwparam.writesetting("socid", socid.hex())
|
self.config.hwparam.writesetting("socid", socid.hex())
|
||||||
if hwcode is not None:
|
if hwcode is not None:
|
||||||
self.info("HWCODE : " + hex(hwcode))
|
self.info(f"HWCODE : {hex(hwcode)}")
|
||||||
retval["hwcode"] = hex(hwcode)
|
retval["hwcode"] = hex(hwcode)
|
||||||
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
||||||
if cid is not None:
|
if cid is not None:
|
||||||
self.info("CID : " + cid)
|
self.info(f"CID : {cid}")
|
||||||
retval["cid"] = cid
|
retval["cid"] = cid
|
||||||
if self.config.chipconfig.dxcc_base is not None:
|
if self.config.chipconfig.dxcc_base is not None:
|
||||||
self.info("Generating dxcc rpmbkey...")
|
self.info("Generating dxcc rpmbkey...")
|
||||||
|
@ -691,34 +691,34 @@ class xflashext(metaclass=LogBase):
|
||||||
# self.info("Provkey : " + provkey.hex())
|
# self.info("Provkey : " + provkey.hex())
|
||||||
# self.info("Platkey : " + platkey.hex())
|
# self.info("Platkey : " + platkey.hex())
|
||||||
if mirpmbkey is not None:
|
if mirpmbkey is not None:
|
||||||
self.info("MIRPMB : " + mirpmbkey.hex())
|
self.info(f"MIRPMB : {mirpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
|
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
|
||||||
retval["mirpmbkey"] = mirpmbkey.hex()
|
retval["mirpmbkey"] = mirpmbkey.hex()
|
||||||
if rpmbkey is not None:
|
if rpmbkey is not None:
|
||||||
self.info("RPMB : " + rpmbkey.hex())
|
self.info(f"RPMB : {rpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
||||||
retval["rpmbkey"] = rpmbkey.hex()
|
retval["rpmbkey"] = rpmbkey.hex()
|
||||||
if rpmb2key is not None:
|
if rpmb2key is not None:
|
||||||
self.info("RPMB2 : " + rpmb2key.hex())
|
self.info(f"RPMB2 : {rpmb2key.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
|
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
|
||||||
retval["rpmb2key"] = rpmb2key.hex()
|
retval["rpmb2key"] = rpmb2key.hex()
|
||||||
if fdekey is not None:
|
if fdekey is not None:
|
||||||
self.info("FDE : " + fdekey.hex())
|
self.info(f"FDE : {fdekey.hex()}")
|
||||||
self.config.hwparam.writesetting("fdekey", fdekey.hex())
|
self.config.hwparam.writesetting("fdekey", fdekey.hex())
|
||||||
retval["fdekey"] = fdekey.hex()
|
retval["fdekey"] = fdekey.hex()
|
||||||
if ikey is not None:
|
if ikey is not None:
|
||||||
self.info("iTrustee : " + ikey.hex())
|
self.info(f"iTrustee : {ikey.hex()}")
|
||||||
self.config.hwparam.writesetting("kmkey", ikey.hex())
|
self.config.hwparam.writesetting("kmkey", ikey.hex())
|
||||||
retval["kmkey"] = ikey.hex()
|
retval["kmkey"] = ikey.hex()
|
||||||
if self.config.chipconfig.prov_addr:
|
if self.config.chipconfig.prov_addr:
|
||||||
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
|
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())
|
self.config.hwparam.writesetting("provkey", provkey.hex())
|
||||||
retval["provkey"] = provkey.hex()
|
retval["provkey"] = provkey.hex()
|
||||||
hrid = self.xflash.get_hrid()
|
hrid = self.xflash.get_hrid()
|
||||||
rid = self.xflash.get_random_id()
|
rid = self.xflash.get_random_id()
|
||||||
if hrid is not None:
|
if hrid is not None:
|
||||||
self.info("HRID : " + hrid.hex())
|
self.info(f"HRID : {hrid.hex()}")
|
||||||
self.config.hwparam.writesetting("hrid", hrid.hex())
|
self.config.hwparam.writesetting("hrid", hrid.hex())
|
||||||
retval["hrid"] = hrid.hex()
|
retval["hrid"] = hrid.hex()
|
||||||
else:
|
else:
|
||||||
|
@ -727,19 +727,19 @@ class xflashext(metaclass=LogBase):
|
||||||
val += self.read_fuse(0xD)
|
val += self.read_fuse(0xD)
|
||||||
val += self.read_fuse(0xE)
|
val += self.read_fuse(0xE)
|
||||||
val += self.read_fuse(0xF)
|
val += self.read_fuse(0xF)
|
||||||
self.info("HRID : " + val.hex())
|
self.info(f"HRID : {val.hex()}")
|
||||||
self.config.hwparam.writesetting("hrid", val.hex())
|
self.config.hwparam.writesetting("hrid", val.hex())
|
||||||
retval["hrid"] = val.hex()
|
retval["hrid"] = val.hex()
|
||||||
|
|
||||||
if rid is not None:
|
if rid is not None:
|
||||||
self.info("RID : " + rid.hex())
|
self.info(f"RID : {rid.hex()}")
|
||||||
self.config.hwparam.writesetting("rid", rid.hex())
|
self.config.hwparam.writesetting("rid", rid.hex())
|
||||||
retval["rid"] = rid.hex()
|
retval["rid"] = rid.hex()
|
||||||
if hwcode == 0x699 and self.config.chipconfig.sej_base is not None:
|
if hwcode == 0x699 and self.config.chipconfig.sej_base is not None:
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
||||||
self.info("MTEE3 : " + mtee3.hex())
|
self.info(f"MTEE3 : {mtee3.hex()}")
|
||||||
retval["mtee3"] = mtee3.hex()
|
retval["mtee3"] = mtee3.hex()
|
||||||
return retval
|
return retval
|
||||||
elif self.config.chipconfig.sej_base is not None:
|
elif self.config.chipconfig.sej_base is not None:
|
||||||
|
@ -754,19 +754,19 @@ class xflashext(metaclass=LogBase):
|
||||||
self.setotp(hwc)
|
self.setotp(hwc)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
if rpmbkey:
|
if rpmbkey:
|
||||||
self.info("RPMB : " + rpmbkey.hex())
|
self.info(f"RPMB : {rpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
||||||
retval["rpmbkey"] = rpmbkey.hex()
|
retval["rpmbkey"] = rpmbkey.hex()
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
||||||
if mtee:
|
if mtee:
|
||||||
self.config.hwparam.writesetting("mtee", mtee.hex())
|
self.config.hwparam.writesetting("mtee", mtee.hex())
|
||||||
self.info("MTEE : " + mtee.hex())
|
self.info(f"MTEE : {mtee.hex()}")
|
||||||
retval["mtee"] = mtee.hex()
|
retval["mtee"] = mtee.hex()
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
||||||
self.info("MTEE3 : " + mtee3.hex())
|
self.info(f"MTEE3 : {mtee3.hex()}")
|
||||||
retval["mtee3"] = mtee3.hex()
|
retval["mtee3"] = mtee3.hex()
|
||||||
else:
|
else:
|
||||||
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
||||||
|
@ -775,7 +775,7 @@ class xflashext(metaclass=LogBase):
|
||||||
self.info("Generating gcpu mtee2 key...")
|
self.info("Generating gcpu mtee2 key...")
|
||||||
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
||||||
if mtee2 is not None:
|
if mtee2 is not None:
|
||||||
self.info("MTEE2 : " + mtee2.hex())
|
self.info(f"MTEE2 : {mtee2.hex()}")
|
||||||
self.config.hwparam.writesetting("mtee2", mtee2.hex())
|
self.config.hwparam.writesetting("mtee2", mtee2.hex())
|
||||||
retval["mtee2"] = mtee2.hex()
|
retval["mtee2"] = mtee2.hex()
|
||||||
return retval
|
return retval
|
||||||
|
|
|
@ -72,7 +72,8 @@ class DAXFlash(metaclass=LogBase):
|
||||||
except Exception:
|
except Exception:
|
||||||
self.carbonara = None
|
self.carbonara = None
|
||||||
|
|
||||||
def usleep(self, usec):
|
@staticmethod
|
||||||
|
def usleep(usec):
|
||||||
time.sleep(usec / 100000)
|
time.sleep(usec / 100000)
|
||||||
|
|
||||||
def ack(self, rstatus=True):
|
def ack(self, rstatus=True):
|
||||||
|
@ -108,7 +109,7 @@ class DAXFlash(metaclass=LogBase):
|
||||||
hdr = self.usbread(4 + 4 + 4)
|
hdr = self.usbread(4 + 4 + 4)
|
||||||
magic, datatype, length = unpack("<III", hdr)
|
magic, datatype, length = unpack("<III", hdr)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.error("xread error: " + str(err))
|
self.error(f"xread error: {str(err)}")
|
||||||
return -1
|
return -1
|
||||||
if magic != 0xFEEEEEEF:
|
if magic != 0xFEEEEEEF:
|
||||||
self.error("xread error: Wrong magic")
|
self.error("xread error: Wrong magic")
|
||||||
|
@ -353,8 +354,7 @@ class DAXFlash(metaclass=LogBase):
|
||||||
if self.daconfig.flashtype == "emmc":
|
if self.daconfig.flashtype == "emmc":
|
||||||
length = min(length, self.emmc.rpmb_size)
|
length = min(length, self.emmc.rpmb_size)
|
||||||
else:
|
else:
|
||||||
self.error("Unknown parttype. Known parttypes are \"boot1\",\"boot2\",\"gp1\"," +
|
self.error('Unknown parttype. Known parttypes are "boot1","boot2","gp1","gp2","gp3","gp4","rpmb"')
|
||||||
"\"gp2\",\"gp3\",\"gp4\",\"rpmb\"")
|
|
||||||
return []
|
return []
|
||||||
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
|
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
|
||||||
if parttype is None or parttype == "lu3" or parttype == "user": # USER
|
if parttype is None or parttype == "lu3" or parttype == "user": # USER
|
||||||
|
@ -370,7 +370,7 @@ class DAXFlash(metaclass=LogBase):
|
||||||
parttype = UFS_PartitionType.UFS_LU4
|
parttype = UFS_PartitionType.UFS_LU4
|
||||||
length = min(length, self.ufs.lu2_size)
|
length = min(length, self.ufs.lu2_size)
|
||||||
else:
|
else:
|
||||||
self.error("Unknown parttype. Known parttypes are \"lu1\",\"lu2\",\"lu3\",\"lu4\"")
|
self.error('Unknown parttype. Known parttypes are "lu1","lu2","lu3","lu4"')
|
||||||
return []
|
return []
|
||||||
elif storage in [DaStorage.MTK_DA_STORAGE_NAND, DaStorage.MTK_DA_STORAGE_NAND_MLC,
|
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,
|
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:
|
if self.daconfig.emi is None:
|
||||||
emmc_info = self.get_emmc_info(False)
|
emmc_info = self.get_emmc_info(False)
|
||||||
if emmc_info is not None and emmc_info.user_size != 0:
|
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:
|
else:
|
||||||
ufs_info = self.get_ufs_info()
|
ufs_info = self.get_ufs_info()
|
||||||
if ufs_info is not None and ufs_info.block_size != 0:
|
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")
|
self.info("No preloader given. Searching for preloader")
|
||||||
found = False
|
found = False
|
||||||
for root, dirs, files in os.walk(os.path.join(self.pathconfig.get_loader_path(), 'Preloader')):
|
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)")
|
self.error("Error on booting to da (xflash)")
|
||||||
return False
|
return False
|
||||||
else:
|
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
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ class xmlflashext(metaclass=LogBase):
|
||||||
self.error("Couldn't read rpmb.")
|
self.error("Couldn't read rpmb.")
|
||||||
return False
|
return False
|
||||||
wf.write(data)
|
wf.write(data)
|
||||||
self.info("Done reading rpmb to " + filename)
|
self.info(f"Done reading rpmb to {filename}")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -686,22 +686,22 @@ class xmlflashext(metaclass=LogBase):
|
||||||
pubk = self.read_pubk()
|
pubk = self.read_pubk()
|
||||||
if pubk is not None:
|
if pubk is not None:
|
||||||
retval["pubkey"] = pubk.hex()
|
retval["pubkey"] = pubk.hex()
|
||||||
self.info("PUBK : " + pubk.hex())
|
self.info(f"PUBK : {pubk.hex()}")
|
||||||
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
self.config.hwparam.writesetting("pubkey", pubk.hex())
|
||||||
if meid is not None:
|
if meid is not None:
|
||||||
self.info("MEID : " + meid.hex())
|
self.info(f"MEID : {meid.hex}")
|
||||||
retval["meid"] = meid.hex()
|
retval["meid"] = meid.hex()
|
||||||
self.config.hwparam.writesetting("meid", meid.hex())
|
self.config.hwparam.writesetting("meid", meid.hex())
|
||||||
if socid is not None:
|
if socid is not None:
|
||||||
self.info("SOCID : " + socid.hex())
|
self.info(f"SOCID : {socid.hex()}")
|
||||||
retval["socid"] = socid.hex()
|
retval["socid"] = socid.hex()
|
||||||
self.config.hwparam.writesetting("socid", socid.hex())
|
self.config.hwparam.writesetting("socid", socid.hex())
|
||||||
if hwcode is not None:
|
if hwcode is not None:
|
||||||
self.info("HWCODE : " + hex(hwcode))
|
self.info(f"HWCODE : {hex(hwcode)}")
|
||||||
retval["hwcode"] = hex(hwcode)
|
retval["hwcode"] = hex(hwcode)
|
||||||
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
self.config.hwparam.writesetting("hwcode", hex(hwcode))
|
||||||
if cid is not None:
|
if cid is not None:
|
||||||
self.info("CID : " + cid)
|
self.info(f"CID : {cid}")
|
||||||
retval["cid"] = cid
|
retval["cid"] = cid
|
||||||
if self.config.chipconfig.dxcc_base is not None:
|
if self.config.chipconfig.dxcc_base is not None:
|
||||||
self.info("Generating dxcc rpmbkey...")
|
self.info("Generating dxcc rpmbkey...")
|
||||||
|
@ -719,28 +719,28 @@ class xmlflashext(metaclass=LogBase):
|
||||||
# self.info("Provkey : " + provkey.hex())
|
# self.info("Provkey : " + provkey.hex())
|
||||||
# self.info("Platkey : " + platkey.hex())
|
# self.info("Platkey : " + platkey.hex())
|
||||||
if mirpmbkey is not None:
|
if mirpmbkey is not None:
|
||||||
self.info("MIRPMB : " + mirpmbkey.hex())
|
self.info(f"MIRPMB : {mirpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
|
self.config.hwparam.writesetting("mirpmbkey", mirpmbkey.hex())
|
||||||
retval["mirpmbkey"] = mirpmbkey.hex()
|
retval["mirpmbkey"] = mirpmbkey.hex()
|
||||||
if rpmbkey is not None:
|
if rpmbkey is not None:
|
||||||
self.info("RPMB : " + rpmbkey.hex())
|
self.info(f"RPMB : {rpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
||||||
retval["rpmbkey"] = rpmbkey.hex()
|
retval["rpmbkey"] = rpmbkey.hex()
|
||||||
if rpmb2key is not None:
|
if rpmb2key is not None:
|
||||||
self.info("RPMB2 : " + rpmb2key.hex())
|
self.info(f"RPMB2 : {rpmb2key.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
|
self.config.hwparam.writesetting("rpmb2key", rpmb2key.hex())
|
||||||
retval["rpmb2key"] = rpmb2key.hex()
|
retval["rpmb2key"] = rpmb2key.hex()
|
||||||
if fdekey is not None:
|
if fdekey is not None:
|
||||||
self.info("FDE : " + fdekey.hex())
|
self.info(f"FDE : {fdekey.hex()}")
|
||||||
self.config.hwparam.writesetting("fdekey", fdekey.hex())
|
self.config.hwparam.writesetting("fdekey", fdekey.hex())
|
||||||
retval["fdekey"] = fdekey.hex()
|
retval["fdekey"] = fdekey.hex()
|
||||||
if ikey is not None:
|
if ikey is not None:
|
||||||
self.info("iTrustee : " + ikey.hex())
|
self.info(f"iTrustee : {ikey.hex()}")
|
||||||
self.config.hwparam.writesetting("kmkey", ikey.hex())
|
self.config.hwparam.writesetting("kmkey", ikey.hex())
|
||||||
retval["kmkey"] = ikey.hex()
|
retval["kmkey"] = ikey.hex()
|
||||||
if self.config.chipconfig.prov_addr:
|
if self.config.chipconfig.prov_addr:
|
||||||
provkey = self.custom_read(self.config.chipconfig.prov_addr, 16)
|
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())
|
self.config.hwparam.writesetting("provkey", provkey.hex())
|
||||||
retval["provkey"] = provkey.hex()
|
retval["provkey"] = provkey.hex()
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@ class xmlflashext(metaclass=LogBase):
|
||||||
val += self.read_fuse(0xD)
|
val += self.read_fuse(0xD)
|
||||||
val += self.read_fuse(0xE)
|
val += self.read_fuse(0xE)
|
||||||
val += self.read_fuse(0xF)
|
val += self.read_fuse(0xF)
|
||||||
self.info("HRID : " + val.hex())
|
self.info(f"HRID : {val.hex()}")
|
||||||
self.config.hwparam.writesetting("hrid", val.hex())
|
self.config.hwparam.writesetting("hrid", val.hex())
|
||||||
retval["hrid"] = val.hex()
|
retval["hrid"] = val.hex()
|
||||||
|
|
||||||
|
@ -757,7 +757,7 @@ class xmlflashext(metaclass=LogBase):
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
||||||
self.info("MTEE3 : " + mtee3.hex())
|
self.info(f"MTEE3 : {mtee3.hex()}")
|
||||||
retval["mtee3"] = mtee3.hex()
|
retval["mtee3"] = mtee3.hex()
|
||||||
return retval
|
return retval
|
||||||
elif self.config.chipconfig.sej_base is not None:
|
elif self.config.chipconfig.sej_base is not None:
|
||||||
|
@ -772,19 +772,19 @@ class xmlflashext(metaclass=LogBase):
|
||||||
self.setotp(hwc)
|
self.setotp(hwc)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
if rpmbkey:
|
if rpmbkey:
|
||||||
self.info("RPMB : " + rpmbkey.hex())
|
self.info(f"RPMB : {rpmbkey.hex()}")
|
||||||
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
self.config.hwparam.writesetting("rpmbkey", rpmbkey.hex())
|
||||||
retval["rpmbkey"] = rpmbkey.hex()
|
retval["rpmbkey"] = rpmbkey.hex()
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
||||||
if mtee:
|
if mtee:
|
||||||
self.config.hwparam.writesetting("mtee", mtee.hex())
|
self.config.hwparam.writesetting("mtee", mtee.hex())
|
||||||
self.info("MTEE : " + mtee.hex())
|
self.info(f"MTEE : {mtee.hex()}")
|
||||||
retval["mtee"] = mtee.hex()
|
retval["mtee"] = mtee.hex()
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
self.config.hwparam.writesetting("mtee3", mtee3.hex())
|
||||||
self.info("MTEE3 : " + mtee3.hex())
|
self.info(f"MTEE3 : {mtee3.hex()}")
|
||||||
retval["mtee3"] = mtee3.hex()
|
retval["mtee3"] = mtee3.hex()
|
||||||
else:
|
else:
|
||||||
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
self.info("SEJ Mode: No meid found. Are you in brom mode ?")
|
||||||
|
@ -793,7 +793,7 @@ class xmlflashext(metaclass=LogBase):
|
||||||
self.info("Generating gcpu mtee2 key...")
|
self.info("Generating gcpu mtee2 key...")
|
||||||
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
mtee2 = hwc.aes_hwcrypt(btype="gcpu", mode="mtee")
|
||||||
if mtee2 is not None:
|
if mtee2 is not None:
|
||||||
self.info("MTEE2 : " + mtee2.hex())
|
self.info(f"MTEE2 : {mtee2.hex()}")
|
||||||
self.config.hwparam.writesetting("mtee2", mtee2.hex())
|
self.config.hwparam.writesetting("mtee2", mtee2.hex())
|
||||||
retval["mtee2"] = mtee2.hex()
|
retval["mtee2"] = mtee2.hex()
|
||||||
return retval
|
return retval
|
||||||
|
|
|
@ -14,7 +14,8 @@ class XMLCmd(metaclass=LogBase):
|
||||||
self.mtk = mtk
|
self.mtk = mtk
|
||||||
self.MAGIC = 0xFEEEEEEF
|
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>"
|
cmd = f"<?xml version=\"1.0\" encoding=\"utf-8\"?><da><version>{version}</version><command>CMD:{cmd}</command>"
|
||||||
if content is not None:
|
if content is not None:
|
||||||
for item in content:
|
for item in content:
|
||||||
|
@ -323,11 +324,13 @@ class XMLCmd(metaclass=LogBase):
|
||||||
cmd = self.create_cmd("WRITE-REGISTER", content)
|
cmd = self.create_cmd("WRITE-REGISTER", content)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def cmd_read_partition_name(self):
|
@staticmethod
|
||||||
|
def cmd_read_partition_name():
|
||||||
cmd = ""
|
cmd = ""
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def cmd_debug_ufs(self):
|
@staticmethod
|
||||||
|
def cmd_debug_ufs():
|
||||||
cmd = ""
|
cmd = ""
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
|
@ -708,7 +708,7 @@ class DAXML(metaclass=LogBase):
|
||||||
self.error("Couldn't find item key")
|
self.error("Couldn't find item key")
|
||||||
return data
|
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)
|
self.send_command(self.Cmd.cmd_get_sys_property(key=key, length=length), noack=True)
|
||||||
cmd, result = self.get_command_result()
|
cmd, result = self.get_command_result()
|
||||||
if type(result) is not upfile:
|
if type(result) is not upfile:
|
||||||
|
@ -783,8 +783,7 @@ class DAXML(metaclass=LogBase):
|
||||||
if self.daconfig.flashtype == "emmc":
|
if self.daconfig.flashtype == "emmc":
|
||||||
length = min(length, self.emmc.gp1_size)
|
length = min(length, self.emmc.gp1_size)
|
||||||
else:
|
else:
|
||||||
self.error("Unknown parttype. Known parttypes are \"boot1\",\"boot2\",\"gp1\"," +
|
self.error('Unknown parttype. Known parttypes are "boot1","boot2","gp1","gp2","gp3","gp4","rpmb"')
|
||||||
"\"gp2\",\"gp3\",\"gp4\",\"rpmb\"")
|
|
||||||
return []
|
return []
|
||||||
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
|
elif storage == DaStorage.MTK_DA_STORAGE_UFS:
|
||||||
if parttype is None or parttype == "lu3" or parttype == "user": # USER
|
if parttype is None or parttype == "lu3" or parttype == "user": # USER
|
||||||
|
|
|
@ -53,10 +53,7 @@ class Hashimoto(Exploitation, metaclass=LogBase):
|
||||||
if addr is None:
|
if addr is None:
|
||||||
addr = self.chipconfig.da_payload_addr
|
addr = self.chipconfig.da_payload_addr
|
||||||
if self.payload(payload, addr):
|
if self.payload(payload, addr):
|
||||||
if dontack:
|
if dontack or self.usbread(4) == pack(">I", ack):
|
||||||
return ack
|
|
||||||
result = self.usbread(4)
|
|
||||||
if result == pack(">I", ack):
|
|
||||||
return ack
|
return ack
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -71,10 +68,7 @@ class Hashimoto(Exploitation, metaclass=LogBase):
|
||||||
if filename is None:
|
if filename is None:
|
||||||
data = bytearray()
|
data = bytearray()
|
||||||
for addr in range(0x200000, 0x240000, 16):
|
for addr in range(0x200000, 0x240000, 16):
|
||||||
if not self.chipconfig.blacklist:
|
data.extend(self.hwcrypto.cqdma.mem_read(addr, 16, 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))
|
|
||||||
return data, filename
|
return data, filename
|
||||||
else:
|
else:
|
||||||
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
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,
|
print_progress(prog, 100, prefix='Progress:', suffix='Complete, addr %08X' % addr,
|
||||||
bar_length=50)
|
bar_length=50)
|
||||||
old = round(prog, 1)
|
old = round(prog, 1)
|
||||||
if not self.chipconfig.blacklist:
|
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, 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))
|
|
||||||
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -110,9 +101,6 @@ class Hashimoto(Exploitation, metaclass=LogBase):
|
||||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete, addr %08X' % addr,
|
print_progress(prog, 100, prefix='Progress:', suffix='Complete, addr %08X' % addr,
|
||||||
bar_length=50)
|
bar_length=50)
|
||||||
old = round(prog, 1)
|
old = round(prog, 1)
|
||||||
if not self.chipconfig.blacklist:
|
wf.write(self.hwcrypto.cqdma.mem_read(addr, 16, 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))
|
|
||||||
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -82,7 +82,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
self.mtk.preloader.display = False
|
self.mtk.preloader.display = False
|
||||||
if self.mtk.preloader.init(display=False):
|
if self.mtk.preloader.init(display=False):
|
||||||
self.mtk = self.mtk.crasher(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:
|
if self.linecode is None:
|
||||||
self.linecode = self.mtk.port.cdc.device.ctrl_transfer(0xA1, 0x21, 0, 0, 7) + array.array('B', [0])
|
self.linecode = self.mtk.port.cdc.device.ctrl_transfer(0xA1, 0x21, 0, 0, 7) + array.array('B', [0])
|
||||||
found, startaddr = self.newbrute(startaddr)
|
found, startaddr = self.newbrute(startaddr)
|
||||||
|
@ -92,8 +92,8 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
cpu = ""
|
cpu = ""
|
||||||
if self.mtk.config.cpu != "":
|
if self.mtk.config.cpu != "":
|
||||||
cpu = "_" + self.mtk.config.cpu
|
cpu = "_" + self.mtk.config.cpu
|
||||||
filename = "brom" + cpu + "_" + hex(self.mtk.config.hwcode)[2:] + ".bin"
|
filename = f"brom{cpu}_{hex(self.mtk.config.hwcode)[2:]}.bin"
|
||||||
self.info("Found " + hex(startaddr) + f", dumping bootrom to {filename}")
|
self.info(f"Found {hex(startaddr)}, dumping bootrom to {filename}")
|
||||||
self.dump_brom(filename, dump_ptr=startaddr)
|
self.dump_brom(filename, dump_ptr=startaddr)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -110,7 +110,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
udev._ctx.managed_claim_interface = lambda *args, **kwargs: None
|
udev._ctx.managed_claim_interface = lambda *args, **kwargs: None
|
||||||
except AttributeError as e:
|
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:
|
if dump:
|
||||||
try:
|
try:
|
||||||
|
@ -135,7 +135,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
|
|
||||||
for address in range(dump_ptr, 0xffff, 4):
|
for address in range(dump_ptr, 0xffff, 4):
|
||||||
if address % 0x100 == 0:
|
if address % 0x100 == 0:
|
||||||
self.info("Bruteforce, testing " + hex(address) + "...")
|
self.info(f"Bruteforce, testing {hex(address)}...")
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
self.kamakiri2(address - 5 + (3 - i))
|
self.kamakiri2(address - 5 + (3 - i))
|
||||||
try:
|
try:
|
||||||
|
@ -143,7 +143,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
return True, address
|
return True, address
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
try:
|
try:
|
||||||
self.info("Bruteforce, testing " + hex(address) + "...")
|
self.info(f"Bruteforce, testing {hex(address)}...")
|
||||||
self.mtk.preloader.read32(addr)
|
self.mtk.preloader.read32(addr)
|
||||||
except Exception:
|
except Exception:
|
||||||
return False, address + 4
|
return False, address + 4
|
||||||
|
@ -212,7 +212,7 @@ class Kamakiri2(Exploitation, metaclass=LogBase):
|
||||||
if result == pack(">I", ack):
|
if result == pack(">I", ack):
|
||||||
return ack
|
return ack
|
||||||
else:
|
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
|
return None
|
||||||
|
|
||||||
def patchda1_and_da2(self):
|
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 stat import S_IFDIR, S_IFREG
|
||||||
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 tempfile import NamedTemporaryFile
|
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):
|
class MtkDaFS(LoggingMixIn, Operations):
|
||||||
def __init__(self, da_handler, rw=False):
|
def __init__(self, da_handler, rw=False):
|
||||||
self.da_handler = da_handler
|
self.da_handler = da_handler
|
||||||
self.rw = rw
|
self.rw = rw
|
||||||
self.files = {}
|
self.files = {'/': dict(
|
||||||
|
|
||||||
self.files['/'] = dict(
|
|
||||||
st_mode=(S_IFDIR | 0o555),
|
st_mode=(S_IFDIR | 0o555),
|
||||||
st_ctime=time(),
|
st_ctime=time(),
|
||||||
st_mtime=time(),
|
st_mtime=time(),
|
||||||
st_atime=time(),
|
st_atime=time(),
|
||||||
st_nlink=2)
|
st_nlink=2), '/emmc_user.bin': dict(
|
||||||
self.files['/emmc_user.bin'] = dict(
|
|
||||||
st_mode=(S_IFREG | 0o777) if self.rw else (S_IFREG | 0o555),
|
st_mode=(S_IFREG | 0o777) if self.rw else (S_IFREG | 0o555),
|
||||||
st_ctime=time(),
|
st_ctime=time(),
|
||||||
st_mtime=time(),
|
st_mtime=time(),
|
||||||
st_atime=time(),
|
st_atime=time(),
|
||||||
st_nlink=2,
|
st_nlink=2,
|
||||||
st_size = self.da_handler.mtk.daloader.daconfig.flashsize)
|
st_size=self.da_handler.mtk.daloader.daconfig.flashsize), '/partitions': dict(
|
||||||
self.files['/partitions'] = dict(
|
|
||||||
st_mode=(S_IFDIR | 0o555),
|
st_mode=(S_IFDIR | 0o555),
|
||||||
st_ctime=time(),
|
st_ctime=time(),
|
||||||
st_mtime=time(),
|
st_mtime=time(),
|
||||||
st_atime=time(),
|
st_atime=time(),
|
||||||
st_nlink=2)
|
st_nlink=2)}
|
||||||
|
|
||||||
for part in self.da_handler.mtk.daloader.get_partition_data():
|
for part in self.da_handler.mtk.daloader.get_partition_data():
|
||||||
self.files[f'/partitions/{part.name}'] = dict(
|
self.files[f'/partitions/{part.name}'] = dict(
|
||||||
|
@ -41,35 +37,36 @@ class MtkDaFS(LoggingMixIn, Operations):
|
||||||
st_mtime=time(),
|
st_mtime=time(),
|
||||||
st_atime=time(),
|
st_atime=time(),
|
||||||
st_nlink=2,
|
st_nlink=2,
|
||||||
st_size = part.sectors*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)
|
offset=part.sector * self.da_handler.mtk.daloader.daconfig.pagesize)
|
||||||
|
|
||||||
def readdir(self, path, fh):
|
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):
|
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''
|
return b''
|
||||||
file_offset = 0
|
file_offset = 0
|
||||||
if 'offset' in self.files[path]:
|
if 'offset' in self.files[path]:
|
||||||
file_offset = self.files[path]['offset']
|
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)
|
return bytes(data)
|
||||||
|
|
||||||
def write(self, path, data, offset, fh):
|
def write(self, path, data, offset, fh):
|
||||||
if not self.rw:
|
if not self.rw:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if offset+len(data) > self.files[path]['st_size']:
|
if offset + len(data) > self.files[path]['st_size']:
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
file_offset = 0
|
file_offset = 0
|
||||||
if 'offset' in self.files[path]:
|
if 'offset' in self.files[path]:
|
||||||
file_offset = self.files[path]['offset']
|
file_offset = self.files[path]['offset']
|
||||||
|
|
||||||
with NamedTemporaryFile('rb+', buffering=0) as f_write:
|
with NamedTemporaryFile('rb+', buffering=0) as f_write:
|
||||||
f_write.write(data)
|
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)
|
return len(data)
|
||||||
|
|
||||||
def getattr(self, path, fh=None):
|
def getattr(self, path, fh=None):
|
||||||
|
|
|
@ -108,7 +108,7 @@ class hwcrypto(metaclass=LogBase):
|
||||||
elif mode == "sha256":
|
elif mode == "sha256":
|
||||||
return self.dxcc.generate_sha256(data=data)
|
return self.dxcc.generate_sha256(data=data)
|
||||||
else:
|
else:
|
||||||
self.error("Unknown aes_hwcrypt type: " + btype)
|
self.error(f"Unknown aes_hwcrypt type: {btype}")
|
||||||
self.error("aes_hwcrypt supported types are: sej")
|
self.error("aes_hwcrypt supported types are: sej")
|
||||||
return bytearray()
|
return bytearray()
|
||||||
|
|
||||||
|
|
|
@ -1050,7 +1050,8 @@ class dxcc(metaclass=LogBase):
|
||||||
def sasi_paldmaunmap(self, value1):
|
def sasi_paldmaunmap(self, value1):
|
||||||
return
|
return
|
||||||
|
|
||||||
def sasi_paldmamap(self, value1):
|
@staticmethod
|
||||||
|
def sasi_paldmamap(value1):
|
||||||
# value2=value1
|
# value2=value1
|
||||||
return value1
|
return value1
|
||||||
|
|
||||||
|
@ -1305,12 +1306,14 @@ class dxcc(metaclass=LogBase):
|
||||||
self.sasi_sb_adddescsequence(xdesc)
|
self.sasi_sb_adddescsequence(xdesc)
|
||||||
return self.SB_HalWaitDescCompletion() == 0
|
return self.SB_HalWaitDescCompletion() == 0
|
||||||
|
|
||||||
def mtee_decrypt(self, data):
|
@staticmethod
|
||||||
|
def mtee_decrypt(data):
|
||||||
key = bytes.fromhex("B936C14D95A99585073E5607784A51F7444B60D6BFD6110F76D004CCB7E1950E")
|
key = bytes.fromhex("B936C14D95A99585073E5607784A51F7444B60D6BFD6110F76D004CCB7E1950E")
|
||||||
skey = hashlib.sha256(key).digest()
|
skey = hashlib.sha256(key).digest()
|
||||||
return AES.new(key=skey[:16], iv=skey[16:], mode=AES.MODE_CBC).decrypt(data)
|
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")
|
key = bytes.fromhex("5C0E349A27DC46034C7B6744A378BD17")
|
||||||
iv = bytes.fromhex("A0B0924686447109F2D51DCDDC93458A")
|
iv = bytes.fromhex("A0B0924686447109F2D51DCDDC93458A")
|
||||||
ctr = Counter.new(128, initial_value=bytes_to_long(iv))
|
ctr = Counter.new(128, initial_value=bytes_to_long(iv))
|
||||||
|
|
|
@ -642,7 +642,7 @@ class GCpu(metaclass=LogBase):
|
||||||
self.aes_setup_cbc(addr, data)
|
self.aes_setup_cbc(addr, data)
|
||||||
|
|
||||||
def mtk_crypto_hmac_sha256_by_devkey_using_seed(self, seed, data):
|
def mtk_crypto_hmac_sha256_by_devkey_using_seed(self, seed, data):
|
||||||
dev_key = bytearray("\x00" * 16)
|
dev_key = bytearray(16)
|
||||||
self.init()
|
self.init()
|
||||||
if not self.load_hw_key(0x30):
|
if not self.load_hw_key(0x30):
|
||||||
self.memptr_set(0x12, seed)
|
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):
|
def mtk_crypto_hmac_sha256_by_devkey(self, data: bytearray, seed: bytearray):
|
||||||
if seed is None:
|
if seed is None:
|
||||||
seed = bytearray("\x00" * 16)
|
seed = bytearray(16)
|
||||||
dev_val = self.get_devinfo_with_index(12)
|
dev_val = self.get_devinfo_with_index(12)
|
||||||
seed = xor_data(seed, dev_val, 4)
|
seed = xor_data(seed, dev_val, 4)
|
||||||
dev_val = self.get_devinfo_with_index(13)
|
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'))
|
self.info("seed: " + hexlify(seed[:16]).decode('utf-8'))
|
||||||
return self.mtk_crypto_hmac_sha256_by_devkey_using_seed(seed, data)
|
return self.mtk_crypto_hmac_sha256_by_devkey_using_seed(seed, data)
|
||||||
|
|
||||||
def byteswap(self, data):
|
@staticmethod
|
||||||
|
def byteswap(data):
|
||||||
data = bytearray(data)
|
data = bytearray(data)
|
||||||
for i in range(0, len(data) // 2):
|
for i in range(0, len(data) // 2):
|
||||||
j = len(data) - i - 1
|
j = len(data) - i - 1
|
||||||
|
|
|
@ -184,7 +184,8 @@ class sej(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
self.__logger.setLevel(logging.INFO)
|
self.__logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
def uffs(self, x):
|
@staticmethod
|
||||||
|
def uffs(x):
|
||||||
v1 = x
|
v1 = x
|
||||||
if x & 0xFFFF:
|
if x & 0xFFFF:
|
||||||
result = 1
|
result = 1
|
||||||
|
@ -669,7 +670,8 @@ class sej(metaclass=LogBase):
|
||||||
hw_key = self.sej_do_aes(True, iv, swkey, 32)
|
hw_key = self.sej_do_aes(True, iv, swkey, 32)
|
||||||
self.sej_set_key(AES_HW_WRAP_KEY, AES_KEY_256, hw_key)
|
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
|
Left for reference - hw implementation
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
|
@ -116,7 +116,7 @@ class Port(metaclass=LogBase):
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
except Exception as serr:
|
except Exception as serr:
|
||||||
print("Handshake: " + str(serr))
|
print(f"Handshake: {str(serr)}")
|
||||||
if "access denied" in str(serr):
|
if "access denied" in str(serr):
|
||||||
self.warning(str(serr))
|
self.warning(str(serr))
|
||||||
self.debug(str(serr))
|
self.debug(str(serr))
|
||||||
|
@ -194,13 +194,13 @@ class Port(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
cmdrsp = self.usbread(dlen)
|
cmdrsp = self.usbread(dlen)
|
||||||
if cmdrsp[0] is not value[0]:
|
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
|
return -1
|
||||||
if bytestoread > 0:
|
if bytestoread > 0:
|
||||||
resp = self.usbread(bytestoread)
|
resp = self.usbread(bytestoread)
|
||||||
return resp
|
return resp
|
||||||
else:
|
else:
|
||||||
self.warning("Couldn't send :" + hexlify(value).decode('utf-8'))
|
self.warning(f"Couldn't send :{hexlify(value).decode('utf-8')}")
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def echo(self, data):
|
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_ARM, CS_MODE_THUMB, CS_MODE_V8, CS_MODE_V9,
|
||||||
CS_MODE_MCLASS, CS_MODE_MICRO, CS_MODE_MIPS32, CS_MODE_MIPS64,
|
CS_MODE_MCLASS, CS_MODE_MICRO, CS_MODE_MIPS32, CS_MODE_MIPS64,
|
||||||
CS_MODE_MIPS32R6, CS_MODE_16, CS_MODE_32, CS_MODE_64)
|
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_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_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,
|
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
|
little = KS_MODE_BIG_ENDIAN # big-endian mode
|
||||||
else:
|
else:
|
||||||
little = KS_MODE_LITTLE_ENDIAN # little-endian mode (default mode)
|
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
|
ks = None
|
||||||
if cpu == "arm":
|
if cpu == "arm":
|
||||||
# ARM architecture (including Thumb, Thumb-2)
|
# ARM architecture (including Thumb, Thumb-2)
|
||||||
|
@ -142,10 +143,8 @@ def disasm(code, cpu, mode, bigendian, size):
|
||||||
print("CPU and/or mode not supported!")
|
print("CPU and/or mode not supported!")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
instr = []
|
instr = [f"{i.mnemonic}\t{i.op_str}" for i in cs.disasm(code, size)]
|
||||||
for i in cs.disasm(code, size):
|
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
|
||||||
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
|
|
||||||
instr.append("%s\t%s" % (i.mnemonic, i.op_str))
|
|
||||||
return instr
|
return instr
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,7 +192,7 @@ def main():
|
||||||
print("[asmtools] Usage: -asm cpu,mode or -disasm cpu,mode")
|
print("[asmtools] Usage: -asm cpu,mode or -disasm cpu,mode")
|
||||||
exit(0)
|
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")
|
print("[asmtools] I must have an infile to work on (-in) or a string input (--inp")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
@ -251,4 +250,5 @@ def main():
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
main()
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
|
@ -76,7 +76,8 @@ class cryptutils:
|
||||||
class aes:
|
class aes:
|
||||||
# GF(2^128) defined by 1 + a + a^2 + a^7 + a^128
|
# GF(2^128) defined by 1 + a + a^2 + a^7 + a^128
|
||||||
# Please note the MSB is x0 and LSB is x127
|
# 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 x < (1 << 128)
|
||||||
assert y < (1 << 128)
|
assert y < (1 << 128)
|
||||||
res = 0
|
res = 0
|
||||||
|
@ -88,7 +89,7 @@ class cryptutils:
|
||||||
|
|
||||||
class AES_GCM:
|
class AES_GCM:
|
||||||
# Galois/Counter Mode with AES-128 and 96-bit IV
|
# Galois/Counter Mode with AES-128 and 96-bit IV
|
||||||
'''
|
"""
|
||||||
Example:
|
Example:
|
||||||
master_key = 0x0ADAABC70895E008147A48C27791F654 #54F69177C2487A1408E09508C7ABDA0A
|
master_key = 0x0ADAABC70895E008147A48C27791F654 #54F69177C2487A1408E09508C7ABDA0A
|
||||||
init_value = 0x2883B4173F9A838437C1CD86CCFAA5ED #EDA5FACC86CDC13784839A3F17B48328
|
init_value = 0x2883B4173F9A838437C1CD86CCFAA5ED #EDA5FACC86CDC13784839A3F17B48328
|
||||||
|
@ -122,7 +123,7 @@ class cryptutils:
|
||||||
b"\xA0\x62\x9E\xF9\xF4\xE7\xE8\x65"
|
b"\xA0\x62\x9E\xF9\xF4\xE7\xE8\x65"
|
||||||
my_gcm = AES_GCM(master_key)
|
my_gcm = AES_GCM(master_key)
|
||||||
decrypted = my_gcm.decrypt(init_value, ciphertext, auth_tag)
|
decrypted = my_gcm.decrypt(init_value, ciphertext, auth_tag)
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, master_key):
|
def __init__(self, master_key):
|
||||||
self.change_key(master_key)
|
self.change_key(master_key)
|
||||||
|
@ -248,7 +249,8 @@ class cryptutils:
|
||||||
|
|
||||||
return plaintext
|
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)
|
cipher = AES.new(aes_key, AES.MODE_GCM, nounce)
|
||||||
if hdr is not None:
|
if hdr is not None:
|
||||||
cipher.update(hdr)
|
cipher.update(hdr)
|
||||||
|
@ -268,30 +270,30 @@ class cryptutils:
|
||||||
ciphertext, tag_auth = cipher.encrypt_and_digest(input)
|
ciphertext, tag_auth = cipher.encrypt_and_digest(input)
|
||||||
return ciphertext, tag_auth
|
return ciphertext, tag_auth
|
||||||
|
|
||||||
def aes_cbc(self, key, iv, data, decrypt=True):
|
@staticmethod
|
||||||
|
def aes_cbc(key, iv, data, decrypt=True):
|
||||||
if decrypt:
|
if decrypt:
|
||||||
return AES.new(key, AES.MODE_CBC, IV=iv).decrypt(data)
|
return AES.new(key, AES.MODE_CBC, IV=iv).decrypt(data)
|
||||||
else:
|
else:
|
||||||
return AES.new(key, AES.MODE_CBC, IV=iv).encrypt(data)
|
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:
|
if decrypt:
|
||||||
return AES.new(key, AES.MODE_ECB).decrypt(data)
|
return AES.new(key, AES.MODE_ECB).decrypt(data)
|
||||||
else:
|
else:
|
||||||
return AES.new(key, AES.MODE_ECB).encrypt(data)
|
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)
|
ctr = Counter.new(128, initial_value=counter)
|
||||||
# Create the AES cipher object and decrypt the ciphertext, basically this here is just aes ctr 256 :)
|
# 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)
|
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
|
||||||
data = b""
|
data = cipher.decrypt(enc_data) if decrypt else cipher.encrypt(enc_data)
|
||||||
if decrypt:
|
|
||||||
data = cipher.decrypt(enc_data)
|
|
||||||
else:
|
|
||||||
data = cipher.encrypt(enc_data)
|
|
||||||
return 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)
|
cipher = AES.new(key, AES.MODE_CCM, nounce)
|
||||||
if decrypt:
|
if decrypt:
|
||||||
plaintext = cipher.decrypt(data)
|
plaintext = cipher.decrypt(data)
|
||||||
|
@ -304,6 +306,7 @@ class cryptutils:
|
||||||
ciphertext = cipher.encrypt(data)
|
ciphertext = cipher.encrypt(data)
|
||||||
return ciphertext
|
return ciphertext
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def aes_cmac_verify(key, plain, compare):
|
def aes_cmac_verify(key, plain, compare):
|
||||||
ctx = CMAC.new(key, ciphermod=AES)
|
ctx = CMAC.new(key, ciphermod=AES)
|
||||||
ctx.update(plain)
|
ctx.update(plain)
|
||||||
|
@ -347,12 +350,13 @@ class cryptutils:
|
||||||
else:
|
else:
|
||||||
print("Test failed.")
|
print("Test failed.")
|
||||||
|
|
||||||
def i2osp(self, x, x_len):
|
@staticmethod
|
||||||
'''Converts the integer x to its big-endian representation of length
|
def i2osp(x, x_len):
|
||||||
|
"""Converts the integer x to its big-endian representation of length
|
||||||
x_len.
|
x_len.
|
||||||
'''
|
"""
|
||||||
if x > 256 ** x_len:
|
if x > 256 ** x_len:
|
||||||
raise ("Integer Too Large")
|
raise "Integer Too Large"
|
||||||
h = hex(x)[2:]
|
h = hex(x)[2:]
|
||||||
if h[-1] == 'L':
|
if h[-1] == 'L':
|
||||||
h = h[:-1]
|
h = h[:-1]
|
||||||
|
@ -361,12 +365,12 @@ class cryptutils:
|
||||||
x = bytes.fromhex(h)
|
x = bytes.fromhex(h)
|
||||||
return b'\x00' * int(x_len - len(x)) + x
|
return b'\x00' * int(x_len - len(x)) + x
|
||||||
|
|
||||||
def os2ip(self, x):
|
@staticmethod
|
||||||
'''Converts the byte string x representing an integer reprented using the
|
def os2ip(x):
|
||||||
|
"""Converts the byte string x representing an integer reprented using the
|
||||||
big-endian convient to an integer.
|
big-endian convient to an integer.
|
||||||
'''
|
"""
|
||||||
h = hexlify(x)
|
return int(hexlify(x), 16)
|
||||||
return int(h, 16)
|
|
||||||
|
|
||||||
# def os2ip(self, X):
|
# def os2ip(self, X):
|
||||||
# return int.from_bytes(X, byteorder='big')
|
# return int.from_bytes(X, byteorder='big')
|
||||||
|
@ -374,13 +378,14 @@ class cryptutils:
|
||||||
def mgf1(self, input, length):
|
def mgf1(self, input, length):
|
||||||
counter = 0
|
counter = 0
|
||||||
output = b''
|
output = b''
|
||||||
while (len(output) < length):
|
while len(output) < length:
|
||||||
C = self.i2osp(counter, 4)
|
C = self.i2osp(counter, 4)
|
||||||
output += self.hash(input + C)
|
output += self.hash(input + C)
|
||||||
counter += 1
|
counter += 1
|
||||||
return output[:length]
|
return output[:length]
|
||||||
|
|
||||||
def assert_int(self, var: int, name: str):
|
@staticmethod
|
||||||
|
def assert_int(var: int, name: str):
|
||||||
if isinstance(var, int):
|
if isinstance(var, int):
|
||||||
return
|
return
|
||||||
raise TypeError('%s should be an integer, not %s' % (name, var.__class__))
|
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)
|
return self.sign(tosign, D, N, emBits)
|
||||||
# 6B1EAA2042A5C8DA8B1B4A8320111A70A0CBA65233D1C6E418EF8156E82A8F96BD843F047FF25AB9702A6582C8387298753E628F23448B4580E09CBD2A483C623B888F47C4BD2C5EFF09013C6DFF67DB59BAB3037F0BEE05D5660264D28CC6251631FE75CE106D931A04FA032FEA31259715CE0FAB1AE0E2F8130807AF4019A61B9C060ECE59104F22156FEE8108F17DC80D7C2F8397AFB9780994F7C5A0652F93D1B48010B0B248AB9711235787D797FBA4D10A29BCF09628585D405640A866B15EE9D7526A2703E72A19811EF447F6E5C43F915B3808EBC79EA4BCF78903DBDE32E47E239CFB5F2B5986D0CBBFBE6BACDC29B2ADE006D23D0B90775B1AE4DD
|
# 6B1EAA2042A5C8DA8B1B4A8320111A70A0CBA65233D1C6E418EF8156E82A8F96BD843F047FF25AB9702A6582C8387298753E628F23448B4580E09CBD2A483C623B888F47C4BD2C5EFF09013C6DFF67DB59BAB3037F0BEE05D5660264D28CC6251631FE75CE106D931A04FA032FEA31259715CE0FAB1AE0E2F8130807AF4019A61B9C060ECE59104F22156FEE8108F17DC80D7C2F8397AFB9780994F7C5A0652F93D1B48010B0B248AB9711235787D797FBA4D10A29BCF09628585D405640A866B15EE9D7526A2703E72A19811EF447F6E5C43F915B3808EBC79EA4BCF78903DBDE32E47E239CFB5F2B5986D0CBBFBE6BACDC29B2ADE006D23D0B90775B1AE4DD
|
||||||
|
|
||||||
def ceil_div(self, a, b):
|
@staticmethod
|
||||||
|
def ceil_div(a, b):
|
||||||
(q, r) = divmod(a, b)
|
(q, r) = divmod(a, b)
|
||||||
if r:
|
if r:
|
||||||
return q + 1
|
return q + 1
|
||||||
|
@ -494,10 +500,12 @@ class cryptutils:
|
||||||
return False
|
return False
|
||||||
return maskedDB
|
return maskedDB
|
||||||
|
|
||||||
def sha1(self, msg):
|
@staticmethod
|
||||||
|
def sha1(msg):
|
||||||
return hashlib.sha1(msg).digest()
|
return hashlib.sha1(msg).digest()
|
||||||
|
|
||||||
def sha256(self, msg):
|
@staticmethod
|
||||||
|
def sha256(msg):
|
||||||
return hashlib.sha256(msg).digest()
|
return hashlib.sha256(msg).digest()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -989,9 +989,9 @@ class ErrorHandler:
|
||||||
|
|
||||||
def status(self, status):
|
def status(self, status):
|
||||||
if status in self.ec:
|
if status in self.ec:
|
||||||
return self.ec[status] + " (" + hex(status) + ")"
|
return f"{self.ec[status]} ({hex(status)})"
|
||||||
if status in self.xec:
|
if status in self.xec:
|
||||||
return self.xec[status] + " (" + hex(status) + ")"
|
return f"{self.xec[status]} ({hex(status)})"
|
||||||
if status in self.lec:
|
if status in self.lec:
|
||||||
return self.lec[status] + " (" + hex(status) + ")"
|
return f"{self.lec[status]} ({hex(status)})"
|
||||||
return "Unknown: " + hex(status)
|
return f"Unknown: {hex(status)}"
|
||||||
|
|
|
@ -328,9 +328,8 @@ class gpt(metaclass=LogBase):
|
||||||
|
|
||||||
def print_gptfile(self, filename):
|
def print_gptfile(self, filename):
|
||||||
try:
|
try:
|
||||||
filesize = os.stat(filename).st_size
|
|
||||||
with open(filename, "rb") as rf:
|
with open(filename, "rb") as rf:
|
||||||
size = min(32 * 4096, filesize)
|
size = min(32 * 4096, os.stat(filename).st_size)
|
||||||
data = rf.read(size)
|
data = rf.read(size)
|
||||||
for sectorsize in [512, 4096]:
|
for sectorsize in [512, 4096]:
|
||||||
result = self.parse(data, sectorsize)
|
result = self.parse(data, sectorsize)
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Mtk(metaclass=LogBase):
|
||||||
idx = -1
|
idx = -1
|
||||||
else:
|
else:
|
||||||
data[idx:idx + len(patchval)] = patchval
|
data[idx:idx + len(patchval)] = patchval
|
||||||
self.info(f"Patched \"{patchval[2]}\" in preloader")
|
self.info(f'Patched "{patchval[2]}" in preloader')
|
||||||
patched = True
|
patched = True
|
||||||
else:
|
else:
|
||||||
pattern = bytes.fromhex(patchval[0])
|
pattern = bytes.fromhex(patchval[0])
|
||||||
|
@ -67,7 +67,7 @@ class Mtk(metaclass=LogBase):
|
||||||
if idx != -1:
|
if idx != -1:
|
||||||
patch = bytes.fromhex(patchval[1])
|
patch = bytes.fromhex(patchval[1])
|
||||||
data[idx:idx + len(patch)] = patch
|
data[idx:idx + len(patch)] = patch
|
||||||
self.info(f"Patched \"{patchval[2]}\" in preloader")
|
self.info(f'Patched "{patchval[2]}" in preloader')
|
||||||
patched = True
|
patched = True
|
||||||
# break
|
# break
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -101,7 +101,7 @@ class Mtk(metaclass=LogBase):
|
||||||
if idx != -1:
|
if idx != -1:
|
||||||
patch = bytes.fromhex(patchval[1])
|
patch = bytes.fromhex(patchval[1])
|
||||||
data[idx:idx + len(patch)] = patch
|
data[idx:idx + len(patch)] = patch
|
||||||
self.info(f"Patched \"{patchval[2]}\" in preloader")
|
self.info(f'Patched "{patchval[2]}" in preloader')
|
||||||
patched = True
|
patched = True
|
||||||
# break
|
# break
|
||||||
i += 1
|
i += 1
|
||||||
|
|
|
@ -166,7 +166,8 @@ class Main(metaclass=LogBase):
|
||||||
if not os.path.exists("logs"):
|
if not os.path.exists("logs"):
|
||||||
os.mkdir("logs")
|
os.mkdir("logs")
|
||||||
|
|
||||||
def close(self):
|
@staticmethod
|
||||||
|
def close():
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def cmd_stage(self, mtk, filename, stage2addr, stage2file, verifystage2):
|
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):
|
for pos in range(offset, offset + length, rlen):
|
||||||
print("Reading pos %08X" % pos)
|
print("Reading pos %08X" % pos)
|
||||||
res = mtk.preloader.read32(pos, rlen // 4)
|
res = mtk.preloader.read32(pos, rlen // 4)
|
||||||
if res == []:
|
if not res:
|
||||||
break
|
break
|
||||||
print(hexlify(b"".join([pack("<I", val) for val in res])).decode('utf-8'))
|
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"":
|
if logs != b"":
|
||||||
with open(filename, "wb") as wf:
|
with open(filename, "wb") as wf:
|
||||||
wf.write(logs)
|
wf.write(logs)
|
||||||
self.info(f"Successfully wrote logs to \"{filename}\"")
|
self.info(f'Successfully wrote logs to "{filename}"')
|
||||||
else:
|
else:
|
||||||
self.info("No logs found.")
|
self.info("No logs found.")
|
||||||
|
|
||||||
|
|
|
@ -1311,7 +1311,8 @@ class Preloader(metaclass=LogBase):
|
||||||
self.config.is_brom = False
|
self.config.is_brom = False
|
||||||
return b""
|
return b""
|
||||||
|
|
||||||
def prepare_data(self, data, sigdata=b"", maxsize=0):
|
@staticmethod
|
||||||
|
def prepare_data(data, sigdata=b"", maxsize=0):
|
||||||
gen_chksum = 0
|
gen_chksum = 0
|
||||||
data = (data[:maxsize] + sigdata)
|
data = (data[:maxsize] + sigdata)
|
||||||
if len(data + sigdata) % 2 != 0:
|
if len(data + sigdata) % 2 != 0:
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Partition(metaclass=LogBase):
|
||||||
pm.sectors = partinfo.size // self.config.pagesize
|
pm.sectors = partinfo.size // self.config.pagesize
|
||||||
pm.type = 1
|
pm.type = 1
|
||||||
pm.flags = partinfo.mask_flags
|
pm.flags = partinfo.mask_flags
|
||||||
partitions.add(pm)
|
partitions.append(pm)
|
||||||
return data, partitions
|
return data, partitions
|
||||||
return b"", None
|
return b"", None
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class Partition(metaclass=LogBase):
|
||||||
return data, guid_gpt
|
return data, guid_gpt
|
||||||
|
|
||||||
def get_backup_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba,
|
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)
|
data = self.readflash(addr=0, length=2 * self.config.pagesize, filename="", parttype=parttype, display=False)
|
||||||
if data == b"":
|
if data == b"":
|
||||||
return data
|
return data
|
||||||
|
|
|
@ -76,7 +76,7 @@ class PLTools(metaclass=LogBase):
|
||||||
|
|
||||||
ack = self.exploit.runpayload(payload, ack, addr, dontack)
|
ack = self.exploit.runpayload(payload, ack, addr, dontack)
|
||||||
if ack == ack:
|
if ack == ack:
|
||||||
self.info("Successfully sent payload: " + filename)
|
self.info(f"Successfully sent payload: {filename}")
|
||||||
self.mtk.daloader.patch = True
|
self.mtk.daloader.patch = True
|
||||||
return True
|
return True
|
||||||
elif ack == b"\xc1\xc2\xc3\xc4":
|
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)
|
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||||
for pos in range(0, 0x40000, 64):
|
for pos in range(0, 0x40000, 64):
|
||||||
wf.write(self.mtk.port.usbread(64))
|
wf.write(self.mtk.port.usbread(64))
|
||||||
self.info("Preloader dumped as: " + "preloader.bin")
|
self.info("Preloader dumped as: preloader.bin")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
with open("out.bin", 'wb') as wf:
|
with open("out.bin", 'wb') as wf:
|
||||||
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||||
for pos in range(0, 0x20000, 64):
|
for pos in range(0, 0x20000, 64):
|
||||||
wf.write(self.mtk.port.usbread(64))
|
wf.write(self.mtk.port.usbread(64))
|
||||||
self.info("Bootrom dumped as: " + "out.bin")
|
self.info("Bootrom dumped as: out.bin")
|
||||||
return True
|
return True
|
||||||
self.error("Error on sending payload: " + filename)
|
self.error(f"Error on sending payload: {filename}")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.error("Error on sending payload: " + filename)
|
self.error(f"Error on sending payload: {filename}")
|
||||||
self.error("Error, payload answered instead: " + hexlify(ack).decode('utf-8'))
|
self.error(f"Error, payload answered instead: {hexlify(ack).decode('utf-8')}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def runbrute(self, args):
|
def runbrute(self, args):
|
||||||
|
@ -138,16 +138,16 @@ class PLTools(metaclass=LogBase):
|
||||||
self.info("Kamakiri / DA Run")
|
self.info("Kamakiri / DA Run")
|
||||||
if self.runpayload(filename=pfilename, ack=0xC1C2C3C4, offset=0):
|
if self.runpayload(filename=pfilename, ack=0xC1C2C3C4, offset=0):
|
||||||
if self.exploit.dump_brom(filename):
|
if self.exploit.dump_brom(filename):
|
||||||
self.info("Dumped as: " + filename)
|
self.info(f"Dumped as:{filename} ")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.error("Error on sending payload: " + filename)
|
self.error(f"Error on sending payload: {filename}")
|
||||||
else:
|
else:
|
||||||
if self.exploit.dump_brom(filename, length=length):
|
if self.exploit.dump_brom(filename, length=length):
|
||||||
self.info("Dumped as: " + filename)
|
self.info(f"Dumped as: {filename}")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.error("Error on sending payload: " + pfilename)
|
self.error(f"Error on sending payload: {pfilename}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def run_dump_preloader(self, filename):
|
def run_dump_preloader(self, filename):
|
||||||
|
@ -158,11 +158,11 @@ class PLTools(metaclass=LogBase):
|
||||||
data, filename = self.exploit.dump_preloader()
|
data, filename = self.exploit.dump_preloader()
|
||||||
return data, filename
|
return data, filename
|
||||||
else:
|
else:
|
||||||
self.error("Error on sending payload: " + pfilename)
|
self.error(f"Error on sending payload: {pfilename}")
|
||||||
return None, None
|
return None, None
|
||||||
else:
|
else:
|
||||||
if self.exploit.dump_brom(filename):
|
if self.exploit.dump_brom(filename):
|
||||||
self.info("Preloader dumped as: " + filename)
|
self.info(f"Preloader dumped as: {filename}")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.error("Error on dumping preloader")
|
self.error("Error on dumping preloader")
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# (c) B.Kerler 2018-2023
|
# (c) B.Kerler 2018-2023
|
||||||
import sys
|
import codecs
|
||||||
|
import copy
|
||||||
|
import datetime as dt
|
||||||
|
import io
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import codecs
|
|
||||||
import struct
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import stat
|
import stat
|
||||||
import colorama
|
import struct
|
||||||
import copy
|
import sys
|
||||||
import time
|
import time
|
||||||
import io
|
|
||||||
import datetime as dt
|
|
||||||
from struct import unpack, pack
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from struct import unpack, pack
|
||||||
|
|
||||||
|
import colorama
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from capstone import Cs, CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN
|
from capstone import Cs, CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN
|
||||||
|
@ -154,10 +155,11 @@ class progress:
|
||||||
else:
|
else:
|
||||||
self.guiprogress = None
|
self.guiprogress = None
|
||||||
|
|
||||||
def calcProcessTime(self, starttime, cur_iter, max_iter):
|
@staticmethod
|
||||||
|
def calcProcessTime(starttime, cur_iter, max_iter):
|
||||||
telapsed = time.time() - starttime
|
telapsed = time.time() - starttime
|
||||||
if telapsed > 0 and cur_iter > 0:
|
if telapsed > 0 and cur_iter > 0:
|
||||||
testimated = (telapsed / cur_iter) * (max_iter)
|
testimated = (telapsed / cur_iter) * max_iter
|
||||||
finishtime = starttime + testimated
|
finishtime = starttime + testimated
|
||||||
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
|
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
|
||||||
lefttime = testimated - telapsed # in seconds
|
lefttime = testimated - telapsed # in seconds
|
||||||
|
@ -207,21 +209,22 @@ class progress:
|
||||||
if lefttime > 0:
|
if lefttime > 0:
|
||||||
sec = lefttime
|
sec = lefttime
|
||||||
if sec > 60:
|
if sec > 60:
|
||||||
min = sec // 60
|
minutes = sec // 60
|
||||||
sec = sec % 60
|
sec = sec % 60
|
||||||
if min > 60:
|
if minutes > 60:
|
||||||
h = min // 24
|
h = minutes // 24
|
||||||
min = min % 24
|
minutes = minutes % 24
|
||||||
hinfo = "%02dh:%02dm:%02ds left" % (h, min, sec)
|
hinfo = "%02dh:%02dm:%02ds left" % (h, minutes, sec)
|
||||||
else:
|
else:
|
||||||
hinfo = "%02dm:%02ds left" % (min, sec)
|
hinfo = "%02dm:%02ds left" % (minutes, sec)
|
||||||
else:
|
else:
|
||||||
hinfo = "%02ds left" % sec
|
hinfo = "%02ds left" % sec
|
||||||
|
|
||||||
print_progress(prog, 100, prefix='Progress:',
|
print_progress(prog, 100, prefix='Progress:',
|
||||||
suffix=prefix + f' (Sector 0x%X of 0x%X, {hinfo}) %0.2f MB/s' % (pos // self.pagesize,
|
suffix=prefix + f' (Sector 0x%X of 0x%X, {hinfo}) %0.2f MB/s' % (pos // self.pagesize,
|
||||||
total // self.pagesize,
|
total // self.pagesize,
|
||||||
throughput), bar_length=50)
|
throughput),
|
||||||
|
bar_length=50)
|
||||||
self.prog = prog
|
self.prog = prog
|
||||||
self.progpos = pos
|
self.progpos = pos
|
||||||
self.progtime = t0
|
self.progtime = t0
|
||||||
|
@ -301,7 +304,7 @@ def do_tcp_server(client, arguments, handler):
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
port = int(arguments.tcpport)
|
port = int(arguments.tcpport)
|
||||||
server_address = ('localhost', port)
|
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.bind(server_address)
|
||||||
sock.listen(1)
|
sock.listen(1)
|
||||||
response = None
|
response = None
|
||||||
|
@ -314,24 +317,20 @@ def do_tcp_server(client, arguments, handler):
|
||||||
data = connection.recv(4096).decode('utf-8')
|
data = connection.recv(4096).decode('utf-8')
|
||||||
if data == '':
|
if data == '':
|
||||||
break
|
break
|
||||||
print('received %s' % data)
|
print(f'received {data}')
|
||||||
if data:
|
if data:
|
||||||
print('handling request')
|
print('handling request')
|
||||||
lines = data.split("\n")
|
lines = data.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if ":" in line:
|
if ":" in line:
|
||||||
cmd = line.split(":")[0]
|
cmd = line.split(":")[0]
|
||||||
marguments = line.split(":")[1]
|
|
||||||
try:
|
try:
|
||||||
opts = parse_args(cmd, marguments, arguments)
|
opts = parse_args(cmd, line.split(":")[1], arguments)
|
||||||
except Exception:
|
except Exception:
|
||||||
response = "Wrong arguments\n<NAK>\n"
|
response = "Wrong arguments\n<NAK>\n"
|
||||||
opts = None
|
opts = None
|
||||||
if opts is not None:
|
if opts is not None:
|
||||||
if handler(cmd, opts):
|
response = "<ACK>\n" if handler(cmd, opts) else "<NAK>\n"
|
||||||
response = "<ACK>\n"
|
|
||||||
else:
|
|
||||||
response = "<NAK>\n"
|
|
||||||
connection.sendall(bytes(response, 'utf-8'))
|
connection.sendall(bytes(response, 'utf-8'))
|
||||||
finally:
|
finally:
|
||||||
connection.close()
|
connection.close()
|
||||||
|
@ -339,11 +338,7 @@ def do_tcp_server(client, arguments, handler):
|
||||||
|
|
||||||
def parse_args(cmd, args, mainargs):
|
def parse_args(cmd, args, mainargs):
|
||||||
options = {}
|
options = {}
|
||||||
opts = None
|
opts = args.split(",") if "," in args else [args]
|
||||||
if "," in args:
|
|
||||||
opts = args.split(",")
|
|
||||||
else:
|
|
||||||
opts = [args]
|
|
||||||
for arg in mainargs:
|
for arg in mainargs:
|
||||||
if "--" in arg:
|
if "--" in arg:
|
||||||
options[arg] = mainargs[arg]
|
options[arg] = mainargs[arg]
|
||||||
|
@ -488,8 +483,8 @@ class LogBase(type):
|
||||||
|
|
||||||
def __init__(cls, *args):
|
def __init__(cls, *args):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
logger_attribute_name = '_' + cls.__name__ + '__logger'
|
logger_attribute_name = f'_{cls.__name__}__logger'
|
||||||
logger_debuglevel_name = '_' + cls.__name__ + '__debuglevel'
|
logger_debuglevel_name = f'_{cls.__name__}__debuglevel'
|
||||||
logger_name = '.'.join([c.__name__ for c in cls.mro()[-2::-1]])
|
logger_name = '.'.join([c.__name__ for c in cls.mro()[-2::-1]])
|
||||||
LOG_CONFIG = {
|
LOG_CONFIG = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
|
@ -603,7 +598,7 @@ class elf:
|
||||||
elif self.elfclass == 2: # 64Bit
|
elif self.elfclass == 2: # 64Bit
|
||||||
start = 0x34
|
start = 0x34
|
||||||
else:
|
else:
|
||||||
print("Error on parsing " + self.filename)
|
print(f"Error on parsing {self.filename}")
|
||||||
return ['', '']
|
return ['', '']
|
||||||
elfheadersize, programheaderentrysize, programheaderentrycount = struct.unpack("<HHH",
|
elfheadersize, programheaderentrysize, programheaderentrycount = struct.unpack("<HHH",
|
||||||
self.data[start:start + 3 * 2])
|
self.data[start:start + 3 * 2])
|
||||||
|
@ -625,7 +620,8 @@ class patchtools:
|
||||||
def __init__(self, bdebug=False):
|
def __init__(self, bdebug=False):
|
||||||
self.bDebug = bdebug
|
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']
|
badchars = [b'\x00', b'\n', b'\r', b'\x08', b'\x7f', b'\x20', b'\x09']
|
||||||
for idx, c in enumerate(data):
|
for idx, c in enumerate(data):
|
||||||
c = bytes([c])
|
c = bytes([c])
|
||||||
|
@ -642,7 +638,7 @@ class patchtools:
|
||||||
badchars = self.has_bad_uart_chars(data)
|
badchars = self.has_bad_uart_chars(data)
|
||||||
if not badchars:
|
if not badchars:
|
||||||
badchars = self.has_bad_uart_chars(data2)
|
badchars = self.has_bad_uart_chars(data2)
|
||||||
if not (badchars):
|
if not badchars:
|
||||||
return div
|
return div
|
||||||
div += 4
|
div += 4
|
||||||
|
|
||||||
|
@ -665,19 +661,17 @@ class patchtools:
|
||||||
abase = ((offset + div) & 0xFFFF0000) >> 16
|
abase = ((offset + div) & 0xFFFF0000) >> 16
|
||||||
a = ((offset + div) & 0xFFFF)
|
a = ((offset + div) & 0xFFFF)
|
||||||
strasm = ""
|
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:
|
if div > 0:
|
||||||
strasm += "# " + hex(offset) + "\n"
|
strasm += f"sub {reg}, {reg}, #{hex(div)};\n"
|
||||||
strasm += "mov " + reg + ", #" + hex(a) + ";\n"
|
|
||||||
strasm += "movk " + reg + ", #" + hex(abase) + ", LSL#16;\n"
|
|
||||||
strasm += "sub " + reg + ", " + reg + ", #" + hex(div) + ";\n"
|
|
||||||
else:
|
else:
|
||||||
strasm += "# " + hex(offset) + "\n"
|
strasm += f"add {reg}, {reg}, #{hex(-div)};\n"
|
||||||
strasm += "mov " + reg + ", #" + hex(a) + ";\n"
|
|
||||||
strasm += "movk " + reg + ", #" + hex(abase) + ", LSL#16;\n"
|
|
||||||
strasm += "add " + reg + ", " + reg + ", #" + hex(-div) + ";\n"
|
|
||||||
return strasm
|
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']
|
badchars = [b'\x00', b'\n', b'\r', b'\x08', b'\x7f', b'\x20', b'\x09']
|
||||||
for idx, c in enumerate(sc):
|
for idx, c in enumerate(sc):
|
||||||
c = bytes([c])
|
c = bytes([c])
|
||||||
|
@ -687,12 +681,11 @@ class patchtools:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def disasm(self, code, size):
|
@staticmethod
|
||||||
|
def disasm(code, size):
|
||||||
cs = Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
|
cs = Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
|
||||||
instr = []
|
instr = [f"{i.mnemonic}\t{i.op_str}" for i in cs.disasm(code, size)]
|
||||||
for i in cs.disasm(code, size):
|
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
|
||||||
# print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
|
|
||||||
instr.append("%s\t%s" % (i.mnemonic, i.op_str))
|
|
||||||
return instr
|
return instr
|
||||||
|
|
||||||
def assembler(self, code):
|
def assembler(self, code):
|
||||||
|
@ -735,7 +728,8 @@ class patchtools:
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def find_binary(self, data, strf, pos=0):
|
@staticmethod
|
||||||
|
def find_binary(data, strf, pos=0):
|
||||||
t = strf.split(b".")
|
t = strf.split(b".")
|
||||||
pre = 0
|
pre = 0
|
||||||
offsets = []
|
offsets = []
|
||||||
|
@ -752,7 +746,7 @@ class patchtools:
|
||||||
continue
|
continue
|
||||||
rt += 1
|
rt += 1
|
||||||
prep = data[rt:].find(t[i])
|
prep = data[rt:].find(t[i])
|
||||||
if (prep != 0):
|
if prep != 0:
|
||||||
error = 1
|
error = 1
|
||||||
break
|
break
|
||||||
rt += len(t[i])
|
rt += len(t[i])
|
||||||
|
@ -766,7 +760,7 @@ class patchtools:
|
||||||
return None
|
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.
|
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)))
|
filled_length = int(round(bar_length * iteration / float(total)))
|
||||||
bar = '█' * filled_length + '-' * (bar_length - filled_length)
|
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:
|
if iteration == total:
|
||||||
sys.stdout.write('\n')
|
sys.stdout.write('\n')
|
||||||
|
|
|
@ -48,7 +48,7 @@ def ldr_lit(curpc, instr):
|
||||||
|
|
||||||
def ldr_imm(instr):
|
def ldr_imm(instr):
|
||||||
simm5 = (instr >> 6) & 0x1F
|
simm5 = (instr >> 6) & 0x1F
|
||||||
sRt = (instr) & 0x7
|
sRt = instr & 0x7
|
||||||
sRn = (instr >> 3) & 0x7
|
sRn = (instr >> 3) & 0x7
|
||||||
return simm5, sRt, sRn
|
return simm5, sRt, sRn
|
||||||
|
|
||||||
|
@ -59,28 +59,27 @@ def main():
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
with open(sys.argv[1], "rb") as rf:
|
with open(sys.argv[1], "rb") as rf:
|
||||||
print()
|
print()
|
||||||
print("Using : " + sys.argv[1])
|
print(f"Using : {sys.argv[1]}")
|
||||||
data = rf.read()
|
data = rf.read()
|
||||||
base = 0
|
base = 0
|
||||||
mpos = find_binary(data, b"\xA0\x0A\x50\x05.\x00\x00\x00", 0)
|
mpos = find_binary(data, b"\xA0\x0A\x50\x05.\x00\x00\x00", 0)
|
||||||
usbdl_get_dword=None
|
usbdl_get_dword = None
|
||||||
usbdl_put_dword=None
|
usbdl_put_dword = None
|
||||||
usbdl_put_word=None
|
|
||||||
if mpos is not None:
|
if mpos is not None:
|
||||||
usbdl_put_data = unpack("<I", data[mpos - 0xC:mpos - 0xC + 4])[0]
|
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_get_data = unpack("<I", data[mpos - 0x10:mpos - 0x10 + 4])[0]
|
||||||
usbdl_put_dword = unpack("<I", data[mpos - 0x14:mpos - 0x14 + 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_get_dword = unpack("<I", data[mpos - 0x18:mpos - 0x18 + 4])[0]
|
||||||
usbdl_put_word = unpack("<I", data[mpos - 0x1C:mpos - 0x1C + 4])[0]
|
usbdl_put_word = unpack("<I", data[mpos - 0x1C:mpos - 0x1C + 4])[0]
|
||||||
else:
|
else:
|
||||||
usbdl_get_data = find_binary(data,"2DE9F04780460F46")
|
usbdl_get_data = find_binary(data, "2DE9F04780460F46")
|
||||||
usbdl_put_data = find_binary(data,"10B5064AD4689368")
|
usbdl_put_data = find_binary(data, "10B5064AD4689368")
|
||||||
usbdl_put_word = find_binary(data, b"\x2D\xE9\xF8\x4F\x80\x46\x8a\x46.\x48")
|
usbdl_put_word = find_binary(data, b"\x2D\xE9\xF8\x4F\x80\x46\x8a\x46.\x48")
|
||||||
|
|
||||||
usbdl_ptr = None
|
usbdl_ptr = None
|
||||||
if usbdl_put_word:
|
if usbdl_put_word:
|
||||||
mpos=(usbdl_put_word&0xFFFFF)+7
|
mpos = (usbdl_put_word & 0xFFFFF) + 7
|
||||||
offset, Rn = ldr_lit(mpos,
|
offset, Rn = ldr_lit(mpos,
|
||||||
unpack("<H", data[mpos:mpos + 2])[0])
|
unpack("<H", data[mpos:mpos + 2])[0])
|
||||||
usbdl_ptr = (base | offset)
|
usbdl_ptr = (base | offset)
|
||||||
|
@ -96,82 +95,82 @@ def main():
|
||||||
pos -= 0x4
|
pos -= 0x4
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 1
|
pos += 1
|
||||||
send_usb_response=base|pos
|
send_usb_response = base | pos
|
||||||
pos = find_binary(data, b"\x10\xB5.\xF0...\x46", 0)
|
pos = find_binary(data, b"\x10\xB5.\xF0...\x46", 0)
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos = find_binary(data, b"\xB5.\xF0...\x49", 0)
|
pos = find_binary(data, b"\xB5.\xF0...\x49", 0)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos-=1
|
pos -= 1
|
||||||
else:
|
else:
|
||||||
pos2 = find_binary(data, "46FFF7", pos + 8)
|
pos2 = find_binary(data, "46FFF7", pos + 8)
|
||||||
if pos2 != None:
|
if pos2 is not None:
|
||||||
if pos2 - pos < 0x20:
|
if pos2 - pos < 0x20:
|
||||||
pos = pos
|
pos = pos
|
||||||
else:
|
else:
|
||||||
pos = pos2 - 1
|
pos = pos2 - 1
|
||||||
posr = -1
|
posr = -1
|
||||||
startpos = 0
|
startpos = 0
|
||||||
while posr != None:
|
while posr is not None:
|
||||||
posr = find_binary(data, "2DE9F047", startpos)
|
posr = find_binary(data, "2DE9F047", startpos)
|
||||||
if posr == None:
|
if posr is None:
|
||||||
break
|
break
|
||||||
if data[posr + 7] == 0x46 and data[posr + 8] == 0x92:
|
if data[posr + 7] == 0x46 and data[posr + 8] == 0x92:
|
||||||
break
|
break
|
||||||
startpos = posr + 2
|
startpos = posr + 2
|
||||||
|
|
||||||
pattern = b"\xB5.\xF0"
|
pattern = b"\xB5.\xF0"
|
||||||
sla=None
|
sla = None
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
sbcpos = pos
|
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)
|
pos = find_binary(data, pattern, pos + 8)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos -= 1
|
pos -= 1
|
||||||
print("sla:\t\t\t\t\t\t0x%08X" % (base|pos))
|
print("sla:\t\t\t\t\t\t0x%08X" % (base | pos))
|
||||||
sla=pos
|
sla = pos
|
||||||
if pos is not None:
|
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:
|
if pos is not None:
|
||||||
pos -= 1
|
pos -= 1
|
||||||
print("daa:\t\t\t\t\t\t0x%08X" % (base|pos))
|
print("daa:\t\t\t\t\t\t0x%08X" % (base | pos))
|
||||||
sec_mode=None
|
sec_mode = None
|
||||||
sec_sbc=None
|
sec_sbc = None
|
||||||
if sla is not None:
|
if sla is not None:
|
||||||
if data[sla+9]&0xF0==0x60:
|
if data[sla + 9] & 0xF0 == 0x60:
|
||||||
offset, Rn = ldr_lit(sla + 6,
|
offset, Rn = ldr_lit(sla + 6,
|
||||||
unpack("<H", data[sla + 6:sla + 6 + 2])[0])
|
unpack("<H", data[sla + 6:sla + 6 + 2])[0])
|
||||||
sec_sbc=unpack("<I",data[offset:offset+4])[0]
|
sec_sbc = unpack("<I", data[offset:offset + 4])[0]
|
||||||
if data[sla+8]==0x51:
|
if data[sla + 8] == 0x51:
|
||||||
sec_sbc+=4
|
sec_sbc += 4
|
||||||
sec_mode=0
|
sec_mode = 0
|
||||||
else:
|
else:
|
||||||
mpos = find_binary(data, "48C16809B1", 0)
|
mpos = find_binary(data, "48C16809B1", 0)
|
||||||
if mpos is not None:
|
if mpos is not None:
|
||||||
mpos-=1
|
mpos -= 1
|
||||||
sec_mode = 1
|
sec_mode = 1
|
||||||
offset, Rn = ldr_lit(mpos,
|
offset, Rn = ldr_lit(mpos,
|
||||||
unpack("<H", data[mpos:mpos+2])[0])
|
unpack("<H", data[mpos:mpos + 2])[0])
|
||||||
rbase=unpack("<I",data[offset:offset+4])[0]
|
rbase = unpack("<I", data[offset:offset + 4])[0]
|
||||||
simm5, sRt, sRn = ldr_imm(unpack("<H", data[mpos+2:mpos + 4])[0])
|
simm5, sRt, sRn = ldr_imm(unpack("<H", data[mpos + 2:mpos + 4])[0])
|
||||||
sec_sbc = (rbase+(simm5*4))
|
sec_sbc = (rbase + (simm5 * 4))
|
||||||
instr=unpack("<H", data[sla+0x12:sla+0x12+2])[0]
|
instr = unpack("<H", data[sla + 0x12:sla + 0x12 + 2])[0]
|
||||||
offset, Rn = ldr_lit(sla+0x12,instr)
|
offset, Rn = ldr_lit(sla + 0x12, instr)
|
||||||
rbase=unpack("<I",data[offset:offset+4])[0]
|
rbase = unpack("<I", data[offset:offset + 4])[0]
|
||||||
simm5, sRt, sRn = ldr_imm(unpack("<H", data[sla+0x12+2:sla+0x12 + 4])[0])
|
simm5, sRt, sRn = ldr_imm(unpack("<H", data[sla + 0x12 + 2:sla + 0x12 + 4])[0])
|
||||||
sec_sla = (rbase + (simm5 * 4))
|
sec_sla = (rbase + (simm5 * 4))
|
||||||
|
|
||||||
func_wdt=None
|
func_wdt = None
|
||||||
func_acm=None
|
func_acm = None
|
||||||
pos = find_binary(data, "70B50646A648", 0)
|
pos = find_binary(data, "70B50646A648", 0)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 1
|
pos += 1
|
||||||
func_acm = base|pos
|
func_acm = base | pos
|
||||||
pos = find_binary(data, "0F4941F6", 0)
|
pos = find_binary(data, "0F4941F6", 0)
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos = find_binary(data, "124941F6", 0)
|
pos = find_binary(data, "124941F6", 0)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 1
|
pos += 1
|
||||||
func_wdt=base|pos
|
func_wdt = base | pos
|
||||||
|
|
||||||
pos = find_binary(data, "F8B50024", 0)
|
pos = find_binary(data, "F8B50024", 0)
|
||||||
if pos is None:
|
if pos is None:
|
||||||
|
@ -187,8 +186,8 @@ def main():
|
||||||
usb_buffer = unpack("<I", data[offset:offset + 4])[0]
|
usb_buffer = unpack("<I", data[offset:offset + 4])[0]
|
||||||
break
|
break
|
||||||
|
|
||||||
vulnaddr=None
|
vulnaddr = None
|
||||||
var1=None
|
var1 = None
|
||||||
pos = find_binary(data, b"\xA1..\xD0\x21", 0)
|
pos = find_binary(data, b"\xA1..\xD0\x21", 0)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
for i in range(0, 0x100, 2):
|
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])
|
unpack("<H", data[vuln_ctrl_handler + i:vuln_ctrl_handler + i + 2])[0])
|
||||||
vulnaddr = unpack("<I", data[offset:offset + 4])[0]
|
vulnaddr = unpack("<I", data[offset:offset + 4])[0]
|
||||||
if data[vuln_ctrl_handler + i + 1] == 0x6A and usb_buffer != 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)
|
vulnoff = (simm5 * 4)
|
||||||
var1 = (usb_buffer - vulnaddr - vulnoff) / 0x34
|
var1 = (usb_buffer - vulnaddr - vulnoff) / 0x34
|
||||||
if int(var1) != var1:
|
if int(var1) != var1:
|
||||||
|
@ -225,19 +225,19 @@ def main():
|
||||||
pos = find_binary(data, b"\x10\xB5..\xF4.\x00\x21", 0)
|
pos = find_binary(data, b"\x10\xB5..\xF4.\x00\x21", 0)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 1
|
pos += 1
|
||||||
cmd_handler=base|pos
|
cmd_handler = base | pos
|
||||||
|
|
||||||
uart_info = None
|
uart_info = None
|
||||||
pos = find_binary(data, "10B5114A")
|
pos = find_binary(data, "10B5114A")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
uart_info=pos
|
uart_info = pos
|
||||||
|
|
||||||
uart_addr = None
|
uart_addr = None
|
||||||
pos = find_binary(data, "315F454E930F0E00")
|
pos = find_binary(data, "315F454E930F0E00")
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos = find_binary(data, "0070315F454E00")
|
pos = find_binary(data, "0070315F454E00")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos+=6
|
pos += 6
|
||||||
uart_addr = unpack("<I", data[pos:pos + 4])[0]
|
uart_addr = unpack("<I", data[pos:pos + 4])[0]
|
||||||
else:
|
else:
|
||||||
pos += 8
|
pos += 8
|
||||||
|
@ -266,8 +266,8 @@ def main():
|
||||||
pos += 8
|
pos += 8
|
||||||
instr = unpack("<H", data[pos:pos + 2])[0]
|
instr = unpack("<H", data[pos:pos + 2])[0]
|
||||||
offset, Rn = ldr_lit(pos, instr)
|
offset, Rn = ldr_lit(pos, instr)
|
||||||
blacklist_ptr = unpack("<I", data[offset:offset + 4])[0]&0xFFFFF
|
blacklist_ptr = unpack("<I", data[offset:offset + 4])[0] & 0xFFFFF
|
||||||
blacklist = unpack("<I", data[blacklist_ptr-4:blacklist_ptr-4 + 4])[0]
|
blacklist = unpack("<I", data[blacklist_ptr - 4:blacklist_ptr - 4 + 4])[0]
|
||||||
else:
|
else:
|
||||||
pos += 10
|
pos += 10
|
||||||
else:
|
else:
|
||||||
|
@ -282,16 +282,16 @@ def main():
|
||||||
pos = find_binary(data, b"\x02\x4A\x02\x60")
|
pos = find_binary(data, b"\x02\x4A\x02\x60")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 4
|
pos += 4
|
||||||
blacklistcount = unpack("<H", data[pos:pos + 2])[0]&0xF
|
blacklistcount = unpack("<H", data[pos:pos + 2])[0] & 0xF
|
||||||
|
|
||||||
blacklist2 = None
|
blacklist2 = None
|
||||||
pos = find_binary(data, b"\x10\xB5..\xD2\xF8\x90\x30\x10\x32")
|
pos = find_binary(data, b"\x10\xB5..\xD2\xF8\x90\x30\x10\x32")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos+=2
|
pos += 2
|
||||||
instr = unpack("<H", data[pos:pos + 2])[0]
|
instr = unpack("<H", data[pos:pos + 2])[0]
|
||||||
offset, Rn = ldr_lit(pos, instr)
|
offset, Rn = ldr_lit(pos, instr)
|
||||||
bl2 = unpack("<I", data[offset:offset + 4])[0]
|
bl2 = unpack("<I", data[offset:offset + 4])[0]
|
||||||
blacklist2 = bl2+0x90
|
blacklist2 = bl2 + 0x90
|
||||||
|
|
||||||
pos = 0
|
pos = 0
|
||||||
memread = None
|
memread = None
|
||||||
|
@ -314,14 +314,13 @@ def main():
|
||||||
payload_addr = unpack("<I", data[pos:pos + 4])[0]
|
payload_addr = unpack("<I", data[pos:pos + 4])[0]
|
||||||
break
|
break
|
||||||
|
|
||||||
coffs=(usbdl_put_data&0xFFFFF)+1
|
coffs = (usbdl_put_data & 0xFFFFF) + 1
|
||||||
try:
|
try:
|
||||||
offset, Rn = ldr_lit(coffs,
|
offset, Rn = ldr_lit(coffs,
|
||||||
unpack("<H", data[coffs:coffs + 2])[0])
|
unpack("<H", data[coffs:coffs + 2])[0])
|
||||||
except:
|
except:
|
||||||
print("Err:"+sys.argv[1])
|
print("Err:" + sys.argv[1])
|
||||||
send_ptr_offset=offset
|
send_ptr = unpack("<I", data[offset:offset + 4])[0] + 8
|
||||||
send_ptr=unpack("<I",data[offset:offset+4])[0]+8
|
|
||||||
send_ptr_offset = base | offset
|
send_ptr_offset = base | offset
|
||||||
ctrl_addr = None
|
ctrl_addr = None
|
||||||
pos = find_binary(data, "41434D2043")
|
pos = find_binary(data, "41434D2043")
|
||||||
|
@ -329,7 +328,6 @@ def main():
|
||||||
pos -= 0x10
|
pos -= 0x10
|
||||||
ctrl_addr = unpack("<I", data[pos:pos + 4])[0]
|
ctrl_addr = unpack("<I", data[pos:pos + 4])[0]
|
||||||
|
|
||||||
|
|
||||||
socid_addr = None
|
socid_addr = None
|
||||||
pos = find_binary(data, "10B501212020FF")
|
pos = find_binary(data, "10B501212020FF")
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
|
@ -346,18 +344,18 @@ def main():
|
||||||
offset, Rn = ldr_lit(pos, instr)
|
offset, Rn = ldr_lit(pos, instr)
|
||||||
meid_addr = unpack("<I", data[offset:offset + 4])[0]
|
meid_addr = unpack("<I", data[offset:offset + 4])[0]
|
||||||
|
|
||||||
brom_register_access=None
|
brom_register_access = None
|
||||||
brom_register_access_ptr=None
|
brom_register_access_ptr = None
|
||||||
pos2 = find_binary(data, "2DE9F04100244FF001")
|
pos2 = find_binary(data, "2DE9F04100244FF001")
|
||||||
if pos2 is not None:
|
if pos2 is not None:
|
||||||
brom_register_access = base|pos2
|
brom_register_access = base | pos2
|
||||||
pos = find_binary(data, b"\xA9\x07.\x48", pos2)
|
pos = find_binary(data, b"\xA9\x07.\x48", pos2)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
pos += 2
|
pos += 2
|
||||||
instr = unpack("<H", data[pos:pos + 2])[0]
|
instr = unpack("<H", data[pos:pos + 2])[0]
|
||||||
offset, Rn = ldr_lit(pos, instr)
|
offset, Rn = ldr_lit(pos, instr)
|
||||||
brom_register_access_ptr=base|pos2
|
brom_register_access_ptr = base | pos2
|
||||||
brom_register_access_ptr_offset=base|offset
|
brom_register_access_ptr_offset = base | offset
|
||||||
else:
|
else:
|
||||||
pos = find_binary(data, "194D1B49", pos2)
|
pos = find_binary(data, "194D1B49", pos2)
|
||||||
if pos is not None:
|
if pos is not None:
|
||||||
|
@ -379,7 +377,7 @@ def main():
|
||||||
print("*sec_mode:\t\t\t\t\t0x%08X" % sec_mode)
|
print("*sec_mode:\t\t\t\t\t0x%08X" % sec_mode)
|
||||||
if sec_sbc:
|
if sec_sbc:
|
||||||
print("*sec_sbc:\t\t\t\t\t0x%08X" % 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("*sec_sla:\t\t\t\t\t0x%08X" % sec_sla)
|
||||||
print("*func_usb_buffer:\t\t\t0x%08X" % (func_usb_buffer + 1 | base))
|
print("*func_usb_buffer:\t\t\t0x%08X" % (func_usb_buffer + 1 | base))
|
||||||
print("usb_buffer:\t\t\t\t\t0x%08X" % usb_buffer)
|
print("usb_buffer:\t\t\t\t\t0x%08X" % usb_buffer)
|
||||||
|
@ -394,7 +392,7 @@ def main():
|
||||||
if usbdl_ptr:
|
if usbdl_ptr:
|
||||||
print("usbdl_ptr:\t\t\t\t\t\t0x%08X" % usbdl_ptr)
|
print("usbdl_ptr:\t\t\t\t\t\t0x%08X" % usbdl_ptr)
|
||||||
else:
|
else:
|
||||||
print("Uhoh: "+sys.argv[1])
|
print("Uhoh: " + sys.argv[1])
|
||||||
if memread:
|
if memread:
|
||||||
print("memread:\t\t\t\t\t0x%08X" % memread)
|
print("memread:\t\t\t\t\t0x%08X" % memread)
|
||||||
if payload_addr:
|
if payload_addr:
|
||||||
|
@ -422,26 +420,27 @@ def main():
|
||||||
if cmd_handler:
|
if cmd_handler:
|
||||||
print("*cmd_handler:\t\t\t\t0x%08X" % cmd_handler)
|
print("*cmd_handler:\t\t\t\t0x%08X" % cmd_handler)
|
||||||
if brom_register_access_ptr:
|
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:
|
if meid_addr:
|
||||||
print(f"meid_addr:\t\t\t\t\t{hex(meid_addr)}")
|
print(f"meid_addr:\t\t\t\t\t{hex(meid_addr)}")
|
||||||
if socid_addr:
|
if socid_addr:
|
||||||
print(f"socid_addr:\t\t\t\t\t{hex(socid_addr)}")
|
print(f"socid_addr:\t\t\t\t\t{hex(socid_addr)}")
|
||||||
print("da_range:\t\t\t\t\t0x%08X" % offset)
|
print("da_range:\t\t\t\t\t0x%08X" % offset)
|
||||||
|
|
||||||
if sec_mode==1:
|
if sec_mode == 1:
|
||||||
sec_offset=0x28
|
sec_offset = 0x28
|
||||||
else:
|
else:
|
||||||
sec_offset=0x40
|
sec_offset = 0x40
|
||||||
sec_sla=0
|
sec_sla = 0
|
||||||
|
|
||||||
if blacklist2 is None:
|
if blacklist2 is None:
|
||||||
blacklist2 = 0
|
blacklist2 = 0
|
||||||
import os
|
import os
|
||||||
socname=os.path.basename(sys.argv[1]).replace(".bin","")[:6]
|
socname = os.path.basename(sys.argv[1]).replace(".bin", "")[:6]
|
||||||
try:
|
try:
|
||||||
if usbdl_ptr:
|
if usbdl_ptr:
|
||||||
header =f"""
|
header = f"""
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#define PAYLOAD_2_0
|
#define PAYLOAD_2_0
|
||||||
char SOC_NAME[] = "{socname}";
|
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 SEC_OFFSET={hex(sec_offset)};
|
||||||
volatile uint32_t *bladdr=(volatile uint32_t *){hex(blacklist)};
|
volatile uint32_t *bladdr=(volatile uint32_t *){hex(blacklist)};
|
||||||
volatile uint32_t *bladdr2=(volatile uint32_t *){hex(blacklist2)};
|
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)};
|
volatile uint32_t *uart_reg1 = (volatile uint32_t*){hex(uart_addr)};
|
||||||
|
|
||||||
int (*cmd_handler)() = (void*){hex(cmd_handler)};
|
int (*cmd_handler)() = (void*){hex(cmd_handler)};
|
||||||
|
@ -464,9 +463,10 @@ int (*cmd_handler)() = (void*){hex(cmd_handler)};
|
||||||
print(header)
|
print(header)
|
||||||
if not os.path.exists("headers"):
|
if not os.path.exists("headers"):
|
||||||
os.mkdir("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:
|
except:
|
||||||
print(sys.argv[1])
|
print(sys.argv[1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from struct import unpack
|
||||||
from mtkclient.config.payloads import pathconfig
|
from mtkclient.config.payloads import pathconfig
|
||||||
from mtkclient.Library.utils import read_object
|
from mtkclient.Library.utils import read_object
|
||||||
from mtkclient.Library.utils import find_binary
|
from mtkclient.Library.utils import find_binary
|
||||||
|
|
||||||
entry_region = [
|
entry_region = [
|
||||||
('m_buf', 'I'),
|
('m_buf', 'I'),
|
||||||
('m_len', 'I'),
|
('m_len', 'I'),
|
||||||
|
@ -27,7 +28,8 @@ DA = [
|
||||||
# vector<entry_region> LoadRegion
|
# vector<entry_region> LoadRegion
|
||||||
]
|
]
|
||||||
|
|
||||||
efusedb={}
|
efusedb = {}
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
da_setup = []
|
da_setup = []
|
||||||
|
@ -54,7 +56,8 @@ def main():
|
||||||
da.append(entry_tmp)
|
da.append(entry_tmp)
|
||||||
da_setup.append(da)
|
da_setup.append(da)
|
||||||
print(f"Loader: {os.path.basename(loader)}")
|
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("hwcode: 0x%04X" % da[0]["hw_code"])
|
||||||
print("hw_sub_code: 0x%04X" % da[0]["hw_sub_code"])
|
print("hw_sub_code: 0x%04X" % da[0]["hw_sub_code"])
|
||||||
print("hw_version: 0x%04X" % da[0]["hw_version"])
|
print("hw_version: 0x%04X" % da[0]["hw_version"])
|
||||||
|
@ -62,56 +65,60 @@ def main():
|
||||||
print("Reserved1: 0x%04X" % da[0]["reserved1"])
|
print("Reserved1: 0x%04X" % da[0]["reserved1"])
|
||||||
print("Reserved3: 0x%04X" % da[0]["reserved3"])
|
print("Reserved3: 0x%04X" % da[0]["reserved3"])
|
||||||
for i in range(da[0]["entry_region_count"]):
|
for i in range(da[0]["entry_region_count"]):
|
||||||
entry=da[i+1]
|
entry = da[i + 1]
|
||||||
print(f"\t{i}: "+hex(entry['m_start_addr']))
|
print(f"\t{i}: {hex(entry['m_start_addr'])}")
|
||||||
mbuf=da[3]["m_buf"]
|
mbuf = da[3]["m_buf"]
|
||||||
m_len=da[3]["m_len"]
|
m_len = da[3]["m_len"]
|
||||||
startaddr=da[3]["m_start_addr"]
|
startaddr = da[3]["m_start_addr"]
|
||||||
with open(loader,"rb") as rf:
|
with open(loader, "rb") as rf:
|
||||||
rf.seek(mbuf)
|
rf.seek(mbuf)
|
||||||
da2data=rf.read(m_len)
|
da2data = rf.read(m_len)
|
||||||
fname=os.path.join("loaders",hex(da[0]["hw_code"])[2:]+"_"+hex(startaddr)[2:]+os.path.basename(loader))
|
fname = os.path.join("loaders",
|
||||||
open(fname,"wb").write(da2data)
|
hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename(
|
||||||
mbuf=da[2]["m_buf"]
|
loader))
|
||||||
m_len=da[2]["m_len"]
|
open(fname, "wb").write(da2data)
|
||||||
startaddr=da[2]["m_start_addr"]
|
mbuf = da[2]["m_buf"]
|
||||||
|
m_len = da[2]["m_len"]
|
||||||
|
startaddr = da[2]["m_start_addr"]
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
with open(loader,"rb") as rf:
|
with open(loader, "rb") as rf:
|
||||||
rf.seek(mbuf)
|
rf.seek(mbuf)
|
||||||
data=rf.read(m_len)
|
data = rf.read(m_len)
|
||||||
hashidx=data.find(int.to_bytes(0xC0070004,4,'little'))
|
hashidx = data.find(int.to_bytes(0xC0070004, 4, 'little'))
|
||||||
if hashidx!=-1:
|
if hashidx != -1:
|
||||||
print("Hash check found.")
|
print("Hash check found.")
|
||||||
else:
|
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:
|
if hashidx != -1:
|
||||||
print("Hash check 2 found.")
|
print("Hash check 2 found.")
|
||||||
else:
|
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:
|
if hashidx is not None:
|
||||||
print("Hash check 3 found.")
|
print("Hash check 3 found.")
|
||||||
else:
|
else:
|
||||||
print("HASH ERROR !!!!")
|
print("HASH ERROR !!!!")
|
||||||
|
|
||||||
fname=os.path.join("loaders",hex(da[0]["hw_code"])[2:]+"_"+hex(startaddr)[2:]+os.path.basename(loader))
|
fname = os.path.join("loaders",
|
||||||
open(fname,"wb").write(data)
|
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"Offset: {hex(mbuf)}")
|
||||||
print(f"Length: {hex(m_len)}")
|
print(f"Length: {hex(m_len)}")
|
||||||
print(f"Addr: {hex(startaddr)}")
|
print(f"Addr: {hex(startaddr)}")
|
||||||
bootldr.seek(da[2]["m_buf"])
|
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("70BB442D27D244A7"))
|
||||||
#idx = tt.find(bytes.fromhex("01279360D36013615361"))
|
#idx = tt.find(bytes.fromhex("01279360D36013615361"))
|
||||||
if idx!=-1:
|
if idx != -1:
|
||||||
print("V3 Enabled")
|
print("V3 Enabled")
|
||||||
bootldr.seek(da[3]["m_buf"])
|
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"))
|
idx2 = tt.find(bytes.fromhex("03 29 0D D9 07 4B 1B 68 03 60"))
|
||||||
if idx2!=-1:
|
if idx2 != -1:
|
||||||
efusedb[da[0]["hw_code"]]=hex(int.from_bytes(tt[idx2+0x24:idx2+0x28],'little')&0xFFFFF000)
|
efusedb[da[0]["hw_code"]] = hex(int.from_bytes(tt[idx2 + 0x24:idx2 + 0x28], 'little') & 0xFFFFF000)
|
||||||
else:
|
else:
|
||||||
if not da[0]["hw_code"] in efusedb:
|
if not da[0]["hw_code"] in efusedb:
|
||||||
efusedb[da[0]["hw_code"]]="None"
|
efusedb[da[0]["hw_code"]] = "None"
|
||||||
print()
|
print()
|
||||||
|
|
||||||
sorted_dict = dict(sorted(efusedb.items()))
|
sorted_dict = dict(sorted(efusedb.items()))
|
||||||
|
@ -135,5 +142,6 @@ def main():
|
||||||
print(str(idx)+" "+name+": "+hex(fields[2]))
|
print(str(idx)+" "+name+": "+hex(fields[2]))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if __name__=="__main__":
|
|
||||||
main()
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#!/bin/bash
|
#!/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:
|
elif address == 0x11020000:
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
if r0 == 0xa:
|
if r0 == 0xa:
|
||||||
print("UART: " + buffer.decode('utf-8'))
|
print(f"UART: {buffer.decode('utf-8')}")
|
||||||
data += buffer.decode('utf-8')
|
data += buffer.decode('utf-8')
|
||||||
buffer = bytearray()
|
buffer = bytearray()
|
||||||
else:
|
else:
|
||||||
|
@ -343,7 +343,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
|
||||||
elif address == 0x11050000:
|
elif address == 0x11050000:
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
if r0 == 0xd:
|
if r0 == 0xd:
|
||||||
print("UART: " + buffer.decode('utf-8'))
|
print(f"UART: {buffer.decode('utf-8')}")
|
||||||
data += buffer.decode('utf-8')
|
data += buffer.decode('utf-8')
|
||||||
buffer = bytearray()
|
buffer = bytearray()
|
||||||
else:
|
else:
|
||||||
|
@ -352,7 +352,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
|
||||||
elif address == 0x11002000:
|
elif address == 0x11002000:
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
if r0 == 0xa:
|
if r0 == 0xa:
|
||||||
print("UART: " + buffer.decode('utf-8'))
|
print(f"UART: {buffer.decode('utf-8')}")
|
||||||
data += buffer.decode('utf-8')
|
data += buffer.decode('utf-8')
|
||||||
buffer = bytearray()
|
buffer = bytearray()
|
||||||
else:
|
else:
|
||||||
|
@ -361,7 +361,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
|
||||||
elif address == 0x11003000:
|
elif address == 0x11003000:
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
if r0 == 0xa:
|
if r0 == 0xa:
|
||||||
print("UART: " + buffer.decode('utf-8'))
|
print(f"UART: {buffer.decode('utf-8')}")
|
||||||
data += buffer.decode('utf-8')
|
data += buffer.decode('utf-8')
|
||||||
buffer = bytearray()
|
buffer = bytearray()
|
||||||
else:
|
else:
|
||||||
|
@ -370,7 +370,7 @@ def hook_mem_write(uc, access, address, size, value, user_data):
|
||||||
elif address == 0x11005000:
|
elif address == 0x11005000:
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
if r0 == 0xa:
|
if r0 == 0xa:
|
||||||
print("UART: " + buffer.decode('utf-8'))
|
print(f"UART: {buffer.decode('utf-8')}")
|
||||||
data += buffer.decode('utf-8')
|
data += buffer.decode('utf-8')
|
||||||
buffer = bytearray()
|
buffer = bytearray()
|
||||||
else:
|
else:
|
||||||
|
@ -389,61 +389,61 @@ def hook_code(uc, access, address, size):
|
||||||
keyslot0 = uc.mem_read(0x701953CC, 0x20)
|
keyslot0 = uc.mem_read(0x701953CC, 0x20)
|
||||||
keyslot1 = uc.mem_read(0x701953EC, 0x20)
|
keyslot1 = uc.mem_read(0x701953EC, 0x20)
|
||||||
keyslot2 = uc.mem_read(0x7019540C, 0x20)
|
keyslot2 = uc.mem_read(0x7019540C, 0x20)
|
||||||
print("Keyslot0: " + hexlify(keyslot0).decode('utf-8'))
|
print(f"Keyslot0: {hexlify(keyslot0).decode('utf-8')}")
|
||||||
print("Keyslot1: " + hexlify(keyslot1).decode('utf-8'))
|
print(f"Keyslot1: {hexlify(keyslot1).decode('utf-8')}")
|
||||||
print("Keyslot2: " + hexlify(keyslot2).decode('utf-8'))
|
print(f"Keyslot2: {hexlify(keyslot2).decode('utf-8')}")
|
||||||
elif pc == 0x70094A5C: # sha256_write
|
elif pc == 0x70094A5C: # sha256_write
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r1 = uc.reg_read(UC_ARM_REG_R1)
|
r1 = uc.reg_read(UC_ARM_REG_R1)
|
||||||
r2 = uc.reg_read(UC_ARM_REG_R2)
|
r2 = uc.reg_read(UC_ARM_REG_R2)
|
||||||
s1 = uc.mem_read(r1, r2)
|
s1 = uc.mem_read(r1, r2)
|
||||||
print("sha256_write")
|
print("sha256_write")
|
||||||
print("lr: " + hex(lr))
|
print(f"lr: {hex(lr)}")
|
||||||
print(f"r1: {hex(r1)} " + hexlify(s1).decode('utf-8'))
|
print(f"r1: {hex(r1)} {hexlify(s1).decode('utf-8')}")
|
||||||
print("r2: " + hex(r2) + "\n")
|
print(f"r2: {hex(r2)}\n")
|
||||||
elif pc == 0x70094E3C: # kdflib_get_huk
|
elif pc == 0x70094E3C: # kdflib_get_huk
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
print("kdflib_get_huk")
|
print("kdflib_get_huk")
|
||||||
print("klr: " + hex(lr))
|
print(f"klr: {hex(lr)}")
|
||||||
print("kr0: " + hex(r0))
|
print(f"kr0: {hex(r0)}")
|
||||||
elif pc == 0x70095240:
|
elif pc == 0x70095240:
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
r4 = uc.reg_read(UC_ARM_REG_R4)
|
r4 = uc.reg_read(UC_ARM_REG_R4)
|
||||||
print("hmac_sha256")
|
print("hmac_sha256")
|
||||||
print("hlr: " + hex(lr))
|
print(f"hlr: {hex(lr)}")
|
||||||
print("hr0: " + hex(r0))
|
print(f"hr0: {hex(r0)}")
|
||||||
print("hr4: " + hex(r4))
|
print(f"hr4: {hex(r4)}")
|
||||||
elif pc == 0x70087430: # memcpy
|
elif pc == 0x70087430: # memcpy
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r0 = uc.reg_read(UC_ARM_REG_R0)
|
r0 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
r1 = uc.reg_read(UC_ARM_REG_R0)
|
r1 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
r2 = uc.reg_read(UC_ARM_REG_R0)
|
r2 = uc.reg_read(UC_ARM_REG_R0)
|
||||||
print("memcpy")
|
print("memcpy")
|
||||||
print("lr: " + hex(lr))
|
print(f"lr: {hex(lr)}")
|
||||||
print("r0: " + hex(r0))
|
print(f"r0: {hex(r0)}")
|
||||||
print("r1: " + hex(r1))
|
print(f"r1: {hex(r1)}")
|
||||||
print("r2: " + hex(r2))
|
print(f"r2: {hex(r2)}")
|
||||||
elif pc == 0x70095084:
|
elif pc == 0x70095084:
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
print("hmac_init")
|
print("hmac_init")
|
||||||
print("lr: " + hex(lr))
|
print(f"lr: {hex(lr)}")
|
||||||
elif pc == 0x70094CF8:
|
elif pc == 0x70094CF8:
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r1 = uc.reg_read(UC_ARM_REG_R1)
|
r1 = uc.reg_read(UC_ARM_REG_R1)
|
||||||
debug = r1
|
debug = r1
|
||||||
print("sha_finish")
|
print("sha_finish")
|
||||||
print("lr: " + hex(lr))
|
print(f"lr: {hex(lr)}")
|
||||||
print("r1: " + hex(r1))
|
print(f"r1: {hex(r1)}")
|
||||||
elif pc == 0x70094DB8:
|
elif pc == 0x70094DB8:
|
||||||
lr = uc.reg_read(UC_ARM_REG_LR)
|
lr = uc.reg_read(UC_ARM_REG_LR)
|
||||||
r1 = debug
|
r1 = debug
|
||||||
s1 = uc.mem_read(r1, 0x20)
|
s1 = uc.mem_read(r1, 0x20)
|
||||||
print("sha_finish2")
|
print("sha_finish2")
|
||||||
print("lr: " + hex(lr))
|
print(f"lr: {hex(lr)}")
|
||||||
print("r1: " + hex(r1))
|
print(f"r1: {hex(r1)}")
|
||||||
print("s1: " + hexlify(s1).decode('utf-8'))
|
print(f"s1: {hexlify(s1).decode('utf-8')}")
|
||||||
|
|
||||||
# print("PC %08X" % pc)
|
# print("PC %08X" % pc)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -96,18 +96,6 @@ class EraseFlashWindow(QObject):
|
||||||
thread.wait()
|
thread.wait()
|
||||||
self.enableButtonsSignal.emit()
|
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):
|
def erasePartitionAsync(self, toolkit, parameters):
|
||||||
self.parent.timeEst.init()
|
self.parent.timeEst.init()
|
||||||
self.parent.timeEstTotal.init()
|
self.parent.timeEstTotal.init()
|
||||||
|
|
|
@ -314,13 +314,13 @@ class Ui_MainWindow(object):
|
||||||
self.gridLayout_2 = QGridLayout(self.keytab)
|
self.gridLayout_2 = QGridLayout(self.keytab)
|
||||||
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
||||||
self.keytable = QTableWidget(self.keytab)
|
self.keytable = QTableWidget(self.keytab)
|
||||||
if (self.keytable.columnCount() < 2):
|
if self.keytable.columnCount() < 2:
|
||||||
self.keytable.setColumnCount(2)
|
self.keytable.setColumnCount(2)
|
||||||
__qtablewidgetitem = QTableWidgetItem()
|
__qtablewidgetitem = QTableWidgetItem()
|
||||||
self.keytable.setHorizontalHeaderItem(0, __qtablewidgetitem)
|
self.keytable.setHorizontalHeaderItem(0, __qtablewidgetitem)
|
||||||
__qtablewidgetitem1 = QTableWidgetItem()
|
__qtablewidgetitem1 = QTableWidgetItem()
|
||||||
self.keytable.setHorizontalHeaderItem(1, __qtablewidgetitem1)
|
self.keytable.setHorizontalHeaderItem(1, __qtablewidgetitem1)
|
||||||
if (self.keytable.rowCount() < 7):
|
if self.keytable.rowCount() < 7:
|
||||||
self.keytable.setRowCount(7)
|
self.keytable.setRowCount(7)
|
||||||
__qtablewidgetitem2 = QTableWidgetItem()
|
__qtablewidgetitem2 = QTableWidgetItem()
|
||||||
self.keytable.setVerticalHeaderItem(0, __qtablewidgetitem2)
|
self.keytable.setVerticalHeaderItem(0, __qtablewidgetitem2)
|
||||||
|
|
|
@ -10,14 +10,14 @@ from mtkclient.config.payloads import pathconfig
|
||||||
|
|
||||||
|
|
||||||
class TimeEstim:
|
class TimeEstim:
|
||||||
def calcProcessTime(self, starttime, cur_iter, max_iter):
|
@staticmethod
|
||||||
|
def calcProcessTime(starttime, cur_iter, max_iter):
|
||||||
telapsed = time.time() - starttime
|
telapsed = time.time() - starttime
|
||||||
if telapsed > 0 and cur_iter > 0:
|
if telapsed > 0 and cur_iter > 0:
|
||||||
testimated = (telapsed / cur_iter) * max_iter
|
testimated = (telapsed / cur_iter) * max_iter
|
||||||
finishtime = starttime + testimated
|
finishtime = starttime + testimated
|
||||||
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
|
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
|
||||||
lefttime = testimated - telapsed # in seconds
|
return int(telapsed), int(testimated - telapsed), finishtime
|
||||||
return int(telapsed), int(lefttime), finishtime
|
|
||||||
else:
|
else:
|
||||||
return 0, 0, ""
|
return 0, 0, ""
|
||||||
|
|
||||||
|
@ -34,14 +34,14 @@ class TimeEstim:
|
||||||
if lefttime > 0:
|
if lefttime > 0:
|
||||||
sec = lefttime
|
sec = lefttime
|
||||||
if sec > 60:
|
if sec > 60:
|
||||||
min = sec // 60
|
minutes = sec // 60
|
||||||
sec = sec % 60
|
sec = sec % 60
|
||||||
if min > 60:
|
if minutes > 60:
|
||||||
h = min // 24
|
h = minutes // 24
|
||||||
min = min % 24
|
minutes = minutes % 24
|
||||||
hinfo = "%02dh:%02dm:%02ds" % (h, min, sec)
|
hinfo = "%02dh:%02dm:%02ds" % (h, minutes, sec)
|
||||||
else:
|
else:
|
||||||
hinfo = "%02dm:%02ds" % (min, sec)
|
hinfo = "%02dm:%02ds" % (minutes, sec)
|
||||||
else:
|
else:
|
||||||
hinfo = "%02ds" % sec
|
hinfo = "%02ds" % sec
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ def convert_size(size_bytes):
|
||||||
i = int(math.floor(math.log(size_bytes, 1024)))
|
i = int(math.floor(math.log(size_bytes, 1024)))
|
||||||
p = math.pow(1024, i)
|
p = math.pow(1024, i)
|
||||||
s = round(size_bytes / p, 2)
|
s = round(size_bytes / p, 2)
|
||||||
return "%s %s" % (s, size_name[i])
|
return f"{s} {size_name[i]}"
|
||||||
|
|
||||||
|
|
||||||
class asyncThread(QThread):
|
class asyncThread(QThread):
|
||||||
|
@ -116,7 +116,7 @@ class asyncThread(QThread):
|
||||||
self.function(self, self.parameters)
|
self.function(self, self.parameters)
|
||||||
|
|
||||||
|
|
||||||
class FDialog():
|
class FDialog:
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
pc = pathconfig()
|
pc = pathconfig()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
|
@ -9,3 +9,5 @@ mock >= 4.0.3
|
||||||
pyserial >= 3.5
|
pyserial >= 3.5
|
||||||
flake8
|
flake8
|
||||||
fusepy
|
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.mtk_config import Mtk_Config
|
||||||
from mtkclient.config.usb_ids import default_ids
|
from mtkclient.config.usb_ids import default_ids
|
||||||
|
|
||||||
|
|
||||||
class Stage2(metaclass=LogBase):
|
class Stage2(metaclass=LogBase):
|
||||||
def __init__(self, args, loglevel=logging.INFO):
|
def __init__(self, args, loglevel=logging.INFO):
|
||||||
self.__logger = self.__logger
|
self.__logger = self.__logger
|
||||||
|
@ -40,8 +41,8 @@ class Stage2(metaclass=LogBase):
|
||||||
self.__logger.setLevel(logging.INFO)
|
self.__logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
self.cdc = usb_class(portconfig=default_ids, loglevel=loglevel, devclass=10)
|
self.cdc = usb_class(portconfig=default_ids, loglevel=loglevel, devclass=10)
|
||||||
self.usbread=self.cdc.usbread
|
self.usbread = self.cdc.usbread
|
||||||
self.usbwrite=self.cdc.usbwrite
|
self.usbwrite = self.cdc.usbwrite
|
||||||
|
|
||||||
def preinit(self):
|
def preinit(self):
|
||||||
try:
|
try:
|
||||||
|
@ -98,11 +99,10 @@ class Stage2(metaclass=LogBase):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def cmd_C8(self, val) -> bool:
|
def cmd_C8(self, val) -> bool:
|
||||||
'Clear cache func'
|
"""Clear cache func"""
|
||||||
self.usbwrite(pack(">I", 0xf00dd00d))
|
self.usbwrite(pack(">I", 0xf00dd00d))
|
||||||
self.usbwrite(pack(">I", 0x5000))
|
self.usbwrite(pack(">I", 0x5000))
|
||||||
ack = self.usbread(4)
|
if self.usbread(4) == b"\xD0\xD0\xD0\xD0":
|
||||||
if ack == b"\xD0\xD0\xD0\xD0":
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -115,8 +115,7 @@ class Stage2(metaclass=LogBase):
|
||||||
self.usbwrite(pack(">I", addr + (pos * 4)))
|
self.usbwrite(pack(">I", addr + (pos * 4)))
|
||||||
self.usbwrite(pack(">I", 4))
|
self.usbwrite(pack(">I", 4))
|
||||||
self.usbwrite(pack("<I", dwords[pos]))
|
self.usbwrite(pack("<I", dwords[pos]))
|
||||||
ack = self.usbread(4)
|
if self.usbread(4) == b"\xD0\xD0\xD0\xD0":
|
||||||
if ack == b"\xD0\xD0\xD0\xD0":
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -130,7 +129,7 @@ class Stage2(metaclass=LogBase):
|
||||||
if self.cdc.connected:
|
if self.cdc.connected:
|
||||||
self.cdc.close()
|
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:
|
if not self.emmc_inited:
|
||||||
self.init_emmc()
|
self.init_emmc()
|
||||||
wf = None
|
wf = None
|
||||||
|
@ -144,7 +143,7 @@ class Stage2(metaclass=LogBase):
|
||||||
# emmc_switch(1)
|
# emmc_switch(1)
|
||||||
self.usbwrite(pack(">I", 0xf00dd00d))
|
self.usbwrite(pack(">I", 0xf00dd00d))
|
||||||
self.usbwrite(pack(">I", 0x1002))
|
self.usbwrite(pack(">I", 0x1002))
|
||||||
self.usbwrite(pack(">I", type))
|
self.usbwrite(pack(">I", type_))
|
||||||
|
|
||||||
# kick-wdt
|
# kick-wdt
|
||||||
# self.usbwrite(pack(">I", 0xf00dd00d))
|
# self.usbwrite(pack(">I", 0xf00dd00d))
|
||||||
|
@ -160,7 +159,7 @@ class Stage2(metaclass=LogBase):
|
||||||
self.usbwrite(pack(">I", sectors))
|
self.usbwrite(pack(">I", sectors))
|
||||||
|
|
||||||
if display:
|
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):
|
for sector in range(sectors):
|
||||||
tmp = self.usbread(0x200)
|
tmp = self.usbread(0x200)
|
||||||
|
@ -183,14 +182,13 @@ class Stage2(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
return buffer[start % 0x200:(start % 0x200) + length]
|
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
|
sectors = 0
|
||||||
if length != 0:
|
if length != 0:
|
||||||
sectors = (length // 0x200) + (1 if length % 0x200 else 0)
|
sectors = (length // 0x200) + (1 if length % 0x200 else 0)
|
||||||
self.info("Reading user data...")
|
self.info("Reading user data...")
|
||||||
if self.cdc.connected:
|
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):
|
def preloader(self, start, length, filename):
|
||||||
sectors = 0
|
sectors = 0
|
||||||
|
@ -201,7 +199,7 @@ class Stage2(metaclass=LogBase):
|
||||||
self.info("Reading preloader...")
|
self.info("Reading preloader...")
|
||||||
if self.cdc.connected:
|
if self.cdc.connected:
|
||||||
if sectors == 0:
|
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:
|
if len(buffer) != 0x4000:
|
||||||
print("Error on reading boot1 area.")
|
print("Error on reading boot1 area.")
|
||||||
return
|
return
|
||||||
|
@ -212,7 +210,7 @@ class Stage2(metaclass=LogBase):
|
||||||
st = buffer[start:start + 4]
|
st = buffer[start:start + 4]
|
||||||
if st == b"MMM\x01":
|
if st == b"MMM\x01":
|
||||||
length = unpack("<I", buffer[start + 0x20:start + 0x24])[0]
|
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:
|
if len(data) != start + length:
|
||||||
print("Warning, please rerun command, length doesn't match.")
|
print("Warning, please rerun command, length doesn't match.")
|
||||||
idx = data.find(b"MTK_BLOADER_INFO")
|
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')
|
filename = data[idx + 0x1B:idx + 0x3D].rstrip(b"\x00").decode('utf-8')
|
||||||
with open(os.path.join("logs", filename), "wb") as wf:
|
with open(os.path.join("logs", filename), "wb") as wf:
|
||||||
wf.write(data[start:start + length])
|
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:
|
with open(os.path.join("logs", "hdr_" + filename), "wb") as wf:
|
||||||
wf.write(data[:start])
|
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
|
return
|
||||||
else:
|
else:
|
||||||
length = 0x40000
|
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("Done")
|
||||||
print("Error on getting preloader info, aborting.")
|
print("Error on getting preloader info, aborting.")
|
||||||
else:
|
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")
|
print("Done")
|
||||||
|
|
||||||
def boot2(self, start, length, filename):
|
def boot2(self, start, length, filename):
|
||||||
|
@ -244,10 +242,10 @@ class Stage2(metaclass=LogBase):
|
||||||
self.info("Reading boot2...")
|
self.info("Reading boot2...")
|
||||||
if self.cdc.connected:
|
if self.cdc.connected:
|
||||||
if sectors == 0:
|
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")
|
print("Done")
|
||||||
else:
|
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")
|
print("Done")
|
||||||
|
|
||||||
def memread(self, start, length, filename=None):
|
def memread(self, start, length, filename=None):
|
||||||
|
@ -269,7 +267,7 @@ class Stage2(metaclass=LogBase):
|
||||||
wf.write(self.usbread(size))
|
wf.write(self.usbread(size))
|
||||||
bytestoread -= size
|
bytestoread -= size
|
||||||
pos += 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:
|
if filename is not None:
|
||||||
wf.close()
|
wf.close()
|
||||||
return data
|
return data
|
||||||
|
@ -318,8 +316,8 @@ class Stage2(metaclass=LogBase):
|
||||||
start = 0
|
start = 0
|
||||||
else:
|
else:
|
||||||
start = (start // 0x100)
|
start = (start // 0x100)
|
||||||
if start>0xFFFF:
|
if start > 0xFFFF:
|
||||||
start=0xFFFF
|
start = 0xFFFF
|
||||||
if length == 0:
|
if length == 0:
|
||||||
sectors = 16 * 1024 * 1024 // 0x100
|
sectors = 16 * 1024 * 1024 // 0x100
|
||||||
else:
|
else:
|
||||||
|
@ -339,8 +337,8 @@ class Stage2(metaclass=LogBase):
|
||||||
bytestoread = sectors * 0x100
|
bytestoread = sectors * 0x100
|
||||||
count = sectors
|
count = sectors
|
||||||
pg = progress(pagesize=0x200)
|
pg = progress(pagesize=0x200)
|
||||||
if sectors>0xFFFF:
|
if sectors > 0xFFFF:
|
||||||
count=0xFFFF
|
count = 0xFFFF
|
||||||
with open(filename, "wb") as wf:
|
with open(filename, "wb") as wf:
|
||||||
self.usbwrite(pack(">I", 0xf00dd00d))
|
self.usbwrite(pack(">I", 0xf00dd00d))
|
||||||
self.usbwrite(pack(">I", 0x2000))
|
self.usbwrite(pack(">I", 0x2000))
|
||||||
|
@ -353,145 +351,135 @@ class Stage2(metaclass=LogBase):
|
||||||
if len(tmp) != 0x100:
|
if len(tmp) != 0x100:
|
||||||
self.error("Error on getting data")
|
self.error("Error on getting data")
|
||||||
return
|
return
|
||||||
pg.show_progress(prefix="Progress:",pos=sector,total=sectors)
|
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
|
||||||
bytesread += 0x100
|
bytesread += 0x100
|
||||||
size = min(bytestoread, len(tmp))
|
size = min(bytestoread, len(tmp))
|
||||||
wf.write(tmp[:size])
|
wf.write(tmp[:size])
|
||||||
bytestoread -= size
|
bytestoread -= size
|
||||||
while bytestoread>0:
|
while bytestoread > 0:
|
||||||
self.usbwrite(pack(">I", 0xf00dd00d))
|
self.usbwrite(pack(">I", 0xf00dd00d))
|
||||||
self.usbwrite(pack(">I", 0x2000))
|
self.usbwrite(pack(">I", 0x2000))
|
||||||
self.usbwrite(pack(">H", sector+1))
|
self.usbwrite(pack(">H", sector + 1))
|
||||||
self.usbwrite(pack(">H", 1))
|
self.usbwrite(pack(">H", 1))
|
||||||
tmp = self.usbread(0x100)
|
tmp = self.usbread(0x100)
|
||||||
size = min(bytestoread, len(tmp))
|
size = min(bytestoread, len(tmp))
|
||||||
wf.write(tmp[:size])
|
wf.write(tmp[:size])
|
||||||
bytestoread -= size
|
bytestoread -= size
|
||||||
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
|
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
|
||||||
sector+=1
|
sector += 1
|
||||||
pg.show_progress(prefix="Progress:", pos=sectors, total=sectors)
|
pg.show_progress(prefix="Progress:", pos=sectors, total=sectors)
|
||||||
print("Done")
|
print("Done")
|
||||||
|
|
||||||
def keys(self, data=b"", otp=None, mode="dxcc"):
|
def keys(self, data=b"", otp=None, mode="dxcc"):
|
||||||
# self.hwcrypto.disable_range_blacklist("cqdma",self.cmd_C8)
|
# self.hwcrypto.disable_range_blacklist("cqdma",self.cmd_C8)
|
||||||
keyinfo=""
|
keyinfo = ""
|
||||||
retval = {}
|
retval = {}
|
||||||
meid = self.config.get_meid()
|
meid = self.config.get_meid()
|
||||||
socid = self.config.get_socid()
|
socid = self.config.get_socid()
|
||||||
if meid is not None:
|
if meid is not None:
|
||||||
self.info("MEID : " + hexlify(meid).decode('utf-8'))
|
self.info(f"MEID : {hexlify(meid).decode('utf-8')}")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if self.config.chipconfig.meid_addr is not None:
|
if self.config.chipconfig.meid_addr is not None:
|
||||||
meid = self.memread(self.config.chipconfig.meid_addr, 16)
|
meid = self.memread(self.config.chipconfig.meid_addr, 16)
|
||||||
self.config.set_meid(meid)
|
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')
|
retval["meid"] = hexlify(meid).decode('utf-8')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
pass
|
pass
|
||||||
if socid is not None:
|
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
|
retval["socid"] = socid
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if self.config.chipconfig.socid_addr is not None:
|
if self.config.chipconfig.socid_addr is not None:
|
||||||
socid = self.memread(self.config.chipconfig.socid_addr, 32)
|
socid = self.memread(self.config.chipconfig.socid_addr, 32)
|
||||||
self.config.set_socid(socid)
|
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')
|
retval["socid"] = hexlify(socid).decode('utf-8')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
pass
|
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"]:
|
if self.setup.dxcc_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
|
||||||
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="rpmb")
|
"sej_sst_encrypt", "dxcc_sha256"]:
|
||||||
|
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb")
|
||||||
rpmb2key = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb2")
|
rpmb2key = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb2")
|
||||||
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="fde")
|
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="fde")
|
||||||
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="itrustee")
|
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="itrustee")
|
||||||
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="prov")
|
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="prov")
|
||||||
keyinfo+="\nKeys :\n-----------------------------------------\n"
|
keyinfo += "\nKeys :\n-----------------------------------------\n"
|
||||||
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')+"\n"
|
keyinfo += f"RPMB: {hexlify(rpmbkey).decode('utf-8')}\n"
|
||||||
keyinfo+="RPMB2: " + hexlify(rpmb2key).decode('utf-8') + "\n"
|
keyinfo += f"RPMB2: {hexlify(rpmb2key).decode('utf-8')}\n"
|
||||||
keyinfo+="FDE : " + hexlify(fdekey).decode('utf-8')+"\n"
|
keyinfo += f"FDE : {hexlify(fdekey).decode('utf-8')}\n"
|
||||||
keyinfo+="iTrustee: " + hexlify(ikey).decode('utf-8')+"\n"
|
keyinfo += f"iTrustee: {hexlify(ikey).decode('utf-8')}\n"
|
||||||
keyinfo+="Platform: " + hexlify(platkey).decode('utf-8')+"\n"
|
keyinfo += f"Platform: {hexlify(platkey).decode('utf-8')}\n"
|
||||||
keyinfo+="Provisioning: " + hexlify(provkey).decode('utf-8')+"\n"
|
keyinfo += f"Provisioning: {hexlify(provkey).decode('utf-8')}\n"
|
||||||
keyinfo+="\n"
|
keyinfo += "\n"
|
||||||
if rpmbkey is not None:
|
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'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
if rpmb2key is not None:
|
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'))
|
self.config.hwparam.writesetting("rpmb2key", hexlify(rpmb2key).decode('utf-8'))
|
||||||
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
|
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
|
||||||
if fdekey is not None:
|
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'))
|
self.config.hwparam.writesetting("fdekey", hexlify(fdekey).decode('utf-8'))
|
||||||
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
|
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
|
||||||
if ikey is not None:
|
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'))
|
self.config.hwparam.writesetting("kmkey", hexlify(ikey).decode('utf-8'))
|
||||||
retval["kmkey"] = hexlify(ikey).decode('utf-8')
|
retval["kmkey"] = hexlify(ikey).decode('utf-8')
|
||||||
if self.config.chipconfig.prov_addr:
|
if self.config.chipconfig.prov_addr:
|
||||||
provkey = self.memread(self.config.chipconfig.prov_addr, 16)
|
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'))
|
self.config.hwparam.writesetting("provkey", hexlify(provkey).decode('utf-8'))
|
||||||
retval["provkey"] = hexlify(provkey).decode('utf-8')
|
retval["provkey"] = hexlify(provkey).decode('utf-8')
|
||||||
return retval, keyinfo
|
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"]:
|
elif self.setup.sej_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
|
||||||
retval={}
|
"sej_sst_encrypt", "dxcc_sha256"]:
|
||||||
|
retval = {}
|
||||||
rpmbkey = self.hwcrypto.aes_hwcrypt(mode="rpmb", data=meid, otp=otp, btype="sej")
|
rpmbkey = self.hwcrypto.aes_hwcrypt(mode="rpmb", data=meid, otp=otp, btype="sej")
|
||||||
if rpmbkey:
|
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'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = self.hwcrypto.aes_hwcrypt(mode="mtee", otp=otp, btype="sej")
|
mtee = self.hwcrypto.aes_hwcrypt(mode="mtee", otp=otp, btype="sej")
|
||||||
if mtee:
|
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'))
|
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
||||||
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
||||||
mtee3 = self.hwcrypto.aes_hwcrypt(mode="mtee3", otp=otp, btype="sej")
|
mtee3 = self.hwcrypto.aes_hwcrypt(mode="mtee3", otp=otp, btype="sej")
|
||||||
if mtee3:
|
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'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
|
||||||
|
|
||||||
keyinfo+="\nKeys :\n-----------------------------------------\n"
|
keyinfo += "\nKeys :\n-----------------------------------------\n"
|
||||||
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')
|
keyinfo += f"RPMB: {hexlify(rpmbkey).decode('utf-8')}\n"
|
||||||
keyinfo+="\n"
|
keyinfo += f"MTEE: {hexlify(mtee).decode('utf-8')}\n"
|
||||||
keyinfo += "MTEE: " + hexlify(mtee).decode('utf-8')
|
|
||||||
keyinfo += "\n"
|
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
return retval, keyinfo
|
return retval, keyinfo
|
||||||
if mode == "sej_aes_decrypt":
|
if mode == "sej_aes_decrypt":
|
||||||
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False, otp=otp)
|
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo += f"\nData: {hexlify(dec_data).decode('utf-8')}\n"
|
||||||
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
|
||||||
keyinfo+="\n"
|
|
||||||
return dec_data, keyinfo
|
return dec_data, keyinfo
|
||||||
elif mode == "sej_aes_encrypt":
|
elif mode == "sej_aes_encrypt":
|
||||||
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True, otp=otp)
|
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo += f"\nData: {hexlify(enc_data).decode('utf-8')}\n"
|
||||||
keyinfo+="Data: " + hexlify(enc_data).decode('utf-8')
|
|
||||||
keyinfo+="\n"
|
|
||||||
return enc_data, keyinfo
|
return enc_data, keyinfo
|
||||||
elif mode == "sej_sst_decrypt":
|
elif mode == "sej_sst_decrypt":
|
||||||
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False, otp=otp)
|
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo += f"\nData: {hexlify(dec_data).decode('utf-8')}\n"
|
||||||
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
|
||||||
keyinfo+="\n"
|
|
||||||
return dec_data, keyinfo
|
return dec_data, keyinfo
|
||||||
elif mode == "sej_sst_encrypt":
|
elif mode == "sej_sst_encrypt":
|
||||||
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True, otp=otp)
|
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True, otp=otp)
|
||||||
keyinfo += "\n"
|
keyinfo += f"\nData: {hexlify(enc_data).decode('utf-8')}\n"
|
||||||
keyinfo += "Data: " + hexlify(enc_data).decode('utf-8')
|
|
||||||
keyinfo += "\n"
|
|
||||||
return enc_data, keyinfo
|
return enc_data, keyinfo
|
||||||
elif mode == "dxcc_sha256":
|
elif mode == "dxcc_sha256":
|
||||||
sha256val = self.hwcrypto.aes_hwcrypt(mode="sha256", data=data, btype="dxcc")
|
sha256val = self.hwcrypto.aes_hwcrypt(mode="sha256", data=data, btype="dxcc")
|
||||||
keyinfo+="\n"
|
keyinfo += f"\nSHA256: {hexlify(sha256val).decode('utf-8')}\n"
|
||||||
keyinfo+="SHA256: " + hexlify(sha256val).decode('utf-8')
|
|
||||||
keyinfo+="\n"
|
|
||||||
return sha256val, keyinfo
|
return sha256val, keyinfo
|
||||||
return None, ""
|
return None, ""
|
||||||
|
|
||||||
|
@ -501,7 +489,6 @@ class Stage2(metaclass=LogBase):
|
||||||
self.usbwrite(pack(">I", 0x3000))
|
self.usbwrite(pack(">I", 0x3000))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getint(valuestr):
|
def getint(valuestr):
|
||||||
if valuestr == '':
|
if valuestr == '':
|
||||||
return None
|
return None
|
||||||
|
@ -533,86 +520,78 @@ cmds = {
|
||||||
info = "MTK Stage2 client (c) B.Kerler 2021"
|
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():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description=info)
|
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 = subparsers.add_parser("rpmb", help="Dump the rpmb")
|
||||||
parser_rpmb.add_argument('--start', dest='start', type=str,
|
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,
|
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",
|
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,
|
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 = subparsers.add_parser("preloader", help="Dump the preloader")
|
||||||
parser_preloader.add_argument('--start', dest='start', type=str,
|
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,
|
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,
|
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 = subparsers.add_parser("data", help="Read the mmc")
|
||||||
parser_data.add_argument('--start', dest='start', type=str,
|
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,
|
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,
|
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 = subparsers.add_parser("boot2", help="Dump boot2")
|
||||||
parser_boot2.add_argument('--start', dest='start', type=str,
|
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,
|
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,
|
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 = subparsers.add_parser("memread", help="Read memory")
|
||||||
parser_memread.add_argument(dest='start', type=str,
|
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,
|
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,
|
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 = subparsers.add_parser("memwrite", help="Write memory")
|
||||||
parser_memwrite.add_argument(dest='start', type=str,
|
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,
|
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_reboot = subparsers.add_parser("reboot", help="Reboot device")
|
||||||
|
|
||||||
parser_seccfg = subparsers.add_parser("seccfg", help="Generate seccfg")
|
parser_seccfg = subparsers.add_parser("seccfg", help="Generate seccfg")
|
||||||
parser_seccfg.add_argument('flag', type=str,
|
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",
|
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 = subparsers.add_parser("keys", help="Write memory")
|
||||||
parser_keys.add_argument('--otp', dest='otp', type=str,
|
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,
|
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,
|
parser_keys.add_argument('--data', dest='data', default=None, type=str,
|
||||||
help='data')
|
help='data')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
cmd = args.cmd
|
cmd = args.cmd
|
||||||
if cmd not in cmds:
|
if cmd not in cmds:
|
||||||
showcommands()
|
parser.print_help()
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
if not os.path.exists("logs"):
|
if not os.path.exists("logs"):
|
||||||
|
@ -673,35 +652,35 @@ def main():
|
||||||
exit(0)
|
exit(0)
|
||||||
start = getint(args.start)
|
start = getint(args.start)
|
||||||
if os.path.exists(args.data):
|
if os.path.exists(args.data):
|
||||||
filename=args.data
|
filename = args.data
|
||||||
data=None
|
data = None
|
||||||
else:
|
else:
|
||||||
if "0x" in args.data:
|
if "0x" in args.data:
|
||||||
data=getint(args.data)
|
data = getint(args.data)
|
||||||
else:
|
else:
|
||||||
data=args.data
|
data = args.data
|
||||||
filename=None
|
filename = None
|
||||||
if st2.memwrite(start, data, filename):
|
if st2.memwrite(start, data, filename):
|
||||||
print(f"Successfully wrote data to {hex(start)}.")
|
print(f"Successfully wrote data to {hex(start)}.")
|
||||||
else:
|
else:
|
||||||
print(f"Failed to write data to {hex(start)}.")
|
print(f"Failed to write data to {hex(start)}.")
|
||||||
elif cmd == "keys":
|
elif cmd == "keys":
|
||||||
keyinfo=""
|
keyinfo = ""
|
||||||
data=b""
|
data = b""
|
||||||
if args.mode in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt"]:
|
if args.mode in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt", "sej_sst_encrypt"]:
|
||||||
if not args.data:
|
if not args.data:
|
||||||
print("Option --data is needed")
|
print("Option --data is needed")
|
||||||
exit(0)
|
exit(0)
|
||||||
data = bytes.fromhex(args.data)
|
data = bytes.fromhex(args.data)
|
||||||
# otp_hisense=bytes.fromhex("486973656E736500000000000000000000000000000000000000000000000000")
|
# otp_hisense=bytes.fromhex("486973656E736500000000000000000000000000000000000000000000000000")
|
||||||
# st2.jump(0x223449)
|
# 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(keyinfo)
|
||||||
print("Wrote keys to logs/hwparam.json")
|
print("Wrote keys to logs/hwparam.json")
|
||||||
elif cmd == "reboot":
|
elif cmd == "reboot":
|
||||||
st2.reboot()
|
st2.reboot()
|
||||||
elif cmd == "seccfg":
|
elif cmd == "seccfg":
|
||||||
if args.flag not in ["unlock","lock"]:
|
if args.flag not in ["unlock", "lock"]:
|
||||||
print("Valid flags are: unlock, lock")
|
print("Valid flags are: unlock, lock")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
"""
|
"""
|
||||||
|
@ -720,15 +699,15 @@ def main():
|
||||||
SBOOT_RUNTIME_OFF = 0
|
SBOOT_RUNTIME_OFF = 0
|
||||||
SBOOT_RUNTIME_ON = 1
|
SBOOT_RUNTIME_ON = 1
|
||||||
"""
|
"""
|
||||||
if args.flag=="unlock":
|
if args.flag == "unlock":
|
||||||
lock_state = 3
|
lock_state = 3
|
||||||
critical_lock_state = 1
|
critical_lock_state = 1
|
||||||
elif args.flag=="lock":
|
elif args.flag == "lock":
|
||||||
lock_state = 1
|
lock_state = 1
|
||||||
critical_lock_state = 0
|
critical_lock_state = 0
|
||||||
with open("seccfg.bin", "wb") as wf:
|
with open("seccfg.bin", "wb") as wf:
|
||||||
seccfg_ver = 4
|
seccfg_ver = 4
|
||||||
seccfg_size = 0x3C
|
seccfg_size = 0x3C
|
||||||
sboot_runtime = 0
|
sboot_runtime = 0
|
||||||
seccfg_data = pack("<IIIIIII", 0x4D4D4D4D, seccfg_ver, seccfg_size, lock_state,
|
seccfg_data = pack("<IIIIIII", 0x4D4D4D4D, seccfg_ver, seccfg_size, lock_state,
|
||||||
critical_lock_state, sboot_runtime, 0x45454545)
|
critical_lock_state, sboot_runtime, 0x45454545)
|
||||||
|
@ -736,12 +715,13 @@ def main():
|
||||||
if args.sw:
|
if args.sw:
|
||||||
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_sw(dec_hash, True)
|
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_sw(dec_hash, True)
|
||||||
else:
|
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 = seccfg_data + enc_hash
|
||||||
data += b"\x00" * (0x200 - len(data))
|
data += b"\x00" * (0x200 - len(data))
|
||||||
wf.write(data)
|
wf.write(data)
|
||||||
print("Successfully wrote seccfg to seccfg.bin. You need to write seccfg.bin to partition seccfg.")
|
print("Successfully wrote seccfg to seccfg.bin. You need to write seccfg.bin to partition seccfg.")
|
||||||
st2.close()
|
st2.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue