Booting bl31 fails as soon as we jump into it at 02021810

This commit is contained in:
Jonathan Herrewijnen 2024-08-13 16:42:17 +02:00
parent 7a80b9f5a9
commit 99385d69e9
4 changed files with 45 additions and 3 deletions

View File

@ -90,6 +90,12 @@ The processor state reported then is:
bl1
===
.. figure:: images/initial_boot_function.png
:align: center
Overview of the initial boot function in the exynos 8890
BL1 needs to be authenticated. 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``. Authentication seems to be done at ``0x00012848``. Initially we thought that 0x0 indicated a verified boot state (as is plausible when reading the decompiled code in Ghidra). But after modifying BL1 in the header and contents, this value did not change.
.. code-block:: python
@ -140,9 +146,9 @@ After authentication the bootROM jumps to this function at, we can execute this
BL1 is laoded at the download buffer and self copies to ``0x02024000`` and resumes execution there (``0x02024010``).
However, this does not result in a jump back to the debugger. But the ROM still receives data from the host
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).
! one payload allowed to be sent by the bootrom.
By adding the IMEM to ghidra, we can have a look at what is going here. (How is this done in Ghidra?). We seem to lose control of our debugger once we step into the `some_weird_brom_function`.
TODO TODO TODO
The reason for this is the following code in bl1:

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -381,8 +381,10 @@ class ExynosDevice():
# with open("/tmp/imem2_bad.bin", "wb") as f:
# f.write(imem2)
# Works until here TODO hijack future control flow
# Overwrite jump back to the debugger from functions encountered during jump_bl1
# self.cd.memwrite_region(0x02020108, p32(0x020c0000)) # Hijack some weird function, original 0x00005790
#
self.cd.memwrite_region(0x020200e8, p32(0x020c0000)) # Overwrite line register to jump back to debugger, at function
self.cd.memwrite_region(0x020200dc, p32(0x020c0000))
@ -398,6 +400,7 @@ class ExynosDevice():
jump_bl1(0x020c0000)
while True:
try:
logging.debug(f'Within jump_bl1')
resp = self.usb_read(0x200)
if self.cd.arch_dbg.state.LR == 0x02022948:
break # ROM will load next stage over USB
@ -406,6 +409,39 @@ class ExynosDevice():
pass
# TODO load bl31
bl31 = open("../S7/bl31.bin", "rb").read()
bl31 = bl31[:0x14] + self.cd.arch_dbg.sc.branch_absolute(0x2069000) + bl31[0x24:]
# Write 0's to 0x02021800 to 0x0206ffff. Except for debugger location, at: 0x020c0000 to 0x020c6000
self.cd.memwrite_region(0x02021800, b"\x00" * 0x4E800)
self.cd.memwrite_region(0x02021800, bl31)
imem_bl31_pre_auth = memdump_imem()
with open("/tmp/imem_bl31_pre_auth.bin", "wb") as f:
f.write(imem_bl31_pre_auth)
auth_bl1(0x020c0000)
imem_bl31_post_auth = memdump_imem()
with open("/tmp/imem_bl31_post_auth.bin", "wb") as f:
f.write(imem_bl31_post_auth)
# TEST JONATHAN
self.cd.jump_to(0x02021800)
self.cd.memwrite_region(0x020200e8, p32(0x020c0000))
self.cd.memwrite_region(0x020200dc, p32(0x020c0000))
# Patch bl31
# self.cd.jump_to(0x2069000)
# self.cd.memwrite_region(0x02021800 + 0x14, self.cd.arch_dbg.sc.branch_absolute(0x2069000))
# jump_bl1(0x2069000)
self.cd.jump_to(0x02021800 + 0x14)
pass