iOS Exploiting

Reading time: 54 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

iOS Exploit Mitigations

1. Code Signing / Runtime Signature Verification

Introduced early (iPhone OS → iOS) Hii ni moja ya ulinzi kuu: msimbo wote unaotekelezwa (apps, dynamic libraries, JIT-ed code, extensions, frameworks, caches) lazima usainishwe kwa cryptographic na mnyororo wa vyeti ulioanzia kwenye trust ya Apple. Wakati wa runtime, kabla ya kupakia binary kwenye memory (au kabla ya kufanya jumps kwenye mipaka fulani), mfumo unakagua saini yake. Ikiwa msimbo umebadilika (bit-flipped, patched) au haujasainiwa, load inashindwa.

  • Inazuia: hatua ya “classic payload drop + execute” katika exploit chains; arbitrary code injection; kubadilisha binary iliyopo kuingiza mantiki hatarishi.
  • Maelezo ya Mechanism:
  • Mach-O loader (na dynamic linker) inakagua code pages, segments, entitlements, team IDs, na kwamba saini inafunika yaliyomo kwenye file.
  • Kwa regions za memory kama JIT caches au dynamically generated code, Apple inasisitiza kwamba pages zisainishwe au zithibitishwe kupitia API maalum (mfano mprotect with code-sign checks).
  • Saini inajumuisha entitlements na identifiers; OS inasimamia kwamba APIs fulani au uwezo wenye privilage yanahitaji entitlements maalum ambazo hazinaweza kuigizwa.
Mfano Tuseme exploit inapata code execution katika process na inajaribu kuandika shellcode kwenye heap na kuruka kuelekea kwake. Kwa iOS, page hiyo ingehitaji kuonekana executable **na** kutimiza vigezo vya code-signature. Kwa kuwa shellcode haijasainiwa na vyeti vya Apple, jump inashindwa au mfumo unatakata kufanya memory region hiyo executable.

2. CoreTrust

Introduced around iOS 14+ era (or gradually in newer devices / later iOS) CoreTrust ni subsystem inayofanya runtime signature validation ya binaries (pamoja na system na user binaries) dhidi ya Apple’s root certificate badala ya kutegemea cached userland trust stores.

  • Inazuia: tampering ya post-install ya binaries, jailbreak techniques zinazo jaribu kubadilisha au kupatch system libraries au user apps; kudanganya mfumo kwa kubadilisha binaries zilizoaminika na toleo hatarishi.
  • Maelezo ya Mechanism:
  • Badala ya kuamini database ya local trust au certificate cache, CoreTrust hupata au kurejea kwa root ya Apple moja kwa moja au kuthibitisha vyeti vya kati katika chain salama.
  • Inahakikisha kwamba marekebisho (mfano kwenye filesystem) ya binaries zilizopo yanatambuliwa na yakatulewe.
  • Inayefunga entitlements, team IDs, code signing flags, na metadata nyingine kwenye binary wakati wa load.
Mfano Jailbreak inaweza kujaribu kubadilisha `SpringBoard` au `libsystem` na version iliyopatchiwa ili kupata persistence. Lakini wakati loader ya OS au CoreTrust inakagua, inagundua mismatch ya saini (au entitlements zilizobadilika) na inakataa kutekeleza.

3. Data Execution Prevention (DEP / NX / W^X)

Introduced in many OSes earlier; iOS had NX-bit / w^x for a long time DEP inalazimisha kwamba pages zilizotajwa writable (kwa data) zisiwe executable, na pages zilizotajwa executable zisiwe writable. Huwezi tu kuandika shellcode kwenye heap au stack region na kuitekeleza.

  • Inazuia: direct shellcode execution; classic buffer-overflow → jump to injected shellcode.
  • Maelezo ya Mechanism:
  • MMU / memory protection flags (kwa page tables) hufanya tofauti hiyo.
  • Jaribio lolote la kufanya writable page kuwa executable linachochea system check (na linaorodheshwa kama la marufuku au linahitaji code-sign approval).
  • Katika matukio mengi, kufanya pages executable kunahitaji kutumia OS APIs zinazotekeleza constraints au checks za ziada.
Mfano Overflow inaandika shellcode kwenye heap. Mshambuliaji anajaribu `mprotect(heap_addr, size, PROT_EXEC)` ili kuifanya executable. Lakini mfumo unakataa au unathibitisha kwamba page mpya lazima ipite vigezo vya code-sign (ambavyo shellcode haiwezi).

4. Address Space Layout Randomization (ASLR)

Introduced in iOS ~4–5 era (roughly iOS 4–5 timeframe) ASLR inarandomiza base addresses za maeneo muhimu ya memory: libraries, heap, stack, n.k., kila kuanzishwa kwa process. Anwani za gadgets zinabadilika kati ya runs.

  • Inazuia: hardcoding gadget addresses kwa ROP/JOP; static exploit chains; kuruka blind kwa offsets zilizo maarufu.
  • Maelezo ya Mechanism:
  • Kila library / dynamic module iliyopakuliwa inarebased kwenye offset iliyorandomizwa.
  • Stack na heap base pointers zinarangishwa (ndani ya mipaka ya entropy).
  • Wakati mwingine maeneo mengine (mfano mmap allocations) pia yamerandomizwa.
  • Imeunganishwa na information-leak mitigations, inamfanya mshambuliaji kwanza ku-leak an address au pointer ili kugundua base addresses wakati wa runtime.
Mfano ROP chain inategemea gadget katika `0x….lib + offset`. Lakini kwa kuwa `lib` imewekwa upya kwa njia tofauti kila run, chain iliyowekwa kimageni inashindwa. Exploit lazima kwanza i-leak base address ya module kabla ya kuhesabu gadget addresses.

5. Kernel Address Space Layout Randomization (KASLR)

Introduced in iOS ~ (iOS 5 / iOS 6 timeframe) Sawa na ASLR ya user, KASLR inarandomiza base ya kernel text na miundo mingine ya kernel wakati wa boot.

  • Inazuia: kernel-level exploits zinazotegemea mahali maalum pa kernel code au data; static kernel exploits.
  • Maelezo ya Mechanism:
  • Kila boot, base address ya kernel inarandomizwa (ndani ya range).
  • Miundo ya data ya kernel (kama task_structs, vm_map, n.k.) pia inaweza kubadilishwa au kupelekwa mahali tofauti.
  • Washambuliaji lazima kwanza wa-leak kernel pointers au kutumia information disclosure vulnerabilities ili kuhesabu offsets kabla ya kuiba kernel structures au code.
Mfano Vulnerability ya local inalenga kuharibu kernel function pointer (mfano kwenye `vtable`) kwenye `KERN_BASE + offset`. Lakini kwa kuwa `KERN_BASE` haijulikani, mshambuliaji lazima a-leak kwanza (mfano kwa primitive ya read) kabla ya kuhesabu address sahihi ya kuharibu.

6. Kernel Patch Protection (KPP / AMCC)

Introduced in newer iOS / A-series hardware (post around iOS 15–16 era or newer chips) KPP (aka AMCC) inafuatilia kwa kila mara integrity ya kernel text pages (kwa hash au checksum). Ikiwa inagundua tampering (patches, inline hooks, code modifications) nje ya windows zilizoruhusiwa, inasababisha kernel panic au reboot.

  • Inazuia: persistent kernel patching (kubadilisha kernel instructions), inline hooks, static function overwrites.
  • Maelezo ya Mechanism:
  • Moduli ya hardware au firmware inafuatilia eneo la kernel text.
  • Mara kwa mara au kwa ombi inare-hash pages na kulinganisha na thamani inayotarajiwa.
  • Ikiwa kuna mismatch nje ya windows za update zisizo hatari, inafanya panic kwa kifaa (kuepuka patch hatarishi kudumu).
  • Washambuliaji lazima wawe wanajiepusha detection windows au kutumia legitimate patch paths.
Mfano Exploit inajaribu kupatch prologue ya kernel function (mfano `memcmp`) ili kunasa simu. Lakini KPP inagundua kuwa code page haifai na inachochea kernel panic, ikikarabati kifaa kabla ya patch kuweza kuwa imara.

7. Kernel Text Read‐Only Region (KTRR)

Introduced in modern SoCs (post ~A12 / newer hardware) KTRR ni mekanisma inayotekelezwa na hardware: mara kernel text inafungwa mapema wakati wa boot, inakuwa read-only kutoka EL1 (kernel), ikizuia maandishi zaidi kwenye code pages.

  • Inazuia: mabadiliko yoyote ya kernel code baada ya boot (mfano patching, in-place code injection) kwa kiwango cha privilage EL1.
  • Maelezo ya Mechanism:
  • Wakati wa boot (katika hatua ya secure/bootloader), memory controller (au unit ya hardware salama) inaweka physical pages zinazo tengeneza kernel text kama read-only.
  • Hata kama exploit inapata privileges za kernel kamili, haiwezi kuandika kwenye pages hizo ili kupatch instructions.
  • Ili kuzibadilisha, mshambuliaji lazima awashinde boot chain, au aelekeze KTRR yenyewe.
Mfano Privilege-escalation exploit inaruka hadi EL1 na kuandika trampoline ndani ya kernel function (mfano kwenye `syscall` handler). Lakini kwa sababu pages zimefungwa kuwa read-only na KTRR, uandishi unashindwa (au unachochea fault), hivyo patch haitekelezwi.

8. Pointer Authentication Codes (PAC)

Introduced with ARMv8.3 (hardware), Apple beginning with A12 / iOS ~12+

  • PAC ni kipengele cha hardware kilicholetwa katika ARMv8.3-A kugundua uharibifu wa pointer values (return addresses, function pointers, certain data pointers) kwa kuingiza saini ndogo ya cryptographic (“MAC”) ndani ya bits za juu zisizotumika za pointer.
  • Saini (“PAC”) inahesabiwa juu ya pointer value pamoja na modifier (thamani ya context, mfano stack pointer au data ya kutofautisha). Kwa njia hiyo pointer yenye thamani ile ile katika contexts tofauti inapata PAC tofauti.
  • Wakati wa matumizi, kabla ya dereferencing au branching kupitia pointer hiyo, instruction ya authenticate inakagua PAC. Ikiwa sahihi, PAC inatondolewa na pointer safi inapatikana; ikiwa si sahihi, pointer inakuwa “poisoned” (au fault inaibuliwa).
  • Keys zinazotumika kutengeneza/kuhakiki PAC zinahifadhiwa katika privileged registers (EL1, kernel) na hazipatikani kwa user mode.
  • Kwa sababu si bits zote 64 za pointer zinatumika kwenye mifumo mingi (mfano 48-bit address space), bits za juu ni “spare” na zinaweza kubeba PAC bila kubadilisha effective address.

