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 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. 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 .. 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``). 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 TODO TODO TODO
The reason for this is the following code in bl1: 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: # with open("/tmp/imem2_bad.bin", "wb") as f:
# f.write(imem2) # 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(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(0x020200e8, p32(0x020c0000)) # Overwrite line register to jump back to debugger, at function
self.cd.memwrite_region(0x020200dc, p32(0x020c0000)) self.cd.memwrite_region(0x020200dc, p32(0x020c0000))
@ -398,6 +400,7 @@ class ExynosDevice():
jump_bl1(0x020c0000) jump_bl1(0x020c0000)
while True: while True:
try: try:
logging.debug(f'Within jump_bl1')
resp = self.usb_read(0x200) resp = self.usb_read(0x200)
if self.cd.arch_dbg.state.LR == 0x02022948: if self.cd.arch_dbg.state.LR == 0x02022948:
break # ROM will load next stage over USB break # ROM will load next stage over USB
@ -406,6 +409,39 @@ class ExynosDevice():
pass pass
# TODO load bl31 # 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