112
KTRW The journey to build a debuggable iPhone Brandon Azad OBTS v3.0

The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

KTRWThe journey to builda debuggable iPhone

Brandon Azad

OBTS v3.0

Page 2: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

https://video-images.vice.com/_uncategorized/1551893361664-IMG_6918.jpeg?resize=1575:*

Page 3: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

https://pbs.twimg.com/media/D1bB7-pWsAAsTe-.jpg:large

Page 4: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

https://pbs.twimg.com/media/DyP1Q_qX0AA838S?format=png&name=large

Page 5: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

I do not use dev-fused devices

Page 6: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

I do not use dev-fused devices

But they sure would makemy security research easier...

Page 7: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Goal: Build my own "home-brewed dev phone"

- Patch kernel memory (__TEXT_EXEC)

- Breakpoints, watchpoints

- Use with LLDB / IDA Pro

- Can update iOS version

- Only parts you can get at an Apple store

Page 8: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 9: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

KTRR

Page 10: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Goal: Build my own "home-brewed dev phone"

- Patch kernel memory (__TEXT_EXEC)

- Breakpoints, watchpoints

- Use with LLDB / IDA Pro

- Can update iOS version

- Only parts you can get at an Apple store

Page 11: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-- r-x r-- r-x rw-

kernelcache

Page 12: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

rw-

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-- r-x r-- r-x

kernelcache

Read/write data

Page 13: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

r-x r-x

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-- r-- rw-

kernelcache

Executable code

Page 14: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

r-- r--

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-x r-x rw-

kernelcache

Page tables __pinstVtablesStrings

Page 15: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-- r-x r-- r-x rw-

Protected by KTRR

Page 16: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

KTRR (Kernel Text Readonly Region)

Strong form of W^X (write-xor-execute) protection

Apple A10 and later

All writes to memory in the KTRR region fail

All instruction fetches from outside the KTRR region fail

Page 17: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

DRAM

AMCC

Memory controller

CPU cores

MMUsL2

cac

he

Page 18: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

CPU cores

MMUsL2

cac

he

kernel

DRAM

Page 19: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

CPU cores

MMUsL2

cac

he

KTRR region

DRAM

Page 20: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

CPU cores

L2 c

ache

MMUs

DRAM

Page 21: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

MMUs

CPU core

DRAM

Page 22: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

MMUs

CPU core

DRAM

Page 23: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

Page 24: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x839a6c000

Page 25: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x839a6c000

Page 26: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x839a6c000

OK

Page 27: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

Page 28: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x803280000

Page 29: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x803280000

Page 30: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x803280000

Page 31: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

WRITE0x803280000

Page 32: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

Page 33: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

EXEC0x839a6c000

Page 34: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

EXEC0x839a6c000

Page 35: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

EXEC0x839a6c000

Page 36: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

L2 c

ache

DRAM

MMUs

CPU core

EXEC0x839a6c000

Page 37: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

AMCC

Memory controller

CPU cores

MMUsL2

cac

he

DRAM

Page 38: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

he

AMCC

Memory controller

DRAM

Page 39: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

he

AMCC

Memory controller

DRAM

Page 40: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

he

AMCC

Memory controller

DRAM

Page 41: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 42: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

he

DRAM

AMCC

Page 43: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 44: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

MMU registers lose state during core sleep

Page 45: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

Page 46: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

MMU KTRRbounds

Page 47: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

MMU KTRRregisters

Page 48: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Breaking KTRR

Page 49: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

iOS 10.1.1: The Yalu KTRR bypass

Luca Todesco found that Apple accidentally left an MSR TTBR1_EL1 instruction executable

Use that instruction to set a new page table base

KTRR is still initialized (so no new kernel code), but readonly pages could now be made read/write

Page 50: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- r-- r-x r-- r-x rw-

Protected by KTRR

Page 51: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Protected by KTRR

low addresses high addresses

iPhone10,1 16G77 kernelcache

rw- rw- r-x rw- r-x rw-

Page 52: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

iOS 11.1.2: Build your own iOS kernel debugger

Ian Beer found that self-hosted debugging could be enabled using ROP

Built an iOS kernel debugger with breakpoints for iOS 11.1.2 that works with LLDB