Architectural Basis & Key Types

  • ARMv8.3 inaleta vifuniko vitano vya 128-bit keys (kila kimefafanuliwa kupitia system register mbili za 64-bit) kwa pointer authentication.

  • APIAKey — kwa instruction pointers (domain “I”, key A)

  • APIBKey — key ya pili ya instruction pointer (domain “I”, key B)

  • APDAKey — kwa data pointers (domain “D”, key A)

  • APDBKey — kwa data pointers (domain “D”, key B)

  • APGAKey — key “generic”, kwa kusaini data isiyo-pointer au matumizi mengine ya generic

  • Keys hizi zinahifadhiwa katika privileged system registers (zinapatikana tu kwenye EL1/EL2 n.k.), hazipatikani kutoka user mode.

  • PAC inahesabiwa kwa kutumia cryptographic function (ARM inapendekeza QARMA kama algorithm) kwa kutumia:

  1. Thamani ya pointer (sehemu canonical)
  2. modifier (thamani ya context, kama salt)
  3. key ya siri
  4. logic nyingine ya tweak ya ndani Ikiwa PAC iliyopatikana inalingana na ile iliyohifadhiwa kwenye bits za juu za pointer, authentication inafanikiwa.

Instruction Families

Conventions za majina ni: PAC / AUT / XPAC, kisha herufi za domain.

  • PACxx instructions hutasaini pointer na kuingiza PAC
  • AUTxx instructions huthibitisha + hutondoa (validate na remove PAC)
  • XPACxx instructions hutondoa bila kuthibitisha

Domains / matamko:

MnemonicMeaning / DomainKey / DomainExample Usage in Assembly
PACIASign instruction pointer with APIAKey“I, A”PACIA X0, X1 — sign pointer in X0 using APIAKey with modifier X1
PACIBSign instruction pointer with APIBKey“I, B”PACIB X2, X3
PACDASign data pointer with APDAKey“D, A”PACDA X4, X5
PACDBSign data pointer with APDBKey“D, B”PACDB X6, X7
PACG / PACGAGeneric (non-pointer) signing with APGAKey“G”PACGA X8, X9, X10 (sign X9 with modifier X10 into X8)
AUTIAAuthenticate APIA-signed instruction pointer & strip PAC“I, A”AUTIA X0, X1 — check PAC on X0 using modifier X1, then strip
AUTIBAuthenticate APIB domain“I, B”AUTIB X2, X3
AUTDAAuthenticate APDA-signed data pointer“D, A”AUTDA X4, X5
AUTDBAuthenticate APDB-signed data pointer“D, B”AUTDB X6, X7
AUTGAAuthenticate generic / blob (APGA)“G”AUTGA X8, X9, X10 (validate generic)
XPACIStrip PAC (instruction pointer, no validation)“I”XPACI X0 — remove PAC from X0 (instruction domain)
XPACDStrip PAC (data pointer, no validation)“D”XPACD X4 — remove PAC from data pointer in X4

There are specialized / alias forms:

  • PACIASP is shorthand for PACIA X30, SP (sign the link register using SP as modifier)
  • AUTIASP is AUTIA X30, SP (authenticate link register with SP)
  • Combined forms like RETAA, RETAB (authenticate-and-return) or BLRAA (authenticate & branch) exist in ARM extensions / compiler support.
  • Also zero-modifier variants: PACIZA / PACIZB where the modifier is implicitly zero, etc.

Modifiers

Lengo kuu la modifier ni kubana PAC kwenye context maalum ili anuani ile ile iliyosainiwa katika contexts tofauti ipe PAC tofauti. Hii inazuia matumizi rahisi ya pointer katika frames au objects tofauti. Ni kama kuongeza salt kwenye hash.

Kwa hivyo:

  • modifier ni thamani ya context (register nyingine) inayochanganywa katika computation ya PAC. Chaguzi za kawaida: stack pointer (SP), frame pointer, au object ID.
  • Kutumia SP kama modifier ni kawaida kwa signing ya return address: PAC inabana kwa frame maalum. Ikiwa unajaribu kutumia tena LR katika frame tofauti, modifier hubadilika, hivyo PAC validation inashindwa.
  • Pointer ile ile iliyosainiwa kwa modifiers tofauti inatoa PAC tofauti.
  • modifier haifai kuwa siri, lakini vyema isiwe control ya mshambuliaji.
  • Kwa instructions zinazofanya kusaini au kuthibitisha pointers ambapo hakuna modifier maanaful, baadhi ya fomu zinatumia zero au constant implicit.

Apple / iOS / XNU Customizations & Observations

  • Utekelezaji wa PAC wa Apple unajumuisha diversifiers za per-boot ili keys au tweaks zibadilike kila boot, kuzuia reuse kati ya boots.
  • Pia wanajumuisha cross-domain mitigations ili PACs zilizotengenezwa user mode zisizoweza kutumika kirahisi katika kernel mode, n.k.
  • Katika Apple M1 / Apple Silicon, reverse engineering ilionyesha kwamba kuna aina tisa za modifier na system registers za Apple maalum kwa udhibiti wa key.
  • Apple inatumia PAC katika subsystems nyingi za kernel: signing ya return addresses, pointer integrity katika kernel data, signed thread contexts, n.k.
  • Google Project Zero ilionyesha jinsi chini ya powerful memory read/write primitive katika kernel, mtu angeweza kuforge kernel PACs (kwa A keys) kwenye devices za A12-era, lakini Apple ilirekebisha mengi ya njia hizo.
  • Katika mfumo wa Apple, baadhi ya keys ni global across kernel, wakati processes za user zinaweza kupata randomness ya per-process key.

PAC Bypasses

  1. Kernel-mode PAC: theoretical vs real bypasses
  • Kwa sababu kernel PAC keys na logic zinadhibitiwa kwa ukali (privileged registers, diversifiers, domain isolation), kuforge arbitrary signed kernel pointers ni vigumu sana.
  • Azad's 2020 "iOS Kernel PAC, One Year Later" inaripoti kuwa katika iOS 12-13, alipata baadhi ya bypasses za sehemu (signing gadgets, reuse ya signed states, unprotected indirect branches) lakini hakuna bypass ya generic kamili. bazad.github.io
  • “Dark Magic” za Apple personalization zinaweka mdogo wa exploitable surfaces (domain switching, per-key enabling bits). i.blackhat.com
  • Kuna CVE inajulikana ya kernel PAC bypass CVE-2023-32424 kwenye Apple silicon (M1/M2) iliyoripotiwa na Zecao Cai et al. i.blackhat.com
  • Lakini bypasses hizi mara nyingi zinategemea gadgets maalum au bugs za implementation; si bypass ya ujumla.

Hivyo kernel PAC inachukuliwa kuwa imara sana, ingawa si kamili.

  1. User-mode / runtime PAC bypass techniques

Hizi ni za kawaida zaidi, na zinatumia kasoro katika jinsi PAC inavyotumika au kutekelezwa katika dynamic linking / runtime frameworks. Hapa chini ni madaraja, pamoja na mifano.

2.1 Shared Cache / A key issues

  • dyld shared cache ni blob kubwa ya system frameworks na libraries pre-linked. Kwa kuwa inashirikiwa sana, function pointers ndani ya shared cache zimeshanasainiwa na kisha kutumika na processes nyingi. Washambuliaji walilenga pointers hizi tayari-zilisainiwa kama “PAC oracles”.

  • Mbinu za bypass zina jaribu kutoa au kutumia tena A-key signed pointers zilizo ndani ya shared cache na kuzitumia katika gadgets.

  • Taarifa "No Clicks Required" inaelezea kujenga oracle juu ya shared cache ili kubaini relative addresses na kuziunganisha na signed pointers ili kuzuia PAC. saelo.github.io

  • Pia, imports za function pointers kutoka shared libraries katika userspace zilipatikana kuwa hazilindwa vya kutosha na PAC, kuruhusu mshambuliaji kupata function pointers bila kubadilisha saini. (Project Zero bug entry) bugs.chromium.org

2.2 dlsym(3) / dynamic symbol resolution

  • Bypass moja inayojulikana ni kuita dlsym() kupata function pointer ambaye tayari amesainiwa (amesainiwa kwa A-key, diversifier zero) na kisha kuitumia. Kwa sababu dlsym inarudisha pointer iliyo halali iliyosainiwa, kuitumia kunazima haja ya kuforge PAC.

  • Blog ya Epsilon inaelezea jinsi baadhi ya bypasses zinavyotumia hili: kuita dlsym("someSym") hurudisha signed pointer na inaweza kutumika kwa indirect calls. blog.epsilon-sec.com

  • Synacktiv "iOS 18.4 --- dlsym considered harmful" inaelezea bug: baadhi ya symbols zilizotambuliwa kupitia dlsym kwenye iOS 18.4 zinarudisha pointers ambazo zimekifanya sign vibaya (au na diversifiers buggy), kuwezesha PAC bypass isiyotarajiwa. Synacktiv

  • Mantiki kwenye dyld kwa dlsym ni: wakati result->isCode, wanaisaini pointer iliyorejeshwa na __builtin_ptrauth_sign_unauthenticated(..., key_asia, 0), yaani context zero. blog.epsilon-sec.com

Hivyo, dlsym ni njia ya mara kwa mara katika user-mode PAC bypasses.

2.3 Other DYLD / runtime relocations

  • DYLD loader na dynamic relocation logic ni tata na wakati mwingine inaweka pages kwa read/write kwa muda kufanya relocations, kisha inageuza kuwa read-only. Washambuliaji walitumia windows hizi. Hotuba ya Synacktiv inaelezea "Operation Triangulation", bypass inayotegemea timing ya PAC kupitia relocations dynamic. Synacktiv

  • DYLD pages sasa zinalindwa na SPRR / VM_FLAGS_TPRO (alama za ulinzi kwa dyld). Lakini matoleo ya awali yalikuwa na ulinzi dhaifu. Synacktiv

  • Katika exploit chains za WebKit, DYLD loader mara nyingi huwa lengo la PAC bypass. Slides zinataja kwamba PAC bypasses nyingi zimetumia DYLD loader (kupitia relocation, interposer hooks). Synacktiv

2.4 NSPredicate / NSExpression / ObjC / SLOP

  • Katika userland exploit chains, Objective-C runtime methods kama NSPredicate, NSExpression au NSInvocation zinatumika kupeleka control calls bila dalili za wazi za pointer forging.

  • Kwenye iOS za zamani (kabla ya PAC), exploit ilitumia fake NSInvocation objects kuita selectors yoyote kwenye memory iliyodhibitiwa. Kwa PAC, mbinu ilihitaji mabadiliko. Lakini SLOP (SeLector Oriented Programming) imeendelea hata chini ya PAC. Project Zero

  • Mbinu ya awali ya SLOP iliruhusu kuunganisha ObjC calls kwa kuunda invocations bandia; bypass inategemea kwamba ISA au selector pointers wakati mwingine hazilindwa kwa PAC kikamilifu. Project Zero

  • Katika mazingira ambapo pointer authentication inatumika kwa sehemu, methods / selectors / target pointers huenda si kila mara zikiwa na ulinzi wa PAC, hivyo kuacha nafasi ya bypass.

Mfano wa Mtiririko

Mfano Signing & Authenticating ``` ; Example: function prologue / return address protection my_func: stp x29, x30, [sp, #-0x20]! ; push frame pointer + LR mov x29, sp PACIASP ; sign LR (x30) using SP as modifier ; … body … mov sp, x29 ldp x29, x30, [sp], #0x20 ; restore AUTIASP ; authenticate & strip PAC ret

; Example: indirect function pointer stored in a struct ; suppose X1 contains a function pointer PACDA X1, X2 ; sign data pointer X1 with context X2 STR X1, [X0] ; store signed pointer

; later retrieval: LDR X1, [X0] AUTDA X1, X2 ; authenticate & strip BLR X1 ; branch to valid target

; Example: stripping for comparison (unsafe) LDR X1, [X0] XPACI X1 ; strip PAC (instruction domain) CMP X1, #some_label_address BEQ matched_label

</details>

<details>
<summary>Example</summary>
Buffer overflow inabandika anwani ya kurudi kwenye stack. Mshambuliaji anaandika anwani ya gadget ya lengo lakini hawezi kuhesabu PAC sahihi. Wakati function inarudi, CPU’s `AUTIA` instruction inatoa hitilafu kwa sababu ya mismatch ya PAC. Mnyororo unashindwa.
Project Zero’s analysis on A12 (iPhone XS) ilionyesha jinsi Apple’s PAC inavyotumika na mbinu za kutengeneza PACs endapo mshambuliaji ana primitive ya kusoma/kuandika memory.
</details>


### 9. **Branch Target Identification (BTI)**
**Introduced with ARMv8.5 (later hardware)**
BTI ni kipengele cha hardware kinachokagua **indirect branch targets**: wakati `blr` au indirect calls/jumps zinapotekelezwa, lengo lazima lianze na **BTI landing pad** (`BTI j` au `BTI c`). Kuruka ndani ya anwani za gadget ambazo hazina landing pad husababisha exception.

LLVM’s implementation inataja aina tatu za maagizo ya BTI na jinsi zinavyolingana na aina za branch.

| BTI Variant | What it permits (which branch types) | Typical placement / use case |
|-------------|----------------------------------------|-------------------------------|
| **BTI C** | Targets of *call*-style indirect branches (e.g. `BLR`, or `BR` using X16/X17) | Put at entry of functions that may be called indirectly |
| **BTI J** | Targets of *jump*-style branches (e.g. `BR` used for tail calls) | Placed at the beginning of blocks reachable by jump tables or tail-calls |
| **BTI JC** | Acts as both C and J | Can be targeted by either call or jump branches |

- Katika code iliyotengenezwa na branch target enforcement, compilers huingiza BTI instruction (C, J, au JC) kwenye kila indirect-branch target halali (mwanzo wa functions au blocks zinazofikiwa kwa jumps) ili indirect branches zifanikiwe tu kwa maeneo hayo.
- **Direct branches / calls** (yaani anwani za fixed `B`, `BL`) hazizuiliwi na BTI. Dhahania ni kwamba code pages zinatiliwa saini na mshambuliaji hawezi kuzibadilisha (hivyo direct branches ni salama).
- Pia, **RET / return** instructions kwa kawaida hazizuiliwi na BTI kwa sababu anwani za kurudi zinatulindwa kupitia PAC au mekanisimu za return signing.

#### Mechanism and enforcement

- Wakati CPU inatokana na **indirect branch (BLR / BR)** kwenye ukurasa uliotamkwa kama “guarded / BTI-enabled,” inakagua ikiwa maagizo ya mwanzo ya anwani ya lengo ni BTI halali (C, J, au JC kama inaruhusiwa). Kama siyo, hutokea **Branch Target Exception**.
- BTI instruction encoding imetengenezwa kutumia opcodes zilizohifadhiwa awali kwa NOPs (katika ARM zamani). Hivyo binaries zilizo BTI-enabled zinabaki backward-compatible: kwenye hardware isiyo na BTI maagizo hayo hufanya kazi kama NOPs.
- Compiler passes zinazoongeza BTIs huziingiza tu pale zinapohitajika: functions ambazo zinaweza kuitwa kwa njia isiyo ya moja kwa moja, au basic blocks zinazolengwa na jumps.
- Baadhi ya patches na code za LLVM zinaonyesha kuwa BTI haingiziwi kwa *kila* basic block — ni kwa blocks ambazo zinaweza kuwa branch targets (kwa mfano kutoka switch / jump tables).

#### BTI + PAC synergy

PAC inalinda thamani ya pointer (chanzo) — kuhakikisha mnyororo wa indirect calls / returns haujadalilishwa.

BTI inahakikisha kwamba hata pointer halali lazima inalenga tu entry points zilizo na alama sahihi.

Pamoja, mshambuliaji anahitaji pointer halali yenye PAC sahihi na pia lengo lazima liwe na BTI imewekwa hapo. Hii inafanya ugumu wa kujenga gadgets za exploit kuongezeka.

#### Example


<details>
<summary>Example</summary>
Exploit inajaribu kutembeza hadi gadget kwenye `0xABCDEF` ambayo haianzi na `BTI c`. CPU, inapotekeleza `blr x0`, inakagua lengo na inatoa fault kwa sababu mpangilio wa maagizo haujumuishi landing pad halali. Hivyo gadgets nyingi hazitumiiki isipokuwa zikiwa na prefix ya BTI.
</details>


### 10. **Privileged Access Never (PAN) & Privileged Execute Never (PXN)**
**Introduced in more recent ARMv8 extensions / iOS support (for hardened kernel)**

#### PAN (Privileged Access Never)

- **PAN** ni kipengele kilichoanzishwa katika **ARMv8.1-A** kinachosuzu code iliyoko privilege (EL1 au EL2) kusoma au kuandika memory iliyotamkwa kama **user-accessible (EL0)**, isipokuwa PAN imezimwa waziwazi.
- Wazo ni: hata kama kernel imedanganywa au imevamiwa, haiwezi dereference pointers za user-space bila kwanza *kuzima* PAN, hivyo kupunguza hatari za exploits za aina ya **`ret2usr`** au matumizi mabaya ya buffers zinazodhibitiwa na user.
- Wakati PAN imewezeshwa (PSTATE.PAN = 1), yoyote privileged load/store inayofikia address ambayo inasema “accessible at EL0” itasababisha **permission fault**.
- Kernel, inapohitajika kwa kweli kufikia memory ya user-space (kwa mfano ku-copy data kwenda/kutoka user buffers), lazima **wakati mfupi wazime PAN** (au watumie maagizo ya “unprivileged load/store”) ili kuruhusu ufikiaji huo.
- Katika Linux on ARM64, support ya PAN ilianzishwa karibu 2015: patches za kernel ziliongeza ugunduzi wa kipengele, na kubadilisha `get_user` / `put_user` n.k. kwa variantes zinazoruhusu kuzima PAN wakati wa ufikiaji wa memory ya user.

**Key nuance / limitation / bug**
- Kama ilivyotajwa na Siguza na wengine, hitilafu ya specification (au tabia isiyokuwa wazi) katika muundo wa ARM inamaanisha kuwa **execute-only user mappings** (`--x`) huenda **zisizofanya kazi na PAN**. Kwa maneno mengine, ukuta wa ukurasa wa user ikiwa ni executable bila ruhusa ya read, jaribio la kernel la kusoma linaweza kupita PAN kwa sababu architecture inaona “accessible at EL0” inahitaji ruhusa ya kusoma, sio tu execute. Hii inasababisha PAN bypass katika mipangilio fulani.
- Kwa hiyo, kama iOS / XNU inaruhusu pages za user kuwa execute-only (kama baadhi ya JIT au code-cache setup zinavyoweza kufanya), kernel huenda ikasoma kutoka kwao hata PAN ikiwa imewezeshwa. Hii ni eneo nyembamba linaloweza kutumika katika baadhi ya ARMv8+ systems.

#### PXN (Privileged eXecute Never)

- **PXN** ni bit kwenye page table (katika entries za page table, leaf au block entries) inayosema kuwa ukurasa hauwezi kutekelezwa ukiwa katika mode ya privileged (yaani wakati EL1 inatekeleza).
- PXN inazuia kernel (au code yoyote yenye privilege) kuruka au kutekeleza maagizo kutoka kwenye user-space pages hata kama control imepinda. Kwa njia hii, inazuia redirection ya control-flow ya kiwango cha kernel kwenda kwenye memory ya user.
- Pamoja na PAN, hili linahakikisha:
1. Kernel haiwezi (kwa default) kusoma au kuandika data ya user-space (PAN)
2. Kernel haiwezi kutekeleza code ya user-space (PXN)
- Katika ARMv8 page table format, entries za leaf zina bit `PXN` (na pia `UXN` kwa unprivileged execute-never) katika attribute bits zao.

Hivyo hata kama kernel ina function pointer iliyoharibika inayolenga memory ya user, na ikijaribu kuruka huko, bit ya PXN itasababisha fault.

#### Memory-permission model & how PAN and PXN map to page table bits

Ili kuelewa jinsi PAN / PXN zinavyofanya kazi, unahitaji kuona jinsi ARM inavyofanya translation na model ya ruhusa (imefupishwa):

- Kila page au block entry ina fields za attribute zikiwemo **AP[2:1]** kwa access permissions (read/write, privileged vs unprivileged) na bits za **UXN / PXN** kwa vizuizi vya execute-never.
- Wakati PSTATE.PAN ni 1 (imewezeshwa), hardware inatekeleza semantics iliyorekebishwa: privileged accesses kwa pages zilizotamkwa kama “accessible by EL0” (yaani user-accessible) zinaruhusiwa tu kwa mipaka na zinakatazwa (fault).
- Kwa sababu ya bug iliyotajwa, pages zilizowekwa kuwa executable tu (bila ruhusa ya read) huenda hazihesabiwi kama “accessible by EL0” katika utekelezaji fulani, hivyo bypass ya PAN inawezekana.
- Wakati bit ya PXN ya ukurasa imewekwa, hata kama instruction fetch inatoka kwa level ya juu ya privilege, utekelezaji unakatazwa.

#### Kernel usage of PAN / PXN in a hardened OS (e.g. iOS / XNU)

Katika muundo wa kernel uliosafishwa (kama yale Apple inaweza kutumia):

- Kernel inawawezesha PAN kwa default (hivyo code yenye privilege inazingatiwa).
- Katika njia ambazo zinahitaji kwa kweli kusoma au kuandika buffers za user (kwa mfano syscall buffer copy, I/O, read/write user pointer), kernel kwa muda **huzimwa PAN** au hutumia maagizo maalumu ili kupitisha.
- Baada ya kumaliza ufikiaji wa data za user, inapaswa kuwarudisha PAN kuwa enabled.
- PXN inatekelezwa kupitia page tables: user pages zina PXN = 1 (hivyo kernel haiwezi kuziendesha), kernel pages hazina PXN (hivyo kernel code inaweza kutekelezeka).
- Kernel inapaswa kuhakikisha hakuna njia za code zinazosababisha mtiririko wa utekelezaji kuingia katika maeneo ya memory ya user (ambazo zingeinua PXN) — hivyo mnyororo za exploit zinazotegemea “kuruka ndani ya shellcode ya user” zinazuuzwa.

Kwa sababu ya PAN bypass kupitia execute-only pages, katika mfumo halisi, Apple inaweza kuzima au kupiga marufuku execute-only user pages, au kuzuia tatizo la specification.

#### Attack surfaces, bypasses, and mitigations

- **PAN bypass via execute-only pages**: kama ilivyoelezwa, spec ina nafasi wazi: user pages zenye execute-only (bila read perm) huenda hazihesabiwi kama “accessible at EL0,” hivyo PAN haitazuia kernel reads kutoka kwa pages hizo katika utekelezaji fulani. Hii hutoa njia isiyo ya kawaida kwa mshambuliaji kusambaza data kupitia sehemu za “execute-only”.
- **Temporal window exploit**: ikiwa kernel inazima PAN kwa dirisha lenye urefu usiohitajika, race au njia ya uharibifu inaweza kutumia dirisha hilo kufanya ufikiaji wa memory za user usiotarajiwa.
- **Forgotten re-enable**: ikiwa njia za code hazirudishi PAN, operesheni za kernel zinazofuata zinaweza kwa makosa kufikia memory za user.
- **Misconfiguration of PXN**: ikiwa page tables hazoweki PXN kwenye user pages au zikaleta mapping mbaya ya user code pages, kernel inaweza kudanganywa kutekeleza code ya user-space.
- **Speculation / side-channels**: kama kwa speculative bypasses, kunaweza kuwa na athari za microarchitectural zinazosababisha ukiukaji wa muda mfupi wa ukaguzi wa PAN / PXN (ingawa mashambulizi kama hayo yanategemea sana muundo wa CPU).
- **Complex interactions**: Katika vipengele vya juu (kama JIT, shared memory, maeneo ya code ya just-in-time), kernel inaweza kuhitaji udhibiti wa undani kuruhusu ufikiaji fulani wa memory au utekelezaji kwenye regions za user-mapped; kubuni hilo salama chini ya vizuizi vya PAN/PXN sio rahisi.

#### Example

<details>
<summary>Code Example</summary>
Hapa kuna mifano ya pseudo-assembly inayoonyesha kuanzisha/kuzima PAN karibu na ufikiaji wa memory ya user, na jinsi fault inaweza kutokea.
</details>
<div class="codeblock_filename_container"><span class="codeblock_filename_inner hljs">  </span></div>

// Suppose kernel entry point, PAN is enabled (privileged code cannot access user memory by default)

; Kernel receives a syscall with user pointer in X0 ; wants to read an integer from user space mov X1, X0 ; X1 = user pointer

; disable PAN to allow privileged access to user memory MSR PSTATE.PAN, #0 ; clear PAN bit, disabling the restriction

ldr W2, [X1] ; now allowed load from user address

; re-enable PAN before doing other kernel logic MSR PSTATE.PAN, #1 ; set PAN

; ... further kernel work ...

; Later, suppose an exploit corrupts a pointer to a user-space code page and jumps there BR X3 ; branch to X3 (which points into user memory)

; Because the target page is marked PXN = 1 for privileged execution, ; the CPU throws an exception (fault) and rejects execution

If the kernel had **not** set PXN on that user page, then the branch might succeed — which would be insecure.

If the kernel forgets to re-enable PAN after user memory access, it opens a window where further kernel logic might accidentally read/write arbitrary user memory.

If the user pointer is into an execute-only page (user page with only execute permission, no read/write), under the PAN spec bug, `ldr W2, [X1]` might **not** fault even with PAN enabled, enabling a bypass exploit, depending on implementation.

</details>

<details>
<summary>Mfano</summary>
Udhaifu wa kernel unajaribu kuchukua function pointer iliyotolewa na mtumiaji na kuitaja katika muktadha wa kernel (yaani `call user_buffer`). Chini ya PAN/PXN, operesheni hiyo hairuhusiwi au inafanya fault.
</details>

---

### 11. **Top Byte Ignore (TBI) / Pointer Tagging**
**Iliyoletwa katika ARMv8.5 / mpya zaidi (au nyongeza ya hiari)**
TBI ina maana ya kwamba top byte (byte yenye umuhimu mkubwa zaidi) ya pointer ya 64-bit inazingatiwa kuwa haipo wakati wa tafsiri ya anwani. Hii inaruhusu OS au hardware kuweka bit za **tag** kwenye top byte ya pointer bila kuathiri anwani halisi.

- TBI inasimama kwa **Top Byte Ignore** (mara nyingine huitwa *Address Tagging*). Ni kipengele cha hardware (kinachopatikana katika utekelezaji nyingi za ARMv8+) kinachofukuza **bita 8 za juu** (bits 63:56) za pointer ya 64-bit wakati wa kufanya **address translation / load/store / instruction fetch**.
- Kwa vitendo, CPU inachukulia pointer `0xTTxxxx_xxxx_xxxx` (ambapo `TT` = top byte) kama `0x00xxxx_xxxx_xxxx` kwa ajili ya tafsiri ya anwani, ikifukuza (kuweka mask) top byte. Top byte inaweza kutumiwa na programu kuhifadhi **metadata / tag bits**.
- Hii inatoa nafasi “ya ndani” kwa programu kuingiza byte ya tag katika kila pointer bila kubadilisha eneo la kumbukumbu linalorejelewa.
- Maumbile huhakikisha kuwa loads, stores, na instruction fetch hutumia pointer yenye top byte imeondolewa (yaani tag imepigwa) kabla ya kufanya ufikiaji wa kumbukumbu.

Hivyo TBI inatenganisha **pointer la kimantiki** (pointer + tag) na **anwani ya kimwili** inayotumika kwa operesheni za kumbukumbu.

#### Kwa nini TBI: Matumizi na motisha

- **Pointer tagging / metadata**: Unaweza kuhifadhi metadata ya ziada (mfano aina ya kitu, toleo, mipaka, tag za uadilifu) katika top byte. Unapoitumia pointer baadaye, tag inatwaliwa na hardware, kwa hivyo huhitaji kuiondoa kwa mkono kabla ya ufikiaji wa kumbukumbu.
- **Memory tagging / MTE (Memory Tagging Extension)**: TBI ni mfumo wa msingi wa hardware ambao MTE inajenga juu yake. Katika ARMv8.5, Memory Tagging Extension inatumia bits 59:56 za pointer kama **logical tag** na kuikagua dhidi ya **allocation tag** iliyohifadhiwa katika kumbukumbu.
- **Usalama ulioboreshwa & uadilifu**: Kwa kuunganisha TBI na pointer authentication (PAC) au ukaguzi wa wakati wa utekelezaji, unaweza kulazimisha si tu thamani ya pointer bali pia tag iwe sahihi. Mdukuzi anayebadilisha pointer bila tag sahihi atasababisha tag isiyolingana.
- **Ulinganifu**: Kwa kuwa TBI ni hiari na bit za tag zinafisikwa na hardware, msimbo uliopo bila tag unaendelea kufanya kazi kawaida. Bit za tag zinakuwa kama “bila maana” kwa msimbo wa urithi.

#### Mfano
<details>
<summary>Mfano</summary>
Function pointer ilihifadhi tag katika top byte yake (kwa mfano `0xAA`). Exploit inabandika juu bits za chini za pointer lakini ikasahau tag, hivyo wakati kernel inathibitisha au kusafisha, pointer inashindwa au inakataliwa.
</details>

---

### 12. **Page Protection Layer (PPL)**
**Iliyoletwa katika iOS ya karibuni / hardware za kisasa (iOS ~17 / Apple silicon / mifano ya kiwango cha juu)** (ripoti zingine zinaonyesha PPL karibu macOS / Apple silicon, lakini Apple inaeneza ulinzi unaofanana hadi iOS)

- PPL imeundwa kama mpaka wa ulinzi ndani ya kernel: hata kama kernel (EL1) imevamiwa na ina uwezo wa kusoma/kuandika, **haitakiwi kuwa na uwezo wa kubadilisha kwa uhuru** kurasa fulani **nyeti** (hasa page tables, metadata za code-signing, kurasa za code za kernel, entitlements, trust caches, n.k.).
- Inaongeza dhana ya **“kernel ndani ya kernel”** — kipengele kidogo kinachoaminiwa (PPL) chenye **idhara za juu** ambacho pekee ndicho kinaweza kubadilisha kurasa zilizolindwa. Msimbo mwingine wa kernel lazima uingie katika utaratibu wa PPL ili kufanya mabadiliko.
- Hii inapunguza uso wa shambulio kwa exploits za kernel: hata ukiwa na R/W/execute bila kikomo katika mode ya kernel, msimbo wa exploit lazima pia upate njia ya kuingia kwingine ndani ya PPL (au kupita PPL) ili kubadilisha miundombinu muhimu.
- Katika Apple silicon mpya (A15+ / M2+), Apple inabadilisha kuelekea **SPTM (Secure Page Table Monitor)**, ambayo katika kesi nyingi inachukua nafasi ya PPL kwa ulinzi wa page-table kwenye majukwaa hayo.

Hivi ndivyo PPL inavyodhaniwa kufanya kazi, kulingana na uchambuzi wa umma:

#### Matumizi ya APRR / permission routing (APRR = Access Permission ReRouting)

- Hardware ya Apple inatumia mfumo unaoitwa **APRR (Access Permission ReRouting)**, unaoruhusu page table entries (PTEs) kuwa na viashiria vidogo, badala ya bita kamili za ruhusa. Viashiria hivyo vinatambuliwa kupitia rejista za APRR kuwa ruhusa halisi. Hii inaruhusu kubadilika kwa ramani za ruhusa kwa kila domain.
- PPL inatumia APRR kutenganisha daraja ndani ya muktadha wa kernel: ni domain ya PPL pekee inayoruhusiwa kusasisha ulinganifu kati ya viashiria na ruhusa halisi. Yaani, wakati msimbo wa kernel usio wa PPL unaandika PTE au kujaribu kubadilisha bita za ruhusa, mantiki ya APRR hainiruhusu (au inafanya iwe read-only).
- Msimbo wa PPL wenyewe huendeshwa katika eneo lililopunguzwa (mfano `__PPLTEXT`) ambalo kwa kawaida haliruhusiwi kuwa executable au writable hadi milango ya kuingia ya muda ifunguliwe. Kernel inaita pointi za kuingia za PPL (“PPL routines”) kufanya operesheni nyeti.

#### Lango / Ingia & Toka

- Wakati kernel inahitaji kubadilisha ukurasa uliolindwa (mfano kubadilisha ruhusa za ukurasa wa kernel, au kubadili page tables), inaita katika rutini ya wrapper ya **PPL**, ambayo inafanya uthibitisho na kisha inabadilisha hadi eneo la PPL. Nje ya eneo hilo, kurasa zilizolindwa zimewekwa kuwa kawaida read-only au zisizoweza kuhaririwa na kernel kuu.
- Wakati wa kuingia PPL, mappings za APRR zinabadilishwa ili kurasa za eneo la PPL ziwe **executable & writable** ndani ya PPL. Baada ya kutoka, zinarejeshwa kuwa read-only / non-writable. Hii inahakikisha kuwa ni rutini za PPL tu zilizochunguzwa vizuri zinaweza kuandika kwa kurasa zilizolindwa.
- Nje ya PPL, jaribio la msimbo wa kernel kuandika kurasa zilizolindwa litasababisha fault (ruhusa imekataa) kwa sababu ramani ya APRR kwa domain hiyo haikubali kuandika.

#### Aina za kurasa zilizo na ulinzi

Kurasa ambazo PPL kawaida inalinda ni pamoja na:

- Miundo ya page table (translation table entries, metadata za mapping)
- Kurasa za code za kernel, hasa zile zenye mantiki nyeti
- Metadata za code-sign (trust caches, blobs za saini)
- Jedwali la entitlements, jedwali la utekelezaji wa saini
- Miundo mingine ya kernel yenye thamani kubwa ambapo kuhariri kwao kungeweza kuruhusu kupitisha ukaguzi wa saini au kubadilisha idhini

Wazo ni kwamba hata kama kumbukumbu ya kernel inadhibitiwa kabisa, mdukuzi hawezi tu kuhariri au kuandika kurasa hizi, isipokuwa pia avami rutini za PPL au apite PPL.

#### Bypasses zilizojulikana & Udhaifu

1. **Bypass ya Project Zero kwa PPL (njia ya stale TLB)**

- Uandishi wa umma na Project Zero unaelezea bypass inayohusisha **stale TLB entries**.
- Wazo ni:

1. Tenga kurasa mbili za kimwili A na B, ziwape alama kama kurasa za PPL (kwa hivyo zinalindwa).
2. Ramisha anwani mbili za kimtandao P na Q ambazo L3 translation table pages zinatoka A na B.
3. Endesha thread ili ikingie Q mara kwa mara, kuweka entry yake ya TLB hai.
4. Piga `pmap_remove_options()` kuondoa mappings kuanzia P; kutokana na mende, msimbo kwa makosa unaondoa TTEs za P na Q, lakini unahitajika kuhalalisha TLB entry kwa P pekee, ukiwaacha entry ya Q kama stale.
5. Tumia tena B (table ya ukurasa wa Q) kuonyesha kumbukumbu yoyote (mfano kurasa zilizo za PPL). Kwa sababu entry ya TLB ya stale bado inahakikisha ramani ya zamani ya Q, ramani hiyo inabaki halali kwa muktadha huo.
6. Kupitia hili, mdukuzi anaweza kuweka mapping iliyoweza kuandikwa ya kurasa za PPL bila kupitia kiolesura cha PPL.

- Exploit hii ilihitaji udhibiti wa kina wa ramani za kimwili na tabia ya TLB. Inaonyesha kwamba mpaka wa usalama unaotegemea TLB / usahihi wa ramani lazima uwe makini sana kuhusu uharibifu wa TLB na ulinganifu wa ramani.
- Project Zero walisema kwamba bypass kama hizi ni nyeti na nadra, lakini zinawezekana katika mifumo tata. Hata hivyo, wanazingatia PPL kama ukarabati thabiti.

2. **Hatari nyingine zinazowezekana & vikwazo**

- Ikiwa exploit ya kernel inaweza kuingia moja kwa moja katika rutini za PPL (kwa kuita wrappers za PPL), inaweza kupita vikwazo. Kwa hivyo uthibitishaji wa argimenti ni muhimu.
- Mende katika msimbo wa PPL wenyewe (mfano overflow ya arithmetic, ukaguzi wa mipaka) zinaweza kuruhusu urekebishaji nje ya mipaka ndani ya PPL. Project Zero waliona kwamba mende katika `pmap_remove_options_internal()` ilitumika katika bypass yao.
- Mipaka ya PPL imeunganishwa bila kurekebishwa na utekelezaji wa hardware (APRR, memory controller), hivyo nguvu yake ni ile ile kama utekelezaji wa hardware.

#### Mfano
<details>
<summary>Mfano wa Msimbo</summary>
Hapa kuna pseudocode / mantiki iliyo rahisi inayoonyesha jinsi kernel inaweza kuita PPL ili kubadilisha kurasa zilizolindwa:
</details>
<div class="codeblock_filename_container"><span class="codeblock_filename_inner hljs">c</span></div>

```c
// In kernel (outside PPL domain)
function kernel_modify_pptable(pt_addr, new_entry) {
// validate arguments, etc.
return ppl_call_modify(pt_addr, new_entry)  // call PPL wrapper
}

