KTRR/CTRR hardware-enforces the kernel code (.text) as read-only and non-modifiable. Kernel instructions cannot be patched directly – forcing exploits to use data-only attacks.


KTRR (A10 – iPhone 7+)

Kernel Text Readonly Region:

  • Hardware register lock (set by iBoot before booting the kernel)
  • Defines the memory range containing the kernel __TEXT segment
  • Any write attempt to this range triggers a hardware fault
  • Cannot be unlocked once set (fuse-based)
KTRR registers:
  KTRR_LOWER_EL1  → start of protected range
  KTRR_UPPER_EL1  → end of protected range
  KTRR_LOCK_EL1   → lock bit (write-once)

Protected:
  - Kernel __TEXT segment (code)
  - Kernel __TEXT_EXEC segment
  - CoreTrust code (iOS 12+)
  
NOT protected:
  - Kernel __DATA segment (writable data)
  - Kernel __DATA_CONST (writable at load time, locked later)
  - Zone allocator memory
  - IOKit objects

Impact: Cannot patch kernel functions – instead you must:

  • Modify function pointers in __DATA
  • Modify kernel variables that control behavior
  • Modify object data (data-only attacks)

CTRR (A15+ – iPhone 13+)

Configurable Text Readonly Region:

  • Enhanced version of KTRR
  • More configurable (per-page granularity instead of a single range)
  • pmap_lockdown_kc() adds a lockdown attribute to each page
  • Pages with the lockdown attribute cannot be mapped into user process page tables
CTRR enhancements:
  - Per-page lockdown (vs KTRR's single range)
  - Prevents mapping protected pages into any process (not just writing)
  - Stronger isolation: even with physrw, cannot map these pages to a user VA

Data-Only Attacks (Post-KTRR Strategy)

Instead of patching code:       Modify data instead:
  NOP out a check instruction    → Set the variable that the check reads to the bypass value
  Patch a function to return 0   → Modify the function pointer to point to existing code
  Insert shellcode               → Chain existing gadgets (ROP/JOP)
  Modify a branch target         → Overwrite a vtable entry

Example:

// Kernel code (in __TEXT, KTRR-protected):
if (amfi_get_out_of_my_way) {   // Variable in __DATA!
    return KERN_SUCCESS;         // Skip code signing check
}

// Exploit: kwrite to set amfi_get_out_of_my_way = 1
// → Code signing check bypassed without modifying code

Resources