updates docs to explain final sboot boot
This commit is contained in:
parent
0174b2a4f7
commit
6711ceea27
@ -332,3 +332,21 @@ The last stage before the kernel boots.
|
|||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Boot chain with EL3 and EL1 areas
|
Boot chain with EL3 and EL1 areas
|
||||||
|
|
||||||
|
To keep access to the debugger, but allow modifications, we need to again load the BL33, but not boot it. We need to set some registers to accomplish this. We continue our bootflow to allow the device to load BL33, and then after it is done loading, let it jump back to the debugger:
|
||||||
|
|
||||||
|
- Store BL33 address in X0: ``self.cd.arch_dbg.state.X0 = BL33_ptr``
|
||||||
|
- Store BL33 link register in LR: ``self.cd.arch_dbg.state.LR = BL33_LR``
|
||||||
|
- Set LR to debugger: ``self.cd.arch_dbg.state.LR = DEBUGGER_ADDR``
|
||||||
|
- Jump into the function that loads BL33: ``self.cd.restore_stack_and_jump(hijacked_fun)``
|
||||||
|
|
||||||
|
Now we can again load our next boot stage (BL33), send it, and verify a return to the debugger.
|
||||||
|
|
||||||
|
At this point, we tried patching something in memory at BL33 - like we did at BL31. But this always failed. After consultation, it seemed most likely that something was checking the integrity of the next boot stages. When we modified and reverted our changes, the boot was proper. The link register to continue our boot flow was at ``0x2024eec``. We did not succeed to manually do a verification, and continue the boot flow. This function at 0x2024eec does also not return, but instead continues onwards.
|
||||||
|
|
||||||
|
.. figure:: images/_integrity_check_BL2-BL33.png
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
Possible integrity check of boot stages at BL2 and BL33.
|
||||||
|
|
||||||
|
The decompilation is a bit broken, but we noticed that there are multiple calls to the same function, not just at the location where BL33 was returning from. With most specific things related to BL33 already done before this function. A similar verification seemed to have been done at ``0x02024e5c``. At this address, the same function was executed as at ``0x02024eec``, so instead of jumpingo into the function at ``0x02024eec``, we jumped into the function at ``0x02024e5c``. This worked, and allowed us to patch BL33, while continuing our boot flow. I assume, that we're doing an integrity check over BL2, while booting BL33.
|
||||||
|
@ -213,3 +213,25 @@ There's an odd space at 0x14kk. With things like deadcafe:
|
|||||||
|
|
||||||
1c0000000000000000000000fecaadde00000000fecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddef
|
1c0000000000000000000000fecaadde00000000fecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddefecaaddef
|
||||||
|
|
||||||
|
Week 37 - 2024
|
||||||
|
--------------
|
||||||
|
A few days ago, I noticed that the memory is no longer being cleared between boots. After some discussion, it seems most likely, that this is because I'm booting the device further, eventually into recovery mode. At some point, it doesn't clear the memory anymore (or it's not being cleared). This is interesting, as it allows me to see what was loaded into memory, before I start booting the device.
|
||||||
|
|
||||||
|
So, I've written something to dump the location of thte TTBR0_EL3 table, before booting any of BL1, but after loading the initial debugger. The read bytes are fluctuating, strongly, but there seems to be a pattern. I'm hoping that after enough boots, I'll have enough data to reconstruct the table.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
blub = self.cd.memdump_region(0x02035000, 0x1000)
|
||||||
|
try:
|
||||||
|
df = pd.read_pickle('ttbr0_el3.pkl')
|
||||||
|
# Concat data to existing dataframe
|
||||||
|
df = pd.concat([df, pd.Series([blub])], ignore_index=True)
|
||||||
|
except:
|
||||||
|
df = pd.DataFrame()
|
||||||
|
df['TTBR0_EL3'] = [blub]
|
||||||
|
df.to_pickle('ttbr0_el3.pkl')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 685 KiB |
@ -5,7 +5,7 @@ start,end,name,order,comment,X0,LR
|
|||||||
0x000064e0,0x0000658c,_boot_usb,,,,
|
0x000064e0,0x0000658c,_boot_usb,,,,
|
||||||
0x020c0000,0x020c0004,_frederic_dest_ptr,,,,
|
0x020c0000,0x020c0004,_frederic_dest_ptr,,,,
|
||||||
0x000002c0,0x000002c4,_jump_bl1,,,,
|
0x000002c0,0x000002c4,_jump_bl1,,,,
|
||||||
0x02022000,0x02023fff,BL1,,,,
|
0x02021800,0x02023800,BL1,,,,
|
||||||
0x02024000,0x02047fff,BL31,,,,
|
0x02024000,0x02047fff,BL31,,,,
|
||||||
0x02048000,0x0206ed10,BL2,,,,
|
0x02048000,0x0206ed10,BL2,,,,
|
||||||
0x02069000,0x0206f000,Debugger,,,,
|
0x02069000,0x0206f000,Debugger,,,,
|
||||||
|
|
@ -1,63 +0,0 @@
|
|||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
root | INFO | Connection is working
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
|
|
||||||
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
root | INFO | Connection is working
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
|
|
||||||
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
root | INFO | Connection is working
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc42508b2f1462
|
|
||||||
Bits: 0000000010111100010000100101000010001011001011110001010001100010
|
|
||||||
|
|
||||||
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
root | INFO | Connection is working
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1462
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100010
|
|
||||||
|
|
||||||
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1460
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100000
|
|
||||||
root | INFO | Connection is working
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1460
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100000
|
|
||||||
Connected device! 0x4e8 0x1234
|
|
||||||
[+] Sent stage
|
|
||||||
TTBR0_EL3: 0xbc46508b2f1460
|
|
||||||
Bits: 0000000010111100010001100101000010001011001011110001010001100000
|
|
@ -632,6 +632,18 @@ class ExynosDevice():
|
|||||||
self.cd.arch_dbg.state.print_ctx()
|
self.cd.arch_dbg.state.print_ctx()
|
||||||
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
||||||
|
|
||||||
|
# Dump contents of TTBR0_EL3 from memory into a pandas dataframe and write it to a pickle file
|
||||||
|
import pandas as pd
|
||||||
|
blub = self.cd.memdump_region(0x02035000, 0x1000)
|
||||||
|
try:
|
||||||
|
df = pd.read_pickle('ttbr0_el3.pkl')
|
||||||
|
# Concat data to existing dataframe
|
||||||
|
df = pd.concat([df, pd.Series([blub])], ignore_index=True)
|
||||||
|
except:
|
||||||
|
df = pd.DataFrame()
|
||||||
|
df['TTBR0_EL3'] = [blub]
|
||||||
|
df.to_pickle('ttbr0_el3.pkl')
|
||||||
|
|
||||||
# Relocate debugger
|
# Relocate debugger
|
||||||
debugger = open("../../dump/reloc_debugger_0x11200000.bin", "rb").read()
|
debugger = open("../../dump/reloc_debugger_0x11200000.bin", "rb").read()
|
||||||
self.relocate_debugger(debugger=debugger, entry=0x11200000, storage=0x11203000, g_data_received=0x11204000)
|
self.relocate_debugger(debugger=debugger, entry=0x11200000, storage=0x11203000, g_data_received=0x11204000)
|
||||||
@ -659,18 +671,6 @@ class ExynosDevice():
|
|||||||
self.send_normal_stage(bl1)
|
self.send_normal_stage(bl1)
|
||||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||||
|
|
||||||
# Dump contents of TTBR0_EL3 from memory into a pandas dataframe and write it to a pickle file
|
|
||||||
import pandas as pd
|
|
||||||
blub = self.cd.memdump_region(0x02035000, 0x1000)
|
|
||||||
try:
|
|
||||||
df = pd.read_pickle('ttbr0_el3.pkl')
|
|
||||||
# Concat data to existing dataframe
|
|
||||||
df = pd.concat([df, pd.Series([blub])], ignore_index=True)
|
|
||||||
except:
|
|
||||||
df = pd.DataFrame()
|
|
||||||
df['TTBR0_EL3'] = [blub]
|
|
||||||
df.to_pickle('ttbr0_el3.pkl')
|
|
||||||
|
|
||||||
# Setup jump and bl_auth
|
# Setup jump and bl_auth
|
||||||
AUTH_BL1 = 0x00012848 # Location of the authentication function
|
AUTH_BL1 = 0x00012848 # Location of the authentication function
|
||||||
def auth_bl1(lr=0x2069000, x0=1, x1=1):
|
def auth_bl1(lr=0x2069000, x0=1, x1=1):
|
||||||
@ -801,20 +801,16 @@ class ExynosDevice():
|
|||||||
|
|
||||||
print(self.cd.arch_dbg.state.print_ctx())
|
print(self.cd.arch_dbg.state.print_ctx())
|
||||||
|
|
||||||
# Trying to patch BL33 but continuing good boot flow
|
|
||||||
# auth_bl1(DEBUGGER_ADDR, 0, 0)
|
|
||||||
|
|
||||||
# # Modify something in BL33
|
# # Modify something in BL33
|
||||||
print(self.cd.memdump_region(0x8f063710, 0x8))
|
print(self.cd.memdump_region(0x8f063710, 0x8))
|
||||||
# Samsung == SaMtung
|
|
||||||
self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53614d74))
|
self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53614d74))
|
||||||
|
|
||||||
# Modify USB Recovyer mode string to something else
|
# Modify USB Recovyer mode string to something else
|
||||||
self.cd.memwrite_region(0x8f06ab10, b'\x50\x41\x54\x43\x48\x49\x4e\x47\x20\x42\x4c\x33\x33\x3a\x2d\x29\x0a\x00')
|
self.cd.memwrite_region(0x8f06ab10, b'\x4e\x46\x49\x20\x50\x61\x74\x63\x68\x69\x6e\x67\x20\x42\x4c\x33\x33')
|
||||||
print(self.cd.memdump_region(0x8f063710, 0x8))
|
print(self.cd.memdump_region(0x8f063710, 0x8))
|
||||||
|
|
||||||
# Do signature verification on BL2 instead of BL33 and proceed to boot (original is jump to 0x2024eec)
|
# Do signature verification on BL2 instead of BL33 and proceed to boot (original is jump to 0x2024eec)
|
||||||
self.cd.restore_stack_and_jump(0x02024e58)
|
self.cd.restore_stack_and_jump(0x02024e5c)
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user