Chip Security TestingΒ 
Binary Security AnalysisΒ 
Contact us
Back to all articles
Binary analysis

Pixel6: Booting up

11 min read
Edit by Georges Gagnerot β€’ Sep 6, 2022


I won't give you the exploitable commands in this blog post, but you may gain some knowledge about the tools used for reversing firmwares and doing patch analysis using one of the latest exploit on Google's phone Pixel 6.


Back from my holidays, on the 25th of August, I started to catch up with all the news i missed during the previous weeks. I found some interesting news on twitter about a possible exploit on the pixel 6. The headline was interesting enough to raise my interest. bootloader.png

After a quick search, I found numerous other information that might be related to the issue on the pixel phone. Some seasoned researchers mentioned that the bug was really bad and that google HAD to fix it and force the anti-rollback.

My understanding was the following one:

The Pixel 6 has a bug in the bootloader that could make user at risk and that forced google to activate the anti-rollback to prevent any privacy issue.


Unfortunately, the fun was over pretty soon. The exploit is private, despite the messages on the Pixel Security Bulletin ... and google saying that they fuzzed the pixel 6 and went up to code execution on Titan-M was more than appealing.


That really picked my interest, if you are not aware what a RCE is, it stands for Remote Code Excecution. It's a bit like the ultimate kind of bug you can have on a software. Remote means, one can trigger the exploit without physically having the phone. Code execution implies, one can do anything on the platform. Imagine a RCE on WhatsApp: that means one can send you a message, and take control of your phone. That's how bad it is.

As time is the most precious value, and since I happened to be HOME ALONE, I decided to work a bit on this issue over the next days (and nights...).

My understanding was the following:

