Adding ghidra BL31 file for later inspection
This commit is contained in:
parent
20ad0cdb45
commit
c03af09de2
@ -17,6 +17,4 @@ What is interesting about the ROM is that it starts by checking MPIDR_EL1 regist
|
|||||||
|
|
||||||
Week 35 - 2024
|
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. Interestingly, one of the setups is at
|
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.
|
||||||
|
|
||||||
Patching the if-statement at 0x020244e8, and in doing so, disabling this function.
|
|
@ -2631,6 +2631,170 @@
|
|||||||
"# Save to html\n",
|
"# Save to html\n",
|
||||||
"fig.write_html(\"../_static/stack_and_functions.html\")"
|
"fig.write_html(\"../_static/stack_and_functions.html\")"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Layered blocks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import plotly.graph_objects as go\n",
|
||||||
|
"import random\n",
|
||||||
|
"\n",
|
||||||
|
"tickpointers = []\n",
|
||||||
|
"vertical_len = len(data['overlap_with'].unique())\n",
|
||||||
|
"vertical_gap_percentage = 0.08\n",
|
||||||
|
"horizontal_gap = 0.1\n",
|
||||||
|
"labels = pd.DataFrame()\n",
|
||||||
|
"\n",
|
||||||
|
"def random_color():\n",
|
||||||
|
" return f'#{random.randint(0, 0xFFFFFF):06x}'\n",
|
||||||
|
"\n",
|
||||||
|
"fig = go.Figure()\n",
|
||||||
|
"\n",
|
||||||
|
"for i, d in data.iterrows():\n",
|
||||||
|
" fillcolor = random_color()\n",
|
||||||
|
" data.at[i, 'fillcolor'] = fillcolor\n",
|
||||||
|
" \n",
|
||||||
|
" x0=1\n",
|
||||||
|
" x1=4\n",
|
||||||
|
"\n",
|
||||||
|
" if d['overlap'] == False:\n",
|
||||||
|
" y0=d['overlap_with']\n",
|
||||||
|
" y1=d['overlap_with']+1\n",
|
||||||
|
" elif d['overlap'] == True:\n",
|
||||||
|
" overlaps = data.loc[data['overlap_with'] == d['overlap_with']].shape[0]\n",
|
||||||
|
"\n",
|
||||||
|
" # Calculate relative size of the overlap\n",
|
||||||
|
" overlap_sizes = data.loc[data['overlap_with'] == d['overlap_with']].iloc[1:]['size'].sum()\n",
|
||||||
|
"\n",
|
||||||
|
" if d['overlap_with'] == i:\n",
|
||||||
|
" y0=i\n",
|
||||||
|
" y1=overlaps+i\n",
|
||||||
|
" if i != data.shape[0]+1:\n",
|
||||||
|
" if d['end'] > data.iloc[i+1].start and d['end'] < data.iloc[i+1].end:\n",
|
||||||
|
" y1=overlaps+i-0.5\n",
|
||||||
|
" x0=x0-horizontal_gap\n",
|
||||||
|
" x1=x1+horizontal_gap\n",
|
||||||
|
" else:\n",
|
||||||
|
" y0=0.02+i\n",
|
||||||
|
" y1=0.87+i\n",
|
||||||
|
" else:\n",
|
||||||
|
" print(f'Something went wrong with {d}. Skipping')\n",
|
||||||
|
" continue\n",
|
||||||
|
"\n",
|
||||||
|
" fig.add_shape(\n",
|
||||||
|
" type=\"rect\",\n",
|
||||||
|
" x0=x0,\n",
|
||||||
|
" x1=x1,\n",
|
||||||
|
" y0=y0+vertical_gap_percentage,\n",
|
||||||
|
" y1=y1-vertical_gap_percentage,\n",
|
||||||
|
" line=dict(width=2),\n",
|
||||||
|
" fillcolor=fillcolor,\n",
|
||||||
|
" opacity=0.5,\n",
|
||||||
|
" layer=\"below\",\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # Add middle text\n",
|
||||||
|
" fig.add_trace(go.Scatter\n",
|
||||||
|
" (\n",
|
||||||
|
" x=[(x0+x1)/2],\n",
|
||||||
|
" y=[y0+0.5],\n",
|
||||||
|
" text=d['name'],\n",
|
||||||
|
" mode=\"text\",\n",
|
||||||
|
" textposition=\"middle center\",\n",
|
||||||
|
" name=d['name'],\n",
|
||||||
|
" marker=dict(\n",
|
||||||
|
" color=fillcolor,\n",
|
||||||
|
" ),\n",
|
||||||
|
" ))\n",
|
||||||
|
"\n",
|
||||||
|
" # Add top-left text with d['end']\n",
|
||||||
|
" fig.add_trace(go.Scatter\n",
|
||||||
|
" (\n",
|
||||||
|
" x=[(x0+0.14+horizontal_gap)],\n",
|
||||||
|
" y=[y1-0.16],\n",
|
||||||
|
" text=hex(d['end']),\n",
|
||||||
|
" mode=\"text\",\n",
|
||||||
|
" textposition=\"middle center\",\n",
|
||||||
|
" marker=dict(\n",
|
||||||
|
" color=fillcolor,\n",
|
||||||
|
" ),\n",
|
||||||
|
" showlegend=False,\n",
|
||||||
|
" ))\n",
|
||||||
|
"\n",
|
||||||
|
" # Add bottom-left text with d['end']\n",
|
||||||
|
" fig.add_trace(go.Scatter\n",
|
||||||
|
" (\n",
|
||||||
|
" x=[(x0+0.14+horizontal_gap)],\n",
|
||||||
|
" y=[y0+0.14],\n",
|
||||||
|
" text=hex(d['start']),\n",
|
||||||
|
" mode=\"text\",\n",
|
||||||
|
" textposition=\"middle center\",\n",
|
||||||
|
" marker=dict(\n",
|
||||||
|
" color=fillcolor,\n",
|
||||||
|
" ),\n",
|
||||||
|
" showlegend=False,\n",
|
||||||
|
" ))\n",
|
||||||
|
"\n",
|
||||||
|
"fig.update_xaxes(\n",
|
||||||
|
" range=[0, 5],\n",
|
||||||
|
" tickvals=[0, 1, 2, 3, 4, 5],\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"start_values = data['start'].sort_values()\n",
|
||||||
|
"end_values = data['end'].sort_values()\n",
|
||||||
|
"\n",
|
||||||
|
"labels = []\n",
|
||||||
|
"\n",
|
||||||
|
"for i, d in data.iterrows():\n",
|
||||||
|
" if i == 0:\n",
|
||||||
|
" labels.append(f'{hex(start_values.iloc[i])}')\n",
|
||||||
|
" elif i == len(data)-1:\n",
|
||||||
|
" labels.append(f'{hex(end_values.iloc[i])}')\n",
|
||||||
|
" else:\n",
|
||||||
|
" labels.append(f'{hex(start_values.iloc[i])}<br>{hex(end_values.iloc[i-1])}')\n",
|
||||||
|
"\n",
|
||||||
|
"tickpointers = [i for i in range(len(data))]\n",
|
||||||
|
"\n",
|
||||||
|
"fig.update_yaxes(\n",
|
||||||
|
" # tickvals=[i for i in range(len(data)+1)], \n",
|
||||||
|
" tickvals = tickpointers,\n",
|
||||||
|
" # ticktext= labels,\n",
|
||||||
|
" griddash=\"longdashdot\",\n",
|
||||||
|
" gridwidth=0,\n",
|
||||||
|
" gridcolor=\"black\",\n",
|
||||||
|
" showgrid=False,\n",
|
||||||
|
" showticklabels=True,\n",
|
||||||
|
" autorange='reversed',\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"fig.update_xaxes(\n",
|
||||||
|
" showgrid=False,\n",
|
||||||
|
" showticklabels=False,\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"fig.update_layout(\n",
|
||||||
|
" width=1200,\n",
|
||||||
|
" height=1200,\n",
|
||||||
|
" autosize=True,\n",
|
||||||
|
" margin=dict(l=200, r=20, t=20, b=20),\n",
|
||||||
|
" font=dict(\n",
|
||||||
|
" size=18,\n",
|
||||||
|
" ),\n",
|
||||||
|
" # Legend being the name of the function\n",
|
||||||
|
" legend_title_text=\"Function/Locations\",\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"fig.show()"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
@ -624,6 +624,19 @@ class ExynosDevice():
|
|||||||
print(f'Jumped to {hex(address)} and back')
|
print(f'Jumped to {hex(address)} and back')
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_special_regs(self):
|
||||||
|
"""
|
||||||
|
Get all special registers from the device.
|
||||||
|
"""
|
||||||
|
self.cd.fetch_special_regs()
|
||||||
|
|
||||||
|
# Get all valeus from self.cd.arch_dbg.state
|
||||||
|
|
||||||
|
|
||||||
|
self.cd.arch_dbg.state.print_ctx()
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def debugger_boot(self):
|
def debugger_boot(self):
|
||||||
"""
|
"""
|
||||||
Boot into USB recovery mode using the debugger.
|
Boot into USB recovery mode using the debugger.
|
||||||
@ -742,15 +755,13 @@ class ExynosDevice():
|
|||||||
TTBR0_EL3 = 0x02035600 # Zeroed out
|
TTBR0_EL3 = 0x02035600 # Zeroed out
|
||||||
|
|
||||||
# Modifies/disables setting up MMU (but is set up eventually) -> MMU says 0x0 instead of 0x1, but still little access (and proper USB recovyer boot!?)
|
# Modifies/disables setting up MMU (but is set up eventually) -> MMU says 0x0 instead of 0x1, but still little access (and proper USB recovyer boot!?)
|
||||||
# self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always false
|
|
||||||
|
|
||||||
# Overwrite jump back at 0202f810
|
|
||||||
# self.cd.memwrite_region(0x020242a8, struct.pack('>I', 0x568f0094)) # Last succesful jump back to debugger, while still having access to 0x02035600
|
|
||||||
|
|
||||||
# self.cd.memwrite_region(0x02032008, struct.pack('>I', 0x1f2003d5)) # Overwrite MAIR to NOP
|
# self.cd.memwrite_region(0x02032008, struct.pack('>I', 0x1f2003d5)) # Overwrite MAIR to NOP
|
||||||
# self.cd.memwrite_region(0x0203203c, struct.pack('>I', 0xf1570094)) # Return to debugger. (not working, it continues booting..)
|
# self.cd.memwrite_region(0x0202ee74, struct.pack('>I', 0x63650094)) # Return to debugger. (not working, it continues booting..)
|
||||||
|
|
||||||
# self.cd.memwrite_region(0x0203200c, struct.pack('>I', 0xfd570094)) # -> X1=0x18800, X30=0x20241a0. Device crashes when writing here.
|
# self.cd.memwrite_region(0x0202eb74, struct.pack('>I', 0x1f2003d5)) # Change check to always false
|
||||||
|
|
||||||
|
# Jump back to debugger, after TTBR0 is no longer accessible
|
||||||
|
self.cd.memwrite_region(0x020308a4, struct.pack('>I', 0xd75d0014)) # Change check to always false
|
||||||
|
|
||||||
# Jump into BL31 and execute it
|
# Jump into BL31 and execute it
|
||||||
self.cd.restore_stack_and_jump(0x02024010)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
@ -759,13 +770,46 @@ class ExynosDevice():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
|
BL31_ra = self.cd.arch_dbg.state.LR
|
||||||
|
|
||||||
|
self.cd.arch_dbg.fetch_special_regs()
|
||||||
|
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
|
||||||
|
|
||||||
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with original debugger (??). Only with relocated debugger.
|
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with original debugger (??). Only with relocated debugger.
|
||||||
VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3
|
VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3
|
||||||
|
|
||||||
|
# Disable MMU and branch to 0x02048000
|
||||||
|
shellcode=f"""
|
||||||
|
mrs x0, sctlr_el3
|
||||||
|
bic x0, x0, #1
|
||||||
|
msr sctlr_el3, x0
|
||||||
|
ldr x0, =0x2048000
|
||||||
|
br x0
|
||||||
|
"""
|
||||||
|
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||||
|
self.cd.memwrite_region(0x02060000, shellcode)
|
||||||
|
self.cd.jump_to(0x02060000)
|
||||||
|
time.sleep(1)
|
||||||
|
self.usb_read(0x200) # GiAs
|
||||||
|
self.cd.arch_dbg.fetch_special_regs()
|
||||||
|
|
||||||
# Print status of MMU
|
# Print status of MMU
|
||||||
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
|
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
|
||||||
BL31_ra = self.cd.arch_dbg.state.LR
|
|
||||||
|
# # Change the values of MAIR_EL3 to a different value
|
||||||
|
# shellcode=f"""
|
||||||
|
# mov x0, #0x000000ff
|
||||||
|
# msr mair_el3, x0
|
||||||
|
# ldr x0, =0x2048000
|
||||||
|
# br x0
|
||||||
|
# """
|
||||||
|
# shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||||
|
# self.cd.memwrite_region(0x02060000, shellcode)
|
||||||
|
# self.cd.jump_to(0x02060000)
|
||||||
|
# time.sleep(1)
|
||||||
|
# self.usb_read(0x200) # GiAs
|
||||||
|
# self.cd.arch_dbg.fetch_special_regs()
|
||||||
|
# print(self.cd.arch_dbg.state.R_MAIR_EL3)
|
||||||
|
|
||||||
# Again restore bootflow
|
# Again restore bootflow
|
||||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
||||||
|
BIN
source/ghidra-transfer/8890_bootrom_bl31_bl2.bin.gzf
Normal file
BIN
source/ghidra-transfer/8890_bootrom_bl31_bl2.bin.gzf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user