To the best of my knowledge, SBOOT uses a proprietary format that is not documented.

Many AArch64 instructions were automatically recognized. When poking around disassembled instructions, basic blocks made sense, letting me think that I really dealt with AArch64 code:

I assumed that the BootROM had not switched to AArch32 state and loaded it first into IDA Pro as a 64-bit binary, leaving the default options:

The Samsung Galaxy S6 is powered by 1.5GHz 64-bit octa-core Samsung Exynos 7420 CPU. Recall that ARMv8 processors can run applications built for AArch32 and AArch64. Thus, one can try to load SBOOT as a 32-bit or a 64-bit ARM binary.

Determining the Base Address

It took me a few days to determine the right base address. As giving you directly the solution is pointless, I first detail all the things I have tried until making the correct assumption which gave me the right base address. As the proverb says, whoever wrote this: "Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime".

Web Search I started by searching for Samsung bootloader and SBOOT related work on several search engines. Unfortunately, results on the subject were scarce and only one reverseengineering.stackexchange.com thread dating back to March 2015 was relevant. This thread mainly gives us 2 hints. J-Cho had the intuition that the bootloader starts at the file offset 0x3F000 and Just helping suggests that it is actually starting at 0x10 . As I wanted to dismiss my hypothesis that the bootloader base address is 0x00000000 and that its code always begins at 0x10 , I started to look for bootloaders used in other Exynos smartphones. SBOOT in Meizu's smartphones does not give valid instructions at 0x10 , confirming my doubts: I also analyzed if there were any debug string left on other bootloaders that would give me hints on where SBOOT is generally loaded in memory. No luck :( But I got another lead: some strings in Meizu's SBOOT suggested that U-Boot is used. Even if U-Boot is not used on Samsung Galaxy S6, it was a lead worth exploring and I started to dig further.

U-Boot Repository U-Boot is open-source and supports several Exynos chips. For instance, Exynos 4 and Exynos 5 have been supported for more than 5 years now. Support for the Exynos 7 has not fully landed on the mainline yet but, based on their mailing list , some patches exist for the Exynos 7 ESPRESSO development board. I may have missed it, but going through patches for the ESPRESSO development board did not bear fruits :( I tried multiple known base addresses from Exynos 4 to Exynos 7 boards without succeeding. It was time to try another angle.

ARM Literal Pools If you are used to reverse engineering ARM assembly, you must have noticed the massive use of literal pools to hold certain constant values that are to be loaded into registers. This property may help us to find approximately where SBOOT is loaded, especially when a branch destination address is loaded from a literal pool. I searched all the branching instructions marked with errors in operands (highlighted in red) by IDA Pro. As the code of a bootloader is self-contained, I can safely assume that most of the branches destination address must target code in the bootloader itself. With this assumption, I could approximate the bootloader's base address. From the very first instructions, I noticed the following branching errors: The interesting facts on these code fragments are: Branching instructions BR (Branch to register) are unconditional and suggest that it will not return. The operand value for both branches is the same ( 0x2104010 ) and, it is located very early in the bootloader. The last byte is 0x10 which is exactly the offset where the code of the bootloader seems to begin. I arbitrarily assumed that the address 0x2104010 was a reset address and I tried to load the SBOOT binary at 0x2104000 , with the following options: Processor Type: ARM Little Endian [ARM]

Start ROM Address: 0x2104000

Loading Address: 0x2104000

Disassemble as 64-bit code: Yes At least, IDA Pro found fewer errors which indicates that my assumption may be correct. Yet, I could not tell for sure that this base address was the right one, I needed to reverse engineer further to be sure. Spoiler: I nearly got it right :)

ARM System Registers Now that I may have the potential base address, I continued reverse engineering SBOOT hoping that there were no anomalies in the code flow. As I wanted to find the TEE OS, I started searching for pieces of code executed in the secure monitor. A rather simple technique to find the secure monitor consists in looking for instructions that set or read registers that can only be accessed from the secure monitor. As previously mentioned, the secure monitor runs in EL3 . VBAR_EL3 is rather a good candidate to find EL3 code as it holds the base address of the EL3 exception vector table and leads to SMC handlers. Do you remember the exception vector table's format presented at the beginning of this article? It is made of 16 entries of 0x80 bytes holding the code of exception handlers. Amongst the search results, code at 0x2111000 seemed to lead to a valid exception vector table: Even though, the chosen base address was still not the right one :( When verifying other instructions that set VBAR_EL3 , one can note that 0x210F000 is in the middle of a function: These anomalies would suggest that 0x2104000 is not the right base address yet. Let us try something else.