At least one bootloader of the pixel 6 has a major exploit leading to code execution that could be escalated up to TitanM. The flaw is major. Maybe I could have the following opportunities depending on the vulnerability:

  • Have Fun (I hardly do reverse engineering anymore but still enjoy it -- Thanks Fravia and the + team )
    • Learn about patch analysis
    • Learn about aarch64 exploitation and ROP (Return-oriented programming)
  • Install my own provisioning on the phone to have a locked bootloader but with my own ROM
  • Install a debugger in TrustZone (like that or that)
  • Forensic
  • ... (Let's stop there)

The next steps looks pretty easy (at first sight only...)


This blog post will focus on the first step, more will come later!

Just a little background before going deeper into the bootloader.

You can find information about the boot flow and TrustZone available directly from android website. Some analysis of bootloaders also provides interesting knowledge about boot process.

Here's an extract of the files present in the pixel 6 bootloader files.png

If google followed arm software specifications we probably have

PBL -> BL1 -> BL2 -> BL31 with TZSW and ABL a bit later in the boot chain.

For reference


/******************************************************************************* * Function to perform late architectural and platform specific initialization. * It also queries the platform to load and run next BL image. Only called * by the primary cpu after a cold boot. ******************************************************************************/


******************************************************************************* * The only thing to do in BL2 is to load further images and pass control to * next BL. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2 * runs entirely in S-EL1. ******************************************************************************/


/******************************************************************************* * BL31 is responsible for setting up the runtime services for the primary cpu * before passing control to the bootloader or an Operating System. This * function calls runtime_svc_init() which initializes all registered runtime * services. The run time services would setup enough context for the core to * switch to the next exception level. When this function returns, the core will * switch to the programmed exception level via an ERET. ******************************************************************************/

Realistically speaking the bootloader is most likely in EL1 and we won't be able to directly touch TrustZone context, or the EL3 one, but who knows maybe we can find some exploits later that will lead to CVE-2021-39653, CVE-2022-20174 CVE-2021-39814 CVE-2021-39684 ...


Finding the vulnerability

I am no expert in vulnerability finding but it seems that usually you find new vulnerabilities from source code review, lucky BSOD (Blue screen of death) or fuzzing techniques. When the vulnerability is known and fixed, finding the patch and understanding what is fixed seems like the easiest way. Time beeing constrained, I followed the path of finding the patch and to figure out what was the fix. One of the tool of the trade for that job is called bindiff.

First step is to download the boot image from google website i chose the following ones rom_initial.png

The first one beeing the initial revision, so most likely the most vulnerable, and I took the one from June, the one after the publication of the Pixel Bulletin. First let's extract the bootloaders using a great tool from Technologeeks.

Load into IDA as ARM64 binary IDA 8.0 helps really a lot with its new heuristic to automatically find functions! It worked really well there on this firmware.

Firmware binaries usually do not have any symbols or other metadata which would help IDA to find code in the unmarked loaded data, so users had to do it manually. In the new release, we've added a plugin which makes use of the pattern format used in Ghidra (with minor extensions). This plugin is enabled by default for binary and binary-like formats and helps IDA discover more code automatically. It can also be invoked manually for regular structured files to find otherwise unreferenced code.



If you don't have an IDA 8.0, making a script to try to create a function each next unexplored address will help you there!

And change the loading address to 0xFFFF0000F8800000.



Wait! How do I know about that loading address ? Different way to find that, the easiest being to reverse a bit the start of the boot code.



There are 2 ways to do reverse engineering for this firmware, the hard or the easy way. I will speak about the hard way on this blog, and let the astute reader find the easy one as an exercise. To start let's make the assumption that the exploit can be done by standard users, meaning that they would use standard fastboot commands! Let's find the command dispatcher then


Commands handlers on bootloader (12.0)

We will try first to try to find a command handler, let's try to look for a string we know is returned from fastboot. I will use the fastboot flashing lock or unlock command, but any other command you use typically with fastboot would yield to the same...

> fastboot flashing lock FAILED (remote: 'invalid android images, skip locking') Finished. Total time: 0.150s

We look for the string in IDA and find this function that looks promising at 0xFFFF0000F8870578 sub_FFFF0000F8870578.png

Now let's have a look at this offset in the binary, is it present somewhere? Since the bootloader handles many commands, it could very well have some kind of table to dispatch them. So let's search for it (Alt + B, FFFF0000F8870578) and let's convert the data before and after to qwords data.png

Then convert the data to offset (O or Ctrl-O shortcut). By the look of it, it seems that we have found something there! data.png

We most likely found the commands table. Moving upward, we find a cross reference at 0xFFFF0000F88FB0E0 that is most likely used in our command dispatcher function. Before going further, we can create a struct by choosing 4 fields starting with the name of the function and using the "create struct from selection" by right clicking. We rename the fields to something better like struct.png

Then we can create an array with 13 entries and rename the corresponding functions to something more suitable fb_commands.png

I never came across the usage of "upload" or "download" command before by using fastboot... It could be either hidden commands or low level commands. We will find later that it is the second one. Going back to our cross reference, we find that 0xFFFF0000F886FCB4 and its caller 0xFFFF0000F886FB88 are pretty interesting, we do some quick analysis with the help of strings and get to some nice looking dispatcher. Let's also create a new segment at 0xFFFF0000F89A9000 to prevent some bad memory access. command_loop.png

Ok we have a good starting point for bindiff let's do the same steps we did for the bootloader 12.0 but with the version 13.0 this time. Afterwards, we can export the database with bindiff's exporter and load them into bindiff to try analyzing the different functions that we previously explored. The idea here now is to find vulnerabilities (hint: you may find more than one...).

Using bindiff is pretty straightforward bindiff_scr1.gif

You can quickly see which basic blocks didn't change (green), the ones that changed (yellow) and the ones that does not exist anymore (red).



The reader is left with the task to diff commands used by bootloader 12 and compare with the same commands used in 13.0. You should find some differences, and even if you don't the next part should let you give you some hints about what to look after.

Setting up Exploitation

Guess what? I found some exploitable methods (you did find one at least right? Don't be fooled by function arguments for some others!) it's time to move to the exploitation part. The tool I use when i want to adress the bootloader is called fastboot and there's most likely things going under the hood there in order to send it's commands to the bootloader since we have seen that the bootloader parses commands that we don't usually play with. A quick look at the fastboot repository provides us with some details about it's internal fastboot_protocol_1.png

and we also get the usage for the low level commands we found in the bootloader binary:

  • getvar
  • download
  • upload
  • flash
  • erase
  • boot
  • continue
  • ...

We don't have direct access to those low lever primitives, the easiest way to get them will be to modify fastboot. How to get a coding environment up and running is a pretty easy task (you have some linux close right?).

> mkdir pixel6 > repo init -u -b android-12.0.0_r32 #(you can change this one to your liking) > repo sync -c --optimized-fetch -j16 #(or more or less) > source build/ > godir fastboot # system/core/fastboot > mma

Ok now we have our fastboot compiled and running in pixel6/out/host/linux-x86/bin/

I made a little patch to have more control over what fastboot send to the bootloader, nothing fancy there, just add two commands:

  • fastboot raw <filename>
  • fastboot rawdl <filename>

fastboot_patch.png I may have missed some checks there, but you get the idea of the patch anyway! OK end of this part, we are all set for the next post about the exploitation itself! WAAAAIIIITTTTT !!!

You had a look at the folders there? Really, no no way???!!!! We just went through all those reverse engineering process to finally find that your text editor was enough to complete the first step!

Next post will be about emulating the bootloader, then about exploitation and getting read/write capabilities.

Thanks to my teammates for their feedbacks, Fernanda, @razaina and Yoan for the tuning!



We have open positions @ eShard

If you are interested by this first blog post and want to work on research projects around bootloaders and internals of Android/iOS, we are looking for kind people! Patch Analysis, Fuzzing and Code Emulation will be 80% of your daily tasks.

If you are interested please contact us!

Top 120 European Mobile Banking App Benchmark



All articles
Binary analysis
Chip Security
Corporate News
esDynamic platform
IoT security
Side-channel analysis
Timeless analysis

you might also be interested in

Corporate News
Binary analysis

Behind the release of esReverse 2024.01

4 min read
Edit by Hugues Thiebeauld β€’ Mar 21, 2024
CopyRights eShard 2024.
All rights reserved
Privacy policy | Legal Notice