KTRR is still fully enabled, but existing instructions can be executed in arbitrary order

Page 53: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Attempts to bypass KTRR

iBoot bug: no

TLB "corruption": no

L2 cache "corruption": no

Page 54: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 55: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 56: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 57: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 58: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 59: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 60: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 61: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

MMIO register

Page 62: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CoreSight?

Page 63: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

dbgwrap_status_t

ml_dbgwrap_halt_cpu_with_state(int cpu_index,

uint64_t timeout_ns, dbgwrap_thread_state_t *state) {

cpu_data_t *cdp = cpu_datap(cpu_index);

...

/* Ensure memory-mapped coresight registers can be written */

*((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]

+ ARM_DEBUG_OFFSET_DBGLAR)) = ARM_DBG_LOCK_ACCESS_KEY;

...

for (unsigned int i = 0; i < ...; ++i) {

instr = (0xD51U << 20) | ... | i; // msr DBGDTR0, x<i>

ml_dbgwrap_stuff_instr(cdp, instr, ...);

state->x[i] = ml_dbgwrap_read_dtr(cdp, ...);

}

...

return status;

Page 64: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

dbgwrap_status_t

ml_dbgwrap_halt_cpu_with_state(int cpu_index,

uint64_t timeout_ns, dbgwrap_thread_state_t *state) {

cpu_data_t *cdp = cpu_datap(cpu_index);

...

/* Ensure memory-mapped coresight registers can be written */

*((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]

+ ARM_DEBUG_OFFSET_DBGLAR)) = ARM_DBG_LOCK_ACCESS_KEY;

...

for (unsigned int i = 0; i < ...; ++i) {

instr = (0xD51U << 20) | ... | i; // msr DBGDTR0, x<i>

ml_dbgwrap_stuff_instr(cdp, instr, ...);

state->x[i] = ml_dbgwrap_read_dtr(cdp, ...);

}

...

return status;

Page 65: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

dbgwrap_status_t

ml_dbgwrap_halt_cpu_with_state(int cpu_index,

uint64_t timeout_ns, dbgwrap_thread_state_t *state) {

cpu_data_t *cdp = cpu_datap(cpu_index);

...

/* Ensure memory-mapped coresight registers can be written */

*((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]

+ ARM_DEBUG_OFFSET_DBGLAR)) = ARM_DBG_LOCK_ACCESS_KEY;

...

for (unsigned int i = 0; i < ...; ++i) {

instr = (0xD51U << 20) | ... | i; // msr DBGDTR0, x<i>

ml_dbgwrap_stuff_instr(cdp, instr, ...);

state->x[i] = ml_dbgwrap_read_dtr(cdp, ...);

}

...

return status;

Page 66: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

dbgwrap_status_t

ml_dbgwrap_halt_cpu_with_state(int cpu_index,

uint64_t timeout_ns, dbgwrap_thread_state_t *state) {

cpu_data_t *cdp = cpu_datap(cpu_index);

...

/* Ensure memory-mapped coresight registers can be written */

*((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]

+ ARM_DEBUG_OFFSET_DBGLAR)) = ARM_DBG_LOCK_ACCESS_KEY;

...

for (unsigned int i = 0; i < ...; ++i) {

instr = (0xD51U << 20) | ... | i; // msr DBGDTR0, x<i>

ml_dbgwrap_stuff_instr(cdp, instr, ...);

state->x[i] = ml_dbgwrap_read_dtr(cdp, ...);

}

...

return status;

ml_dbgwrap_stuff_instr()is executing

dynamically-generated instructions!

Page 67: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 68: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 69: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Kernel mode

Page 70: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Reset vector!

Page 71: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

We've halted execution in the reset vector, before the MMU has been turned on!

Page 72: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

We've halted execution in the reset vector, before the MMU has been turned on!

How do we use this?

Page 73: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

We've halted execution in the reset vector, before the MMU has been turned on!

How do we use this?

What exactly is this CoreSight thing

anyway?

Page 74: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 75: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 76: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CoreSight External Debug Interface

On-chip debug architecture

Per-CPU debug registers accessible via MMIO

Extensively documented in the ARMv8 manual

Can set breakpoints/watchpoints, execute instructions, etc

