General notes on interesting/peculiar things found on the S7 USB recovery boot process

Emulator

What is interesting about the ROM is that it starts by checking MPIDR_EL1 register and doing a conditional branch to 0x20e0000.

bash false Reset XREF[1]: Entry Point(*) 00000000 bb 00 38 d5 mrs x27,mpidr_el1 00000004 7b 0f 78 92 and x27,x27,#0xf00 00000008 7f 03 00 f1 cmp x27,#0x0 0000000c 41 00 00 54 b.ne LAB_00000014 00000010 fc 7f 83 14 b LAB_020e0000]]>

BL1 peculiarities

At this point, we assumed that the authentication was succesful, and the bootROM would jump back to the debugger after loading, but this was not the case. After running this function, we were able to send a single packet, but never received a response. Indicating that the function we were executing never returned on us.

BL1 authentication

If authentication at auth_bl1 is succesful, the returns a value from a function at 1230c. This function does some things, but eventually jumps to a function at:

BL1 authentication

After authentication the bootROM jumps to this function at, we can execute this function with the debugger.

python false

BL1 is loaded at the download buffer and self copies to 0x02022000 and resumes execution there, with a size of 0x2000 (0x02022000 to 0x02024000).

However, this does not result in a jump back to the debugger. But the ROM still allows receival of one data package from the USB host (this is likely the system ‘waiting’ to receive the bootloader).

By adding the IMEM to ghidra, we can have a look at what is going here. After having modified the LR to jump back to the debugger and jumping into auth_bl1 at 0x00012848 we jump back to the debugger. Jumping into BL1 at 2c0 does not return us to the debugger. Here we need to hijack 020200dc and 02021880 we’re able to boot into BL1. We store the address of the hijacked function, to restore it later for a proper boot flow.

python false

Authentication of BL1 seems to be done at 0x0012848. With return value ‘0’ expected when this function is executed, to execute other functions.

BL1 authentication.

purpose

bl1 interacts with several pheriperals, from the DTB these are:

bash false ; interrupts = <0 212 0>; }; /* FSYS1 */ pinctrl_6: pinctrl@15690000 { compatible = "samsung,exynos8890-pinctrl"; reg = <0x0 0x15690000 0x1000>; interrupts = <0 202 0>; }; /* PERIC1 */ pinctrl_9: pinctrl@14CC0000 { compatible = "samsung,exynos8890-pinctrl"; reg = <0x0 0x14CC0000 0x1000>; interrupts = <0 460 0>; }; pmu_system_controller: system-controller@105C0000 { compatible = "samsung,exynos8890-pmu", "syscon"; reg = <0x0 0x105C0000 0x10000>; }; rtc@10070000 { compatible = "samsung,s3c6410-rtc"; reg = <0x0 0x10070000 0x100>; interrupts = <0 73 0>, <0 74 0>; clocks = <&clock 157>; clock-names = "gate_rtc"; };]]>

Probably the only thing it does is set some clocks and prepare for BL31.

The reason for this is the following code in bl1:

cpp false

This code uses a predefined ROM function(I was looking for it) and jumps back to that function when it’s done. This function is at address 0x020200e8, looking in our IMEM dump we can see where in the ROM this points to:

cpp false

Replacing this function with our debugger makes us jump back:

python false

However this does not fully run bl1, so we will have to dig a bit deeper to see the puropose and when to jump back to the debugger.

Week 35 - 2024

After booting BL31, the MMU seems to be set up, and we’re unable to do get any data off of spaces we’re not ‘allowed’ to access. Patching the if-statement at 0x020244e8, disables the bit that says that the MMU is setup, but booting into recovery is possible (meaning the MMU is setup). Additionally, the memory at 0x02035600 is still not dumpable. At 0x02048000 is still accessible.

Weird space found at 0x105c2400. Seems to contain references to usb buffer (about 48-64 bytes). Also space at 0x020307f0, but I lose access to this after booting

python false

Week 36 - 2024

Interesting links: - Heap overflow - UART on S8

By accident found space at 0x11207010. Seems to be a memory read/write space. Not executable however, unless the MMU is turned off.

We can use this space to store our debugger, and patch the boot process. After loading BL2, we’re now indeed loading VBAR’s for EL1.

bl31 MMU is 0x0 (0x1=enabled, 0x0=disabled) TTBR0_EL3: 0xbc4640892f1460, TTBR1_EL2: 0x854d39cb76f0, TTBR0_EL1: 0xa5c20f408c581142 VBAR_EL3: 0x18800, VBAR_EL2: 0x0, VBAR_EL1: 0x0 TCR_EL3: 0x0, TCR_EL2: 0x80800000, TCR_EL1: 0x0 SCTLR_EL3: 0xc5183a, SCTLR_EL2: 0x30c5083a, SCTLR_EL1: 0xc5083a MAIR_EL3: 0x44e048e000098aa4, MAIR_EL2: 0x9e42bf572931240b, MAIR_EL1: 0x44e048e000098aa4 Current EL: 0xc

Jumped to 0x11207010 and back

bL2 [+] Sent stage Connected device! 0x4e8 0x1234 MMU is 0x0 (0x1=enabled, 0x0=disabled) TTBR0_EL3: 0xbc4640892f1460, TTBR1_EL2: 0x854d39cb76f0, TTBR0_EL1: 0xa5c20f408c581142 VBAR_EL3: 0x2031800, VBAR_EL2: 0x0, VBAR_EL1: 0x2053800 TCR_EL3: 0x0, TCR_EL2: 0x80800000, TCR_EL1: 0x0 SCTLR_EL3: 0xc5183a, SCTLR_EL2: 0x30c5083a, SCTLR_EL1: 0x30c5083a MAIR_EL3: 0x44e048e000098aa4, MAIR_EL2: 0x9e42bf572931240b, MAIR_EL1: 0x44e048e000098aa4 Current EL: 0xc

The debugger at 0x11200000 can only dump 0x768 at a time (its space related. Before BL31 this is also an issue.).

There’s an odd space at 0x14kk. With things like deadcafe:

python false