// In PPL (trusted domain)
function ppl_call_modify(pt_addr, new_entry) {
// temporarily enable write access to protected pages (via APRR adjustments)
aprr_set_index_for_write(PPL_INDEX)
// perform the modification
*pt_addr = new_entry
// restore permissions (make pages read-only again)
aprr_restore_default()
return success
}

// If kernel code outside PPL does:
*pt_addr = new_entry  // a direct write
// It will fault because APRR mapping for non-PPL domain disallows write to that page

The kernel can do many normal operations, but only through ppl_call_* routines can it change protected mappings or patch code.

Example A kernel exploit tries to overwrite the entitlement table, or disable code-sign enforcement by modifying a kernel signature blob. Because that page is PPL-protected, the write is blocked unless going through the PPL interface. So even with kernel code execution, you cannot bypass code-sign constraints or modify credential data arbitrarily. On iOS 17+ certain devices use SPTM to further isolate PPL-managed pages.

PPL → SPTM / Mbadala / Mustakabali

  • On Apple’s modern SoCs (A15 or later, M2 or later), Apple supports SPTM (Secure Page Table Monitor), which replaces PPL for page table protections.
  • Apple calls out in documentation: “Page Protection Layer (PPL) and Secure Page Table Monitor (SPTM) enforce execution of signed and trusted code … PPL manages the page table permission overrides … Secure Page Table Monitor replaces PPL on supported platforms.”
  • The SPTM architecture likely shifts more policy enforcement into a higher-privileged monitor outside kernel control, further reducing the trust boundary.

