Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions mtkclient/Library/DA/mtk_da_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,15 @@ def connect(self, mtk, directory:str = None):
step = self.mtk.step
mtk.preloader.dump_internal_flash(offset=offset,length=length,step=step,filename="internal_flash.bin")
else:
if mtk.serialportname is not None:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also critical, why remove it ?

mtk.preloader.init()
if directory:
self.mtk.config.hwparam_path = directory
if mtk.port.cdc.connected and os.path.exists(os.path.join(mtk.config.hwparam_path, ".state")):
mtk.daloader.reinit()
mtk.reinited = True
return mtk
else:
# Device found via USB but no DA state — likely BROM mode already connected
mtk.preloader.init(directory=directory)
if mtk.config.target_config is None:
self.info("Please disconnect, start mtkclient and reconnect.")
return None
Expand Down
53 changes: 28 additions & 25 deletions mtkclient/Library/Port.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ def run_serial_handshake(self):
while i < length:
if ep_out(int.to_bytes(startcmd[i], 1, 'little')):
v = ep_in(1, timeout=20) # Do not wait 1 sec, bootloader is only active for 0.3 sec.
if len(v) == 1 and v[0] == ~(startcmd[i]) & 0xFF:
i += 1
if len(v) == 1 and (v[0] == ~(startcmd[i]) & 0xFF or v[0] == startcmd[i]):
i += 1 # complement (UART) or same-byte echo (USB command mode)
else:
i = 0
self.info("Device detected :)")
Expand Down Expand Up @@ -134,40 +134,43 @@ def run_handshake(self, retries=5):
self.cdc.setcontrollinestate(rts=True)

startcmd = b"\xa0\x0a\x50\x05"
expected_echo = bytes(~b & 0xFF for b in startcmd) # Precompute: b'\x5f\xf5\xaf\xfa'

brom_pids = [0x3, 0xF200, 0xD1E9, 0xD1E2, 0xD1EC, 0xD1DD]
if self.cdc.pid not in brom_pids:
ep_out(b"\xa0") # Send first byte separately if needed
ep_out(b"\xa0")

for attempt in range(retries):
received = b""
try:
for byte in startcmd:
written = ep_out(bytes([byte]), timeout=500) # Explicit timeout
if written != 1:
raise ValueError("Write failed")

# Read exactly 1 echo byte (fastest)
echo = ep_in(1, timeout=500)
if len(echo) != 1 or echo[0] != (~byte & 0xFF):
raise ValueError(f"Echo mismatch: got {echo!r}, expected {~byte & 0xFF:02x}")
# Flush any bytes BROM sent before we started
try:
ep_in(maxinsize, timeout=50)
except Exception:
pass

received += echo

if received == expected_echo:
success = True
for byte in startcmd:
ep_out(bytes([byte]), timeout=500)
got_echo = False
for _ in range(64):
try:
echo = ep_in(1, timeout=100)
if len(echo) == 1:
if echo[0] == (~byte & 0xFF) or echo[0] == byte:
got_echo = True # complement (UART) or same-byte (USB)
break
except Exception:
break
if not got_echo:
success = False
break

if success:
self.info("Device detected :)")
return True

except Exception as e: # Includes USBError, timeout, pipe error
except Exception as e:
self.debug(f"Handshake attempt {attempt + 1} failed: {e}")
time.sleep(0.01) # Short backoff

# Optional: flush input buffer before retry
try:
ep_in(maxinsize, timeout=50) # Discard any stale data
except:
pass
time.sleep(0.01)

self.info("Handshake failed after retries")
return False
Expand Down
6 changes: 4 additions & 2 deletions mtkclient/Library/exploit_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# (c) B.Kerler 2018-2025 GPLv3 License
import logging
import time
import traceback
from struct import pack, unpack

from mtkclient.Library.Hardware.hwcrypto import HwCrypto, CryptoSetup
Expand Down Expand Up @@ -91,8 +92,9 @@ def da_payload(self, payload, addr, forcekamakiri=True, exploittype=1):
self.info("Done sending payload...")
time.sleep(0.2)
return True
except Exception:
self.error("Error on sending payload.")
except Exception as _exploit_ex:
self.error(f"Error on sending payload: {_exploit_ex}")
self.debug(traceback.format_exc())
return False
else:
self.info("Sending payload via insecure da.")
Expand Down
2 changes: 1 addition & 1 deletion mtkclient/config/usb_ids.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
default_ids = {
0x0E8D: {0x0003: -1, # MTK Brom
0x0E8D: {0x0003: 1, # MTK Brom - interface 1 has bulk endpoints (interface 0 is CDC comm/control only)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break many devices :(

0x6000: 2, # MTK Preloader
0x2000: -1, # MTK Preloader
0x2001: -1, # MTK Preloader
Expand Down