Skip to content

Fix MT6768 BROM USB handshake and interface selection (0e8d:0003) - #264

Open
chinmayabansal wants to merge 2 commits into
bkerler:mainfrom
chinmayabansal:fix/mt6768-brom-usb-handshake
Open

Fix MT6768 BROM USB handshake and interface selection (0e8d:0003)#264
chinmayabansal wants to merge 2 commits into
bkerler:mainfrom
chinmayabansal:fix/mt6768-brom-usb-handshake

Conversation

@chinmayabansal

@chinmayabansal chinmayabansal commented Jun 29, 2026

Copy link
Copy Markdown

Summary

Fixes BROM communication for MediaTek MT6768 (Helio P65/G85) over USB CDC when the device enumerates as 0e8d:0003.

Problems fixed

  1. usb_ids.py — PID 0x0003 used interface -1 (auto); auto-select picked CDC comm interface 0 (interrupt only, no bulk). Bulk endpoints are on interface 1.
  2. Port.py — BROM handshake only accepted bitwise-complement echo (UART). MT6768 BROM over USB echoes the same byte; handshake looped forever (Handshake failed, retrying...).
  3. mtk_da_handler.py — If the device was already connected in USB BROM mode at startup, preloader.init() was skipped → Please disconnect, start mtkclient and reconnect.
  4. exploit_handler.py — Payload failures were caught without logging the underlying exception (hid AttributeError when --serialport was used).

Test device

  • Model: Lenovo Tab M9 TB310XU
  • SoC: MT6768 / MT6769, HW code 0x707
  • Host: Ubuntu Linux, udev rules from Setup/Linux/, ModemManager masked
  • Command: sudo python3 mtk.py e frp
  • Result: FRP partition formatted at 0x1508000, device boots to setup wizard without account lock

Notes

  • Debugged with AI assistance; reproduced on physical hardware.
  • Does not use --serialport (Kamakiri2 requires USB ctrl_transfer).
  • macOS host may still have separate libusb permission issues; this PR targets Linux USB path.

Checklist

  • Tested on real MT6768 hardware
  • Minimal diff, no unrelated changes

- usb_ids: use interface 1 for PID 0x0003 (bulk endpoints on CDC data iface)
- Port: accept same-byte handshake echo over USB (MT6768 BROM command mode)
- mtk_da_handler: init preloader when USB device already connected in BROM
- exploit_handler: surface exception details on payload send failure

Tested: Lenovo Tab M9 TB310XU (MT6768, HW 0x707), sudo python3 mtk.py e frp
Keeps the error message string on failure; stack trace only with --debugmode.
@chinmayabansal

chinmayabansal commented Jun 29, 2026

Copy link
Copy Markdown
Author

Re exploit_handler.py traceback: the unconditional print_exc() is noisy for normal runs.

Pushed a follow-up commit — stack trace now goes through self.debug(traceback.format_exc()), so it only surfaces with --debugmode. The main fix remains the error message string (Error on sending payload: {exception}), which is what made the --serialport / ctrl_transfer failure diagnosable on MT6768.

Happy to adjust further if you prefer a different logging pattern.

@bkerler

bkerler commented Jul 2, 2026

Copy link
Copy Markdown
Owner

I don't think I can add this patch, as it would break a lot of other devices. Can you please explain why you did the changes the way you did ? because some of them do not even make sense (connect is happening after connected state is checked - thus will never work)

@sleepy-natalie

Copy link
Copy Markdown

At this point nake it it's own thing like how it is with the Redmi 13c

@chinmayabansal

Copy link
Copy Markdown
Author

Thanks for the review.

Re the connect() concern: the patch doesn't call connect() twice. Line 114 always runs cdc.connect() once. The else branch is for when USB is already up at startup — if .state exists we reinit() (DA resume); if not, we call preloader.init() (BROM case). Without that, TB310XU hit target_config is None → "Please disconnect…".

Other fixes (TB310XU / MT6768, HW 0x707, 0e8d:0003):

  • usb_ids: interface 1 has bulk EPs; interface 0 doesn't
  • Port.py: BROM echoes same byte over USB, not UART complement → handshake loop
  • exploit_handler: error string + traceback via self.debug() only

Verified with sudo python3 mtk.py e frp (FRP erased at 0x1508000). Debugged with AI assistance on real hardware.

Happy to gate usb_ids/handshake on HW 0x707 only, or keep TB310XU patches on my fork — whichever you prefer.

@@ -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 :(

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 ?

@bkerler

bkerler commented Aug 7, 2026

Copy link
Copy Markdown
Owner

at this state of the PR, I cannot merge it right now. I took parts of your PR and integrated it in the upcoming version. Will keep this as draft for now. Once you tested it with your device, I will merge this and add credits to you :)

@chinmayabansal

Copy link
Copy Markdown
Author

Thanks for taking parts of this into the upcoming version — and for the notes on usb_ids / serialportname. Makes sense.

When the draft or next release is ready to try, I’ll re-test sudo python3 mtk.py e frp on the Tab M9 TB310XU (MT6768) and report back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants