.. _boot-chain-label: ======= Booting ======= After exploitation the goal is to fully boot the device. Current boot chain: .. figure:: images/boot_chain.drawio.svg :align: center Boot chain As done by Frederic, the bootrom can be dumped using his provided scripts, and can the be split into different boots: .. code-block:: bash ./exynos-usbdl e payloads/Exynos8890_dump_bootrom.bin dumped_sboot.bin scripts/split-sboot-8890.sh dumped_sboot.bin debugger ======== Some other information about the debugger and it's current state. bl1 === Loads at address ``0x02024000`` and contains some form of header (ramdump). There seems to be a samsung header format, where the first 4 bytes define the entry point of the binary. In this case this entry is ``+0x10`` so we jump to ``0x02024010``. .. code-block:: python fwbl1 = open("../S7/bl1.bin", "rb").read() self.cd.memwrite_region(0x02024000, fwbl1) def jump_fwbl1(): self.cd.arch_dbg.state.LR = 0x2069000 self.cd.restore_stack_and_jump(0x02024010) jump_fwbl1() However, this does not result in a jump back to the debugger. The reason for this is the following code in bl1: .. code-block:: c iVar3 = FUN_02024320(); if (iVar3 == 1) { (*(code *)(ulong)uRam0000000002020108)(0,1); } 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: .. code-block:: c DAT_02020108 XREF[2]: FUN_00001708:000018b4(W), FUN_02021970:02021a40(R) 02020108 90 57 00 00 undefined4 00005790h Replacing this function with our debugger makes us jump back: .. code-block:: python # Overwrite jump back self.cd.memwrite_region(0x02020108, p32(0x2069000)) self.cd.memwrite_region(0x020200e8, p32(0x2069000)) def jump_bl1(): self.cd.arch_dbg.state.LR = 0x2069000 self.cd.restore_stack_and_jump(0x02024010) # self.cd.restore_stack_and_jump(0x02021810) bl1 = open("../S7/bl1.bin", "rb").read() self.cd.memwrite_region(0x02024000, bl1) self.usb_write(b"FLSH") # auth_bl1() jump_bl1() assert self.usb_read(0x200) == b"GiAs", "not jumped back to debugger?" self.cd.arch_dbg.state.print_ctx() root | DEBUG | X0 : 0xc00000 | X1 : 0x2069000 | X2 : 0x0 | X3 : 0x2023114 | X4 : 0x4 | X5 : 0x0 | X6 : 0x0 | X7 : 0x136c0008 | X8 : 0x2069000 | X9 : 0x0 | X10 : 0x2070000 | X11 : 0x0 | X12 : 0x0 | X13 : 0x0 | X14 : 0xf | X15 : 0x206d000 | X16 : 0x9 | X17 : 0x0 | X18 : 0x1 | X19 : 0x20200e8 | X20 : 0x0 | X21 : 0x80000000 | X22 : 0x0 | X23 : 0x0 | X24 : 0x0 | X25 : 0x0 | X26 : 0x0 | X27 : 0x1 | X28 : 0x0 | X29 : 0x2020ed8 | LR/X30 : 0x202419c | SP/X31 : 0x2020ec0 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. purpose ------- bl1 interacts with several pheriperals, from the DTB these are: .. code-block:: dtsi /* FSYS0 */ pinctrl_5: pinctrl@10E60000 { compatible = "samsung,exynos8890-pinctrl"; reg = <0x0 0x10E60000 0x1000>; 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"; }; BL31 ---- Setups EL3 stuff, probably in preperation of loading trustzone