The memory-mapped version of the debug registers used by Ian Beer in "Build your own iOS kernel debugger"

Page 77: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Use External Debugto single-stepLowResetVectorBaseand skip KTRR lockdown

Page 78: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

Page 79: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Challenges

We can halt a CPU core, and we can execute instructions on it to modify state, but how do we resume execution after making our modifications?

We are using one CPU core to hijack another as it executes the reset vector, so how do we handle subsequent core resets?

Page 80: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 81: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

Take this branch

Page 82: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

Take this branch

Page 83: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

FFFFFFF0070E4000 LowResetVectorBaseFFFFFFF0070E4000 MSR #0, c1, c0, #4FFFFFFF0070E4004 MSR #6, #0xF...FFFFFFF0070E4080 ADRL X17, _rorgn_beginFFFFFFF0070E4088 LDR X17, [X17]FFFFFFF0070E408C CBZ X17, Lskip_ktrrFFFFFFF0070E4090 ADRL X19, _rorgn_endFFFFFFF0070E4098 LDR X19, [X19]FFFFFFF0070E409C CBZ X19, Lskip_ktrrFFFFFFF0070E40A0 MSR ARM64_REG_KTRR_LOWER_EL1, X17FFFFFFF0070E40A4 SUB X19, X19, #4,LSL#12FFFFFFF0070E40A8 MSR ARM64_REG_KTRR_UPPER_EL1, X19FFFFFFF0070E40AC MOV X17, #1FFFFFFF0070E40B0 MSR ARM64_REG_KTRR_LOCK_EL1, X17FFFFFFF0070E40B4FFFFFFF0070E40B4 Lskip_ktrr ; CODE XREF: LowResetVectorBase+8C↑j

Take this branch

Page 84: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 85: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 86: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAMKernel shellcodemode activated!

Page 87: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Building KTRW

Page 88: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Steps to building a kernel debugger

- Remapping the kernel

- Loading a kernel extension

- Interrupt handling

- Communication channel

- GDB stub

Page 89: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 90: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAM

Page 91: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

CPU cores

MMUsL2

cac

heAMCC

DRAMRoRgn pages

are still readonly

Page 92: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Remapping the kernel

We need to modify page table permissions to make the kext's memory executable

Root page tables are in the KTRR region (still readonly)

Solution: Remap the kernel onto fresh, writable pages and set TTBR1_EL1 to point to the new page tables

Page 93: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

L2 c

ache

MMUs

CPU core

DRAM

AMCC

TTBR1_EL1

Page 94: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

L2 c

ache

MMUs

CPU core

AMCC

TTBR1_EL1 DRAM

Page 95: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

L2 c

ache

MMUs

CPU core

AMCC

TTBR1_EL1 DRAM

Page 96: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Loading kernel extensions

Allocate kernel memory for the kext

Copy in the kext binary

Dynamically link against kernel symbols

Modify page tables to make it executable

Call the kext_start() function

Page 97: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

KTRW: High-level design

One (monitor) core reserved for KTRW

Other (debugged) cores run XNU normally

Breakpoints/watchpoints cause the debugged core to halt and enter Debug state

Monitor core polls for entry to Debug state and notifies LLDB over some communication channel

Page 98: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Need some channel for LLDB to communicate with the KTRW kext

Page 99: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Communication channels

Serial USB WiFi

Page 100: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Communication channels

Serial USB WiFi

Easy Fast An option

Page 101: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Communication channels

Serial USB WiFi

Easy Fast An option

Requires special hardware

Write a custom USB stack

Write a custom WiFi driver

Page 102: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

Communication channels

Serial USB WiFi

Easy Fast An option

Requires special hardware

Write a custom USB stack

Write a custom WiFi driver

Page 103: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 104: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 105: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 106: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 107: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 108: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 109: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro
Page 110: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

oob_timestamp

Page 111: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

DEMO

Page 112: The journey to build a debuggable iPhone KTRW · Goal: Build my own "home-brewed dev phone" - Patch kernel memory (__TEXT_EXEC) - Breakpoints, watchpoints - Use with LLDB / IDA Pro

https://github.com/googleprojectzero/ktrw

https://googleprojectzero.blogspot.com/2019/10/ktrw-journey-to-build-debuggable-iphone.html