MTE | EMTE | MIE

Here’s a higher-level description of how EMTE operates under Apple’s MIE setup:

  1. Ugawaji wa tag
  • When memory is allocated (e.g. in kernel or user space via secure allocators), a secret tag is assigned to that block.
  • The pointer returned to the user or kernel includes that tag in its high bits (using TBI / top byte ignore mechanisms).
  1. Tag checking on access
  • Whenever a load or store is executed using a pointer, the hardware checks that the pointer’s tag matches the memory block’s tag (allocation tag). If mismatch, it faults immediately (since synchronous).
  • Because it's synchronous, there is no “delayed detection” window.
  1. Kuretag wakati wa free / reuse
  • When memory is freed, the allocator changes the block’s tag (so older pointers with old tags no longer match).
  • A use-after-free pointer would therefore have a stale tag and mismatch when accessed.
  1. Neighbor-tag differentiation to catch overflows
  • Adjacent allocations are given distinct tags. If a buffer overflow spills into neighbor’s memory, tag mismatch causes a fault.
  • This is especially powerful in catching small overflows that cross boundary.
  1. Tag confidentiality enforcement
  • Apple must prevent tag values being leaked (because if attacker learns the tag, they could craft pointers with correct tags).
  • They include protections (microarchitectural / speculative controls) to avoid side-channel leakage of tag bits.
  1. Kernel and user-space integration
  • Apple uses EMTE not just in user-space but also in kernel / OS-critical components (to guard kernel against memory corruption).
  • The hardware/OS ensures tag rules apply even when kernel is executing on behalf of user space.
Example ``` Allocate A = 0x1000, assign tag T1 Allocate B = 0x2000, assign tag T2

// pointer P points into A with tag T1 P = (T1 << 56) | 0x1000

// Valid store *(P + offset) = value // tag T1 matches allocation → allowed

// Overflow attempt: P’ = P + size_of_A (into B region) *(P' + delta) = value → pointer includes tag T1 but memory block has tag T2 → mismatch → fault

// Free A, allocator retags it to T3 free(A)

// Use-after-free: *(P) = value → pointer still has old tag T1, memory region is now T3 → mismatch → fault

</details>

#### Limitations & challenges

- **Intrablock overflows**: Ikiwa overflow inabaki ndani ya allocation ileile (haipiti boundary) na tag inabaki ile ile, tag mismatch haikutambuli.
- **Tag width limitation**: Bits chache tu (kwa mfano 4 bits, au domain ndogo) zinapatikana kwa tag—namespace ndogo.
- **Side-channel leaks**: Ikiwa bit za tag zinaweza kufichuliwa (kwa kupitia cache / speculative execution), mshambuliaji anaweza kujua tags halali na kupitisha. Apple’s Tag Confidentiality Enforcement inalenga kupunguza hili.
- **Performance overhead**: Ukaguzi wa tag kwa kila load/store unaongeza gharama; Apple lazima isakinishe hardware ili kupunguza overhead.
- **Compatibility & fallback**: Kwa hardware ya zamani au sehemu ambazo hazitumi support ya EMTE, lazima kuwe na fallback. Apple inadai MIE imewezeshwa tu kwenye devices zenye support.
- **Complex allocator logic**: Allocator lazima idaribu tags, retagging, kulinganisha boundaries, na kuepuka mis-tag collisions. Bugs katika logic ya allocator zinaweza kuleta udhaifu.
- **Mixed memory / hybrid areas**: Baadhi ya memory inaweza kubaki untagged (legacy), kufanya interoperabilty iwe ngumu zaidi.
- **Speculative / transient attacks**: Kama ilivyo kwa nyingi microarchitectural protections, speculative execution au micro-op fusions zinaweza kupitisha checks transiently au kufichua tag bits.
- **Limited to supported regions**: Apple inaweza kutekeleza EMTE tu katika maeneo maalum yaliyo katika hatari kubwa (kernel, security-critical subsystems), sio kote.

---

## Key enhancements / differences compared to standard MTE

Here are the improvements and changes Apple emphasizes:

| Feature | Original MTE | EMTE (Apple’s enhanced) / MIE |
|---|---|---|
| **Check mode** | Supports synchronous and asynchronous modes. In async, tag mismatches are reported later (delayed)| Apple insists on **synchronous mode** by default—tag mismatches are caught immediately, no delay/race windows allowed.|
| **Coverage of non-tagged memory** | Accesses to non-tagged memory (e.g. globals) may bypass checks in some implementations | EMTE requires that accesses from a tagged region to non-tagged memory also validate tag knowledge, making it harder to bypass by mixing allocations.|
| **Tag confidentiality / secrecy** | Tags might be observable or leaked via side channels | Apple adds **Tag Confidentiality Enforcement**, which attempts to prevent leakage of tag values (via speculative side-channels etc.).|
| **Allocator integration & retagging** | MTE leaves much of allocator logic to software | Apple’s secure typed allocators (kalloc_type, xzone malloc, etc.) integrate with EMTE: when memory is allocated or freed, tags are managed at fine granularity.|
| **Always-on by default** | In many platforms, MTE is optional or off by default | Apple enables EMTE / MIE by default on supported hardware (e.g. iPhone 17 / A19) for kernel and many user processes.|

Kwa kuwa Apple inasimamia hardware na software stack pamoja, inaweza kutekeleza EMTE kwa nguvu, kuepuka performance pitfalls, na kufunga njia za side-channel.

---

## How EMTE works in practice (Apple / MIE)

Here’s a higher-level description of how EMTE operates under Apple’s MIE setup:

1. **Tag assignment**
- When memory is allocated (e.g. in kernel or user space via secure allocators), a **secret tag** is assigned to that block.
- The pointer returned to the user or kernel includes that tag in its high bits (using TBI / top byte ignore mechanisms).

2. **Tag checking on access**
- Whenever a load or store is executed using a pointer, the hardware checks that the pointer’s tag matches the memory block’s tag (allocation tag). If mismatch, it faults immediately (since synchronous).
- Because it's synchronous, there is no “delayed detection” window.

3. **Retagging on free / reuse**
- When memory is freed, the allocator changes the block’s tag (so older pointers with old tags no longer match).
- A use-after-free pointer would therefore have a stale tag and mismatch when accessed.

4. **Neighbor-tag differentiation to catch overflows**
- Adjacent allocations are given distinct tags. If a buffer overflow spills into neighbor’s memory, tag mismatch causes a fault.
- This is especially powerful in catching small overflows that cross boundary.

5. **Tag confidentiality enforcement**
- Apple must prevent tag values being leaked (because if attacker learns the tag, they could craft pointers with correct tags).
- They include protections (microarchitectural / speculative controls) to avoid side-channel leakage of tag bits.

6. **Kernel and user-space integration**
- Apple uses EMTE not just in user-space but also in kernel / OS-critical components (to guard kernel against memory corruption).
- The hardware/OS ensures tag rules apply even when kernel is executing on behalf of user space.

Because EMTE is built into MIE, Apple uses EMTE in synchronous mode across key attack surfaces, not as opt-in or debugging mode.

---

## Exception handling in XNU

When an **exception** occurs (e.g., `EXC_BAD_ACCESS`, `EXC_BAD_INSTRUCTION`, `EXC_CRASH`, `EXC_ARM_PAC`, etc.), the **Mach layer** of the XNU kernel is responsible for intercepting it before it becomes a UNIX-style **signal** (like `SIGSEGV`, `SIGBUS`, `SIGILL`, ...).

This process involves multiple layers of exception propagation and handling before reaching user space or being converted to a BSD signal.

### Exception Flow (High-Level)

1.  **CPU triggers a synchronous exception** (e.g., invalid pointer dereference, PAC failure, illegal instruction, etc.).

2.  **Low-level trap handler** runs (`trap.c`, `exception.c` in XNU source).

3.  The trap handler calls **`exception_triage()`**, the core of the Mach exception handling.

4.  `exception_triage()` decides how to route the exception:

-   First to the **thread's exception port**.

-   Then to the **task's exception port**.

-   Then to the **host's exception port** (often `launchd` or `ReportCrash`).

If none of these ports handle the exception, the kernel may:

-   **Convert it into a BSD signal** (for user-space processes).

-   **Panic** (for kernel-space exceptions).

### Core Function: `exception_triage()`

The function `exception_triage()` routes Mach exceptions up the chain of possible handlers until one handles it or until it's finally fatal. It's defined in `osfmk/kern/exception.c`.
<div class="codeblock_filename_container"><span class="codeblock_filename_inner hljs">c</span></div>

```c
void exception_triage(exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt);

Mtiririko wa Kawaida wa Kuitwa:

exception_triage() └── exception_deliver() ├── exception_deliver_thread() ├── exception_deliver_task() └── exception_deliver_host()

Iwapo yote yatashindwa → inashughulikiwa na bsd_exception() → hubadilishwa kuwa ishara kama SIGSEGV.

Exception Ports

Kila Mach object (thread, task, host) inaweza kusajili exception ports, ambapo ujumbe za exception hutumwa.

Zimefafanuliwa na API:

task_set_exception_ports()
thread_set_exception_ports()
host_set_exception_ports()

Each exception port has:

  • A mask (ni exceptions ipi inazotaka kupokea)
  • A port name (Mach port ya kupokea ujumbe)
  • A behavior (jinsi kernel inavyotuma ujumbe)
  • A flavor (ni thread state gani itakayojumuishwa)

Debuggers and Exception Handling

A debugger (mfano, LLDB) huweka exception port kwenye target task au thread, kawaida kwa kutumia task_set_exception_ports().

Wakati exception inapotokea:

  • Ujumbe wa Mach hutumwa kwa mchakato wa debugger.
  • Debugger inaweza kuamua kushughulikia (resume, modify registers, skip instruction) au kutokushughulikia exception.
  • Ikiwa debugger haitashughulikia, exception husambaa kwa ngazi inayofuata (task → host).

Flow of EXC_BAD_ACCESS

  1. Thread inarejelea pointer isiyo halali → CPU inatoa Data Abort.

  2. Trap handler ya kernel inaita exception_triage(EXC_BAD_ACCESS, ...).

  3. Ujumbe hutumwa kwa:

  • Thread port → (debugger anaweza kukamata breakpoint).

  • Ikiwa debugger inapuuza → Task port → (process-level handler).

  • Ikiwa inapuuziwa → Host port (kawaida ReportCrash).

  1. Iwapo hakuna anayeshughulikia → bsd_exception() hubadilisha kuwa SIGSEGV.

PAC Exceptions

Wakati Pointer Authentication (PAC) inashindwa (signature haiendani), special Mach exception inafufuliwa:

  • EXC_ARM_PAC (type)
  • Codes zinaweza kujumuisha maelezo (mfano, aina ya key, aina ya pointer).

Ikiwa binary ina flag TFRO_PAC_EXC_FATAL, kernel huchukulia kushindwa kwa PAC kama fatal, ikiepuka kukamatwa na debugger. Hii ni kuzuia wadukuzi kutumia debuggers kuzunguka PAC checks na imewezeshwa kwa platform binaries.

Software Breakpoints

A software breakpoint (int3 on x86, brk on ARM64) inatekelezwa kwa kusababisha fault kwa makusudi.
Debugger inakamata hili kupitia exception port:

  • Hubadilisha instruction pointer au memory.
  • Inarejesha instruction ya awali.
  • Inaendelea utekelezaji.

Mekanizimu hii ile ile inakuwezesha "kukamata" PAC exception --- isipokuwa TFRO_PAC_EXC_FATAL iko, kisha haiifikii debugger.

Conversion to BSD Signals

Ikiwa hakuna handler anayekubali exception:

  • Kernel inaita task_exception_notify() → bsd_exception().

  • Hii inalinganisha Mach exceptions na signals:

Mach ExceptionSignal
EXC_BAD_ACCESSSIGSEGV or SIGBUS
EXC_BAD_INSTRUCTIONSIGILL
EXC_ARITHMETICSIGFPE
EXC_SOFTWARESIGTRAP
EXC_BREAKPOINTSIGTRAP
EXC_CRASHSIGKILL
EXC_ARM_PACSIGILL (on non-fatal)

### Key Files in XNU Source

  • osfmk/kern/exception.c → Msingi wa exception_triage(), exception_deliver_*().
  • bsd/kern/kern_sig.c → Mantiki ya utoaji wa signal.
  • osfmk/arm64/trap.c → Low-level trap handlers.
  • osfmk/mach/exc.h → Exception codes and structures.
  • osfmk/kern/task.c → Task exception port setup.

Old Kernel Heap (Kabla ya iOS 15 / Kabla ya A12)

Kernel ilitumia zone allocator (kalloc) iliyogawanywa kwenye fixed-size "zones." Kila zone ilihifadhi tu allocations za daraja moja ya ukubwa.

From the screenshot:

Jina la ZoneUkubwa wa KipengeeMfano wa Matumizi
default.kalloc.1616 bytesMiundo ndogo sana za kernel, pointers.
default.kalloc.3232 bytesMiundo midogo, object headers.
default.kalloc.6464 bytesIPC messages, tiny kernel buffers.
default.kalloc.128128 bytesVitu vya kati kama sehemu za OSObject.
default.kalloc.12801280 bytesMiundo mikubwa, IOSurface/graphics metadata.

Ilivyofanya kazi:

  • Kila ombi la allocation linapangiliwa hadi ukubwa wa zone inayofaa. (Mfano, ombi la 50-byte linaingia kwenye kalloc.64 zone).
  • Kumbukumbu katika kila zone ilihifadhiwa kwenye free list — vipande vilivyofunguliwa na kernel vilirudi kwenye zone hiyo.
  • Ikiwa utavunja buffer ya 64-byte, ungeandika juu ya kitu kinachofuata kwenye zone ileile.

Hii ndiyo sababu heap spraying / feng shui ilikuwa yenye ufanisi: uliweza kutabiri majirani wa vitu kwa kupiga allocations za daraja moja ya ukubwa.

Orodha ya bure (freelist)

Ndani ya kila kalloc zone, vitu vilivyofunguliwa havikurudishwa moja kwa moja kwa mfumo — viliingia kwenye freelist, orodha iliyounganishwa ya vipande vinavyopatikana.

  • Wakati kipande kimefunguliwa, kernel iliandika pointer mwanzoni mwa kipande hicho → anwani ya kipande kinachofuata chenye bure katika zone ileile.

  • Zone ilihifadhi pointer HEAD kwa kipande cha kwanza kilicho bure.

  • Allocation ilitumia kila mara HEAD ya sasa:

  1. Pop HEAD (rudisha kumbukumbu hiyo kwa muomba).

  2. Sasisha HEAD = HEAD->next (iliyoandikwa kwenye kichwa cha kipande kilichofunguliwa).

  • Kufungua kulisukuma vipande kurudi:

  • freed_chunk->next = HEAD

  • HEAD = freed_chunk

Hivyo freelist ilikuwa orodha iliyounganishwa iliyojengwa ndani ya kumbukumbu iliyofunguliwa yenyewe.

Normal state:

Zone page (64-byte chunks for example):
[ A ] [ F ] [ F ] [ A ] [ F ] [ A ] [ F ]

Freelist view:
HEAD ──► [ F ] ──► [ F ] ──► [ F ] ──► [ F ] ──► NULL
(next ptrs stored at start of freed chunks)

Exploiting the freelist

Kwa sababu the first 8 bytes of a free chunk = freelist pointer, mshambuliaji anaweza kuharibu:

  1. Heap overflow ndani ya freed chunk iliyoko jirani → kuandika tena “next” pointer yake.

  2. Use-after-free kuandika ndani ya freed object → kuandika tena “next” pointer yake.

Kisha, kwenye allocation inayofuata ya ukubwa huo:

  • Allocator huondoa (pops) chunk iliyoharibika.

  • Inafuata “next” pointer iliyotolewa na mshambuliaji.

  • Inarudisha pointer kwa memory yoyote, ikiruhusu fake object primitives au targeted overwrite.

Visual example of freelist poisoning:

Before corruption:
HEAD ──► [ F1 ] ──► [ F2 ] ──► [ F3 ] ──► NULL

After attacker overwrite of F1->next:
HEAD ──► [ F1 ]
(next) ──► 0xDEAD_BEEF_CAFE_BABE  (attacker-chosen)

Next alloc of this zone → kernel hands out memory at attacker-controlled address.

This freelist design ilifanya exploitation kuwa ya ufanisi mkubwa kabla ya hardening: majirani yanayoweza kutabirika kutokana na heap sprays, raw pointer freelist links, na kutokuwepo kwa separation ya aina kuliruhusu attackers kuinua mdudu wa UAF/overflow hadi kudhibiti arbitrary kernel memory.

Heap Grooming / Feng Shui

The goal of heap grooming ni kuunda mpangilio wa heap ili wakati attacker atakapoanzisha overflow au use-after-free, object la lengo (victim) likae karibu kabisa na object inayodhibitiwa na attacker.
Kwa njia hiyo, wakati corruption ya memory inapotokea, attacker anaweza kwa uhakika kuandika juu object la victim na data anayotaka.

Steps:

  1. Spray allocations (fill the holes)
  • Kwa muda, kernel heap inageuka fragmented: baadhi ya zones zina mashimo ambapo objects za zamani zilifunguliwa.
  • Attacker kwanza anafanya allocations nyingi za dummy ili kujaza pengo hizi, hivyo heap inakuwa “packed” na inayotabirika.
  1. Force new pages
  • Mara mashimo yanapojazwa, allocations inayofuata lazima itoke kwenye pages mpya zilizoongezwa kwenye zone.
  • Pages safi zinamaanisha objects zitakuwa clustered pamoja, si kusambaa kwenye memory ya zamani yenye fragmentation.
  • Hii inampa attacker udhibiti bora wa majirani.
  1. Place attacker objects
  • Attacker sasa anafanya spray tena, akitengeneza objects nyingi zinazoendeshwa na attacker kwenye pages hizo mpya.
  • Objects hizi zina ukubwa na nafasi zinazotabirika (kwa kuwa zote ziko kwenye zone moja).
  1. Free a controlled object (make a gap)
  • Attacker hubadilika akatoa moja ya objects zake mwenyewe.
  • Hii inaunda “hole” kwenye heap, ambayo allocator baadaye itatumia kwa allocation inayofuata ya ukubwa huo.
  1. Victim object lands in the hole
  • Attacker anasababisha kernel kuallocate object la victim (ile wanayotaka kuharibu).
  • Kwa kuwa hole ni slot ya kwanza inayopatikana kwenye freelist, victim inawekwa mahali pale pale ambapo attacker aliifungua object yake.
  1. Overflow / UAF into victim
  • Sasa attacker ana objects zinazodhibitiwa na attacker karibu na victim.
  • Kwa kuoverflow kutoka kwenye moja ya objects zao (au kutumia tena iliyofunguliwa), wanaweza kwa uhakika kuandika juu ya fields za memory za victim kwa thamani walizochagua.

Why it works:

  • Zone allocator predictability: allocations za ukubwa sawa kila mara zinatoka kwenye zone ile ile.
  • Freelist behavior: allocations mpya zinatumia chunk iliyofunguliwa hivi karibuni kwanza.
  • Heap sprays: attacker anajaza memory na content inayotabirika na anadhibiti layout.
  • End result: attacker anadhibiti mahali ambako object la victim linakuja na data inayokaa karibu nalo.

Modern Kernel Heap (iOS 15+/A12+ SoCs)

Apple iliharden allocator na kufanya heap grooming kuwa ngumu zaidi:

1. From Classic kalloc to kalloc_type

  • Before: zone moja kalloc.<size> ilikuwapo kwa kila size class (16, 32, 64, … 1280, n.k.). Kila object ya ukubwa huo iliwekwa pale → attacker objects zingeweza kukaa karibu na kernel objects zilizo priveleged.
  • Now:
  • Kernel objects zinaallocate kutoka kwa typed zones (kalloc_type).
  • Kila aina ya object (mf., ipc_port_t, task_t, OSString, OSData) ina zone yake maalum, hata kama zina ukubwa ule ule.
  • Mapping kati ya object type ↔ zone inazalishwa kutoka kwa kalloc_type system wakati wa compile.

Attacker hawezi tena kuhakikisha kwamba data iliyo controlled (OSData) itakapokaa karibu na kernel objects nyeti (task_t) za ukubwa ule ule.

2. Slabs and Per-CPU Caches

  • Heap imegawanywa kuwa slabs (pages za memory zilizokatwa katika chunks za ukubwa thabiti kwa zone hiyo).
  • Kila zone ina per-CPU cache kupunguza contention.
  • Allocation path:
  1. Jaribu per-CPU cache.
  2. Ikiwa siku wazi, chukua kutoka global freelist.
  3. Ikiwa freelist tupu, allocate slab mpya (page moja au zaidi).
  • Faida: decentralization hii inafanya heap sprays zisitabirike kwa urahisi, kwani allocations zinaweza kutimizwa kutoka caches za CPU tofauti.

3. Randomization inside zones

  • Ndani ya zone, elements zilizofunguliwa hazirudishiwi kwa FIFO/LIFO rahisi.
  • XNU ya kisasa inatumia encoded freelist pointers (safe-linking style kama Linux, ilianzishwa ~iOS 14).
  • Kila freelist pointer imeXOR-encoded na cookie ya siri ya zone.
  • Hii inazuia attackers kutengeneza pointer za freelist za uongo ikiwa wanapata write primitive.
  • Baadhi allocations zinapangwa kwa randomized placement ndani ya slab, kwa hivyo spraying haitahakikishi adjacency.

4. Guarded Allocations

  • Baadhi kernel objects muhimu (mf., credentials, task structures) zinaallocate katika guarded zones.
  • Zones hizi zinaweka guard pages (memory isiyo mapped) kati ya slabs au kutumia redzones kuzunguka objects.
  • Overflow yoyote katika guard page husababisha fault → panic mara moja badala ya corruption kimya.

5. Page Protection Layer (PPL) and SPTM

  • Hata ukidhibiti object uliotolewa, huwezi kubadilisha yote ya kernel memory:
  • PPL (Page Protection Layer) inasimamia kwamba maeneo fulani (mf., code signing data, entitlements) ni read-only hata kwa kernel yenyewe.
  • Kwenye A15/M2+ devices, nafasi hii imebadilishwa/imetiwa nguvu na SPTM (Secure Page Table Monitor) + TXM (Trusted Execution Monitor).
  • Tabaka hizi za hardware-zilizotekelezwa zinamaanisha attackers hawawezi kuinuka kutoka kwa single heap corruption hadi kufanya patch yoyote arbitrary ya critical security structures.
  • (Added / Enhanced): pia, PAC (Pointer Authentication Codes) inatumika kwenye kernel kulinda pointers (hasa function pointers, vtables) ili kutengeneza au kuharibu kuwa ngumu zaidi.
  • (Added / Enhanced): zones zinaweza kutekeleza zone_require / zone enforcement, yaani kwamba object iliyofunguliwa inaweza kurudishwa tu kupitia zone yake sahihi; frees zisizo sahihi kati ya zones zinaweza kusababisha panic au kukataliwa. (Apple yanataja hili katika machapisho yao kuhusu memory safety)

6. Large Allocations

  • Si allocations zote zinapitia kalloc_type.
  • Requests kubwa sana (juu ya ~16 KB) hupita typed zones na hutolewa moja kwa moja kutoka kernel VM (kmem) kupitia page allocations.
  • Hizi hazitabiriki sana, lakini pia hazielekezwi sana kwa exploitation, kwa kuwa hazishiriki slabs na objects nyingine.

7. Allocation Patterns Attackers Target

Hata na kinga hizi, attackers bado wanatafuta:

  • Reference count objects: ikiwa unaweza kubadilisha retain/release counters, unaweza kusababisha use-after-free.
  • Objects with function pointers (vtables): kuharibu moja bado hutoa control flow.
  • Shared memory objects (IOSurface, Mach ports): hizi bado ni malengo kwa sababu zinakwandisha user ↔ kernel.

Lakini — tofauti na zamani — huwezi tu kufanya spray OSData na kutarajia ije karibu na task_t. Unahitaji bugs maalum kwa aina au info leaks kufanikiwa.

Example: Allocation Flow in Modern Heap

Suppose userspace inaita IOKit kuallocate object OSData:

  1. Type lookupOSData inaenda kwenye kalloc_type_osdata zone (size 64 bytes).
  2. Angalia per-CPU cache kwa elements zote za bure.
  • Ikiwa ipo → rudisha moja.
  • Ikiwa tupu → nenda kwenye global freelist.
  • Ikiwa freelist tupu → allocate slab mpya (page ya 4KB → 64 chunks za 64 bytes).
  1. Rudisha chunk kwa mtumiaji.

Freelist pointer protection:

  • Kila chunk iliyofunguliwa inahifadhi address ya chunk inayofuata ya bure, lakini imeencoded na key ya siri.
  • Kuandika juu ya field hiyo kwa data ya attacker hautafanya kazi isipokuwa unajua key.

Comparison Table

FeatureOld Heap (Pre-iOS 15)Modern Heap (iOS 15+ / A12+)
Allocation granularityFixed size buckets (kalloc.16, kalloc.32, etc.)Size + type-based buckets (kalloc_type)
Placement predictabilityHigh (same-size objects side by side)Low (same-type grouping + randomness)
Freelist managementRaw pointers in freed chunks (easy to corrupt)Encoded pointers (safe-linking style)
Adjacent object controlEasy via sprays/frees (feng shui predictable)Hard — typed zones separate attacker objects
Kernel data/code protectionsFew hardware protectionsPPL / SPTM protect page tables & code pages, and PAC protects pointers
Allocation reuse validationNone (freelist pointers raw)zone_require / zone enforcement
Exploit reliabilityHigh with heap spraysMuch lower, requires logic bugs or info leaks
Large allocations handlingAll small allocations managed equallyLarge ones bypass zones → handled via VM

Modern Userland Heap (iOS, macOS — type-aware / xzone malloc)

Katika toleo za hivi karibuni za Apple OS (hasa iOS 17+), Apple ilianzisha allocator ya userland ya usalama zaidi, xzone malloc (XZM). Hii ni analog ya user-space kwa kalloc_type ya kernel, ikitumia type awareness, metadata isolation, na memory tagging safeguards.

Goals & Design Principles

  • Type segregation / type awareness: kuunganisha allocations kwa aina au matumizi (pointer vs data) ili kuzuia type confusion na cross-type reuse.
  • Metadata isolation: kutenganisha heap metadata (mf. free lists, size/state bits) kutoka payload ya objects ili out-of-bounds writes isiweze kuharibu metadata.
  • Guard pages / redzones: kuweka unmapped pages au padding kuzunguka allocations ili kugundua overflows.
  • Memory tagging (EMTE / MIE): kufanya kazi kwa pamoja na hardware tagging kugundua use-after-free, out-of-bounds, na accesses zisizo halali.
  • Scalable performance: kudumisha overhead ndogo, kuepuka fragmentation nyingi, na kusaidia allocations nyingi kwa sekunde kwa latency ndogo.

Architecture & Components

Hapa chini ni vipengele vikuu vya xzone allocator:

Segment Groups & Zones

  • Segment groups hunyanyua address space kwa kategoria za matumizi: mf. data, pointer_xzones, data_large, pointer_large.
  • Kila segment group ina segments (VM ranges) zinazoweka allocations kwa kategoria hiyo.
  • Kila segment ina metadata slab (eneo tofauti la VM) linalohifadhi metadata (mf. free/used bits, size classes) kwa segment hiyo. Hii out-of-line (OOL) metadata inahakikisha metadata haichanganyiki na payload ya object, kupunguza uharibifu kutokana na overflows.
  • Segments zimegawanywa katika chunks (slices) ambazo zinasambazwa ndani katika blocks (unites za allocation). Chunk imehusishwa na size class na segment group maalum (yaani blocks zote katika chunk zinashiriki size & category sawa).
  • Kwa allocations ndogo/kati, itatumia chunks za ukubwa thabiti; kwa kubwa/huge, inaweza map tofauti.

Chunks & Blocks

  • Chunk ni eneo (mara nyingi kurasa kadhaa) lililotengwa kwa allocations za size class moja ndani ya kundi.
  • Ndani ya chunk, blocks ni slots zinazopatikana kwa allocations. Blocks zilizofunguliwa zinadhibitiwa kupitia metadata slab — mf. kupitia bitmaps au free lists zilizohifadhiwa out-of-line.
  • Kati ya chunks (au ndani), guard slices / guard pages zinaweza kuingizwa (mf. unmapped slices) ili kugundua out-of-bounds writes.

Type / Type ID

  • Kila site ya allocation (au wito wa malloc, calloc, n.k.) inaambatanishwa na type identifier (malloc_type_id_t) ambayo inaweka aina ya object inayotengenezwa. Type ID hupelekwa kwa allocator, ambayo hutumia kuchagua zone / segment inayofaa.
  • Kwa hivyo, hata ikiwa allocations mbili zina ukubwa ule ule, zinaweza kwenda kwenye zones tofauti kabisa ikiwa types zao tofauti.
  • Katika toleo za mwanzo za iOS 17, APIs zote (mf. CFAllocator) hazikuwa za type-aware kabisa; Apple walitatua baadhi ya udhaifu huo katika iOS 18.

Allocation & Freeing Workflow

Hapa ni mtiririko wa juu jinsi allocation na deallocation zinavyofanya kazi katika xzone:

  1. malloc / calloc / realloc / typed alloc inaitwa na size na type ID.
  2. Allocator inatumia type ID kuchagua segment group / zone sahihi.
  3. Ndani ya zone/segment, inatafuta chunk ambayo ina free blocks za size iliyotakiwa.
  • Inaweza kushauriana na local caches / per-thread pools au free block lists kutoka metadata.
  • Ikiwa hakuna block ya bure, inaweza allocate chunk mpya katika zone hiyo.
  1. Metadata slab inasasishwa (free bit inafutwa, bookkeeping).
  2. Ikiwa memory tagging (EMTE) iko, block iliyorudishwa inapewa tag, na metadata inasasishwa kuonyesha hali yake “live”.
  3. Wakati free() inaitwa:
  • Block inatambulishwa kama imetolewa katika metadata (kupitia OOL slab).
  • Block inaweza kuwekwa kwenye free list au kupooliwa kwa matumizi tena.
  • Hiari, maudhui ya block yanaweza kufutwa au ku-poison ili kupunguza data leaks au exploitation ya use-after-free.
  • Hardware tag inayohusishwa na block inaweza kuvunjwa au kupewa tag mpya.
  • Ikiwa chunk nzima inakuwa bure (blocks zote zimetolewa), allocator inaweza reclaim chunk hiyo (ku-unmap au kurejesha kwa OS) chini ya shinikizo la kumbukumbu.

Security Features & Hardening

Hizi ni defenses zilizojengwa ndani ya xzone ya userland:

FeaturePurposeNotes
Metadata decouplingPrevent overflow from corrupting metadataMetadata lives in separate VM region (metadata slab)
Guard pages / unmapped slicesCatch out-of-bounds writesHelps detect buffer overflows rather than silently corrupting adjacent blocks
Type-based segregationPrevent cross-type reuse & type confusionEven same-size allocations from different types go to different zones
Memory Tagging (EMTE / MIE)Detect invalid access, stale references, OOB, UAFxzone works in concert with hardware EMTE in synchronous mode (“Memory Integrity Enforcement”)
Delayed reuse / poisoning / zapReduce chance of use-after-free exploitationFreed blocks may be poisoned, zeroed, or quarantined before reuse
Chunk reclamation / dynamic unmappingReduce memory waste and fragmentationEntire chunks may be unmapped when unused
Randomization / placement variationPrevent deterministic adjacencyBlocks in a chunk and chunk selection may have randomized aspects
Segregation of “data-only” allocationsSeparate allocations that don’t store pointersReduces attacker control over metadata or control fields

Interaction with Memory Integrity Enforcement (MIE / EMTE)

  • MIE (Memory Integrity Enforcement) ya Apple ni mfumo wa hardware + OS unaoleta Enhanced Memory Tagging Extension (EMTE) katika mode ya always-on, synchronous kwa maeneo makuu ya attack.
  • xzone allocator ni msingi muhimu wa MIE katika user space: allocations zinazofanywa kupitia xzone zinapewa tags, na accesses zinakaguliwa na hardware.
  • Kwenye MIE, allocator, ugawaji wa tag, usimamizi wa metadata, na enforcement ya usiri wa tag vimeunganishwa kuhakikisha kwamba makosa ya memory (mf. stale reads, OOB, UAF) yanagunduliwa mara moja, si kutumiwa baadaye.

Ikiwa ungependa, naweza pia kuzalisha cheat-sheet au mchoro wa xzone internals kwa kitabu chako. Unataka nifanye hivyo sasa? ::contentReference[oai:20]{index=20}


(Old) Physical Use-After-Free via IOSurface

ios Physical UAF - IOSurface


Ghidra Install BinDiff

Download BinDiff DMG kutoka https://www.zynamics.com/bindiff/manual na install it.

Open Ghidra with ghidraRun and go to File --> Install Extensions, press the add button and select the path /Applications/BinDiff/Extra/Ghidra/BinExport and click OK and isntall it even if there is a version mismatch.

Using BinDiff with Kernel versions

  1. Go to the page https://ipsw.me/ and download the iOS versions you want to diff. These will be .ipsw files.
  2. Decompress until you get the bin format of the kernelcache of both .ipsw files. You have information on how to do this on:

macOS Kernel Extensions & Kernelcache

  1. Open Ghidra with ghidraRun, create a new project and load the kernelcaches.
  2. Open each kernelcache so they are automatically analyzed by Ghidra.
  3. Then, on the project Window of Ghidra, right click each kernelcache, select Export, select format Binary BinExport (v2) for BinDiff and export them.
  4. Open BinDiff, create a new workspace and add a new diff indicating as primary file the kernelcache that contains the vulnerability and as secondary file the patched kernelcache.

Finding the right XNU version

If you want to check for vulnerabilities in a specific version of iOS, you can check which XNU release version the iOS version uses at [https://www.theiphonewiki.com/wiki/kernel]https://www.theiphonewiki.com/wiki/kernel).

For example, the versions 15.1 RC, 15.1 and 15.1.1 use the version Darwin Kernel Version 21.1.0: Wed Oct 13 19:14:48 PDT 2021; root:xnu-8019.43.1~1/RELEASE_ARM64_T8006.

iMessage/Media Parser Zero-Click Chains

Imessage Media Parser Zero Click Coreaudio Pac Bypass

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks