===============
= ptrcnull.me =
===============
writeups and other stuff

Unbrick "Cannot load Android system"

Disclaimer: I have no idea on which phones it works, it might actually brick your phone even more, etc. If in doubt, don’t listen to me.

Short answer:

  • enter fastboot (depends on your phone)
  • create an 8KB empty file - truncate -s 8K file
  • flash it to para/boot_para/sometimes misc - fastboot flash para file
  • reboot

Long answer - a short tale about living with a broken phone:

Honestly, this might not even apply to you. There’s the “Try again” option. But, you see, I have a broken power button and couldn’t select it… I’ve been doing some software patches to my phone to mitigate this hardware issue, most notably making a few patches to my phone’s bootloader, incl. one that makes it boot on plugged USB cable, because sadly on this phone it’s not a togglable option, like others have. (fastboot oem off-mode-charge 0)

Unfortunately, the patches did not help this time. I was presented with two options and no way to pick either of them. Tried disconnecting my battery and connecting it back, to no avail - bootloader just skipped straight to recovery, completely ignoring the volume buttons. Making matters even worse, the recovery didn’t handle USB in any way - no fastbootd, no adb, no anything. Just the screen of doom and my phone lying to my face with the ominous “Cannot load Android system”.

After trying all the simple solutions, I realized my only hope was to patch the bootloader again (lol) and make it boot regular boot.img. To make stuff a bit easier, I focused first on getting working fastboot; from there I can just override the bootloader again and reboot without having to use the dreaded Smart Phone Flash Tool, just fastboot flash lk lk.img.

So… I opened Ghidra alongside MediaTek’s Little Kernel-based bootloader code, generously leak^Wopen-sourced by Umidigi with the Linux sources and other stuff. At first I tried to find stuff related to the actual issue itself - wipe, erase, anything like that, but couldn’t find anything meaningful. Ended up spending multiple hours trying to map the C code onto functions Ghidra was showing me, expecially that some of them were so highly optimized, that the decompiler was completely lost. Fortunately, it yielded some nice results - at the end of mt_boot_init there was a following snippet:

        /* Will not return */
        boot_linux_from_storage();

fastboot:
        target_fastboot_init();

This meant that if I’m lucky, I can get to fastboot with just one simple patch, replacing the branch instruction to boot_linux_from_storage with a NOP or two. And lucky I was, because a while later I had the patch ready and it worked! Less fortunately, removing that call meant that it couldn’t boot any Linux, and the Android recovery is one too. My workaround turned out to be another laptop with SPFT that reflashed only the lk partition - seems a bit pointless, but it allowed me for faster prototyping, because I could do most of the stuff from my Linux workstation and only use Windows for clicking one button.

What followed was a lot of trial and error with changing various things, including trying to repack the recovery - turns out magiskboot can be ran on a regular Linux machine and is really good at its job; you can just unpack the Magisk .apk file and run lib/x86_64/libmagiskboot.so. Sadly, I didn’t get much further with that, so I gave up on experimentation and opened Android Code Search in hopes of finding something useful.

From perspective, I wish I did that sooner, because only after a few minutes of looking around the code, I found bootloader_message.cpp which revealed that the bootloader uses the misc partition to communicate with recovery. The partition wasn’t there on my phone, but now that I knew where to look, I opened the recovery executable from my phone in Ghidra and found out that MTK uses the name para instead, for some reason. With all that, I ensured that making the partition empty wouldn’t break anything and just flashed it.

With all that, after a few days of messing around, I finally booted my phone (and promptly dropped it in the bathtub the same day, causing it to bootloop again before I managed to backup any data from it :) ) Fortunately, it managed to survive and serves me as a backup phone to this day.