iOS Exploiting
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
iOS Exploit Mitigations
1. Code Signing / Runtime Signature Verification
Introduced early (iPhone OS → iOS) Hii ni moja ya ulinzi za msingi: maktaba zote zinazotekelezwa (apps, dynamic libraries, JIT-ed code, extensions, frameworks, caches) lazima zisainiwa kwa kihalisi na mnyororo wa cheti uliotokana na imani ya Apple. Wakati wa runtime, kabla ya kupakia binary kwenye memory (au kabla ya kufanya jumps kwenye mipaka fulani), mfumo unakagua saini yake. Ikiwa code imebadilishwa (bit-flipped, patched) au haisainwi, upakiaji unafa.
- Inazuia: hatua ya “classic payload drop + execute” katika mnyororo za exploit; injection ya arbitrary code; kubadilisha binary iliyopo ili kuweka mantiki ya kibaya.
- Maelezo ya utendaji:
- Mach-O loader (na dynamic linker) inakagua pages za code, segments, entitlements, team IDs, na kwamba saini inahusisha yaliyomo kwenye file.
- Kwa maeneo ya memory kama JIT caches au code inayotengenezwa dynamic, Apple inalazimisha kwamba pages zisainwe au zithibitishwe kupitia APIs maalum (mfano
mprotectwith code-sign checks). - Saini inajumuisha entitlements na identifiers; OS inafuatilia kwamba APIs fulani au uwezo wenye vibali maalum vinahitaji entitlements maalum ambazo haiwezi kuigizwa.
Example
Fikiria exploit inapata code execution katika process na inajaribu kuandika shellcode kwenye heap kisha kuruka kwa hiyo location. Kwenye iOS, page hiyo ingehitaji kuamriwa executable **na** kutimiza vigezo vya code-signature. Kwa kuwa shellcode haijasainiwa na cheti cha Apple, kuruka kunashindwa au mfumo unakataa kuifanya memory region hiyo iwe executable.2. CoreTrust
Introduced around iOS 14+ era (or gradually in newer devices / later iOS) CoreTrust ni subsystem inayofanya runtime signature validation ya binaries (ikiwa ni pamoja na system na user binaries) dhidi ya Apple’s root certificate badala ya kutegemea cached userland trust stores.
- Inazuia: kupotoshwa baada ya instal kama tampering ya binaries, mbinu za jailbreaking zinazojaribu kubadilisha au ku-patch system libraries au user apps; kudanganya mfumo kwa kubadilisha binaries za imani na zao zenye madhara.
- Maelezo ya utendaji:
- Badala ya kuamini database ya imani ya lokali au cache ya cheti, CoreTrust hupata au kurejea kwa root ya Apple moja kwa moja au kuthibitisha certificates kati katika chain iliyosimbwa.
- Inahakikisha kuwa mabadiliko (mfano kwenye filesystem) kwa binaries zilizopo yanagunduliwa na kukataliwa.
- Inafunga entitlements, team IDs, code signing flags, na metadata nyingine kwenye binary wakati wa load.
Example
Jailbreak inaweza kujaribu kubadilisha `SpringBoard` au `libsystem` na toleo lililopatchiwa ili kupata persistence. Lakini wakati loader ya OS au CoreTrust inakagua, inatambua mismatch ya saini (au entitlements zilizobadilishwa) na inakataa kuendesha.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 kuwa writable (kwa data) zisiwe executable, na pages zilizotajwa executable zisitokee writable. Huwezi kwa urahisi kuandika shellcode kwenye heap au stack kisha kuitekeleza.
- Inazuia: execution ya shellcode moja kwa moja; classic buffer-overflow → kuruka kwa injected shellcode.
- Maelezo ya utendaji:
- MMU / mgao wa upatikanaji wa memory (kwa page tables) inatekeleza utofauti huo.
- Jaribio lolote la kufanya writable page iwe executable kinasababisha ukaguzi wa mfumo (na linaamriwa kukanushwa au linahitaji idhini ya code-sign).
- Katika visa vingi, kufanya pages executable kunahitaji kupitia OS APIs ambazo zinatoa vigezo vya ziada au ukaguzi.
Example
Overflow inaandika shellcode kwenye heap. Mwizi anajaribu `mprotect(heap_addr, size, PROT_EXEC)` ili kuiifanya executable. Lakini mfumo unakataa au unathibitisha kwamba page mpya inapaswa kupitisha vigezo vya code-sign (ambazo shellcode haiwezi).4. Address Space Layout Randomization (ASLR)
Introduced in iOS ~4–5 era (roughly iOS 4–5 timeframe) ASLR inarandamiza addresses za msingi za maeneo muhimu ya memory: libraries, heap, stack, n.k., kila kuanzisha process. Addresses za gadgets zinabadilika kati ya runs.
- Inazuia: kuandika hardcoded addresses za gadgets kwa ROP/JOP; mnyororo thabiti za exploit; kuruka bila kujua offsets.
- Maelezo ya utendaji:
- Kila library iliyopakuliwa / module inayotumika inarebase kwa offset iliyoratibiwa.
- Stack na heap base pointers zinarandamizwa (ndani ya mipaka ya entropy).
- Wakati mwingine maeneo mengine (mfano mmap allocations) nayo yanarandamishwa.
- Ikitumika pamoja na information-leak mitigations, inamfanya mwizi aanze kwa kwanza kupata address au pointer ili kugundua base addresses wakati wa runtime.
Example
ROP chain inatarajia gadget kwenye `0x….lib + offset`. Lakini kwa kuwa `lib` imehamishwa tofauti kila run, mnyororo uliowekwa kwa nguvu haufanyi kazi. Exploit lazima kwanza i-lake 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 user ASLR, KASLR inarandamiza msingi wa kernel text na miundo mingine ya kernel wakati wa boot.
- Inazuia: kernel-level exploits zinazotegemea mahali thabiti pa kernel code au data; exploits za kernel zinazokaa thabiti.
- Maelezo ya utendaji:
- Kila boot, base address ya kernel inarandamizwa (ndani ya range).
- Miundo ya data ya kernel (kama
task_structs,vm_map, n.k.) pia zinaweza kuhamishwa au kuwekwa offsets. - Wachuuzi lazima kwanza waleke kernel pointers au kutumia vulnerabilities za information disclosure kupata offsets kabla ya kuharibu miundo ya kernel au code.
Example
Vulnerability ya local inalenga kubadilisha kernel function pointer (mfano katika `vtable`) kwenye `KERN_BASE + offset`. Lakini kwa kuwa `KERN_BASE` haijulikani, mwizi lazima awaleke kwanza (mfano kupitia read primitive) kabla ya kuhesabu address sahihi ya kukarabati.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 kuendelea uadilifu wa kernel text pages (kwa hash au checksum). Ikiwa inagundua tampering (patches, inline hooks, mabadiliko ya code) nje ya windows zinazokubalika, husababisha kernel panic au reboot.
- Inazuia: ku-patch kwa kudumu kwa kernel (kubadilisha maelekezo ya kernel), inline hooks, kuandika juu ya functions.
- Maelezo ya utendaji:
- Module ya hardware au firmware inafuatilia eneo la kernel text.
- Mara kwa mara au kwa ombi inaripia-hash pages na ikilinganisha na thamani zinazotarajiwa.
- Ikiwa mismatch inatokea nje ya windows za update zinazokubalika, inafanya panic (ili kuzuia patchi za kudumu).
- Wachuuzi lazima waweepuka madirisha ya ugunduzi au watumie njia halali za patch.
Example
Exploit inajaribu ku-patch prologue ya kernel function (mfano `memcmp`) ili kukamata simu. Lakini KPP inagundua kuwa page ya code haolingani na thamani inayotarajiwa na inasababisha kernel panic, ikiharibu kifaa kabla patch iweze kuimarika.7. Kernel Text Read‐Only Region (KTRR)
Introduced in modern SoCs (post ~A12 / newer hardware) KTRR ni mbinu inayotekelezwa kwa hardware: mara kernel text inafungwa mapema wakati wa boot, inakuwa read-only kutoka EL1 (kernel), ikizuia uandishi wa pages za code.
- Inazuia: mabadiliko yoyote ya kernel code baada ya boot (mfano patching, in-place code injection) kwa ngazi ya mamlaka EL1.
- Maelezo ya utendaji:
- Wakati wa boot (katika hatua ya secure/bootloader), memory controller (au unit ya hardware salama) inaweka physical pages zinazoshikilia kernel text kuwa read-only.
- Hata kama exploit inapata mamlaka kamili ya kernel, haiwezi kuandika kwenye pages hizo kubadilisha maelekezo.
- Ili kuziyumba, mwizi lazima kwanza apige boot chain, au aharibu KTRR yenyewe.
Example
Exploit ya privilege-escalation inaruka hadi EL1 na kuandika trampoline katika kernel function (mfano katika handler ya `syscall`). Lakini kwa sababu pages zimefungwa kuwa read-only na KTRR, uandishi unashindwa (au husababisha fault), hivyo patchi hazitumiki.8. Pointer Authentication Codes (PAC)
Introduced with ARMv8.3 (hardware), Apple beginning with A12 / iOS ~12+
- PAC ni kipengele cha hardware kilichowezeshwa katika ARMv8.3-A kugundua kuharibiwa kwa thamani za pointer (return addresses, function pointers, certain data pointers) kwa kuweka saini ndogo ya kriptografia (MAC) ndani ya bits za juu zisizotumika za pointer.
- Saini (“PAC”) inahesabiwa juu ya thamani ya pointer pamoja na modifier (thamani ya context, mfano stack pointer au data ya kutofautisha). Kwa hivyo pointer ile ile katika contexts tofauti itapata PAC tofauti.
- Wakati wa matumizi, kabla ya dereferencing au branching kupitia pointer hiyo, instruction ya authenticate inakagua PAC. Ikiwa halali, PAC inaondolewa na pointer halisi inapatikana; ikiwa si halali, pointer inakuwa “poisoned” (au fault inaibuka).
- Keys zinazotumiwa kuzalisha/kuthibitisha PAC zinaishi katika registers zilizo na mamlaka (EL1, kernel) na hazipatikani moja kwa moja kutoka user mode.
- Kwa sababu si bit zote 64 za pointer zinatumiwa katika mifumo mingi (mfano 48-bit address space), bits za juu ni “spare” na zinaweza kushikilia PAC bila kubadilisha address inayofaa.
Architectural Basis & Key Types
-
ARMv8.3 inatambulisha vifunguo vitano vya 128-bit (kila kimojawapo kimefanywa kwa registers 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 jumla
-
Vifunguo hivi vinahifadhiwa katika privileged system registers (zinazopatikana tu kwa EL1/EL2 n.k.), haipatikani kutoka user mode.
-
PAC inahesabiwa kwa kutumia kazi ya kriptografia (ARM inapendekeza QARMA kama algorithm) kwa:
- Thamani ya pointer (sehemu ya canonical)
- modifier (thamani ya context, kama salt)
- secret key
- mchanganyiko wa ndani Ikiwa PAC inayotokana inalingana na ile iliyo kwenye bits za juu za pointer, authentication inafanikiwa.
Instruction Families
Kanuni ya majina ni: PAC / AUT / XPAC, kisha herufi za domain.
PACxxinstructions huweka saini kwenye pointer na kuingiza PACAUTxxinstructions huthibitisha + kuondoa (validate na kuondoa PAC)XPACxxinstructions huondoa bila kuthibitisha
Domains / suffixes:
| Mnemonic | Meaning / Domain | Key / Domain | Example Usage in Assembly |
|---|---|---|---|
| PACIA | Sign instruction pointer with APIAKey | “I, A” | PACIA X0, X1 — sign pointer in X0 using APIAKey with modifier X1 |
| PACIB | Sign instruction pointer with APIBKey | “I, B” | PACIB X2, X3 |
| PACDA | Sign data pointer with APDAKey | “D, A” | PACDA X4, X5 |
| PACDB | Sign data pointer with APDBKey | “D, B” | PACDB X6, X7 |
| PACG / PACGA | Generic (non-pointer) signing with APGAKey | “G” | PACGA X8, X9, X10 (sign X9 with modifier X10 into X8) |
| AUTIA | Authenticate APIA-signed instruction pointer & strip PAC | “I, A” | AUTIA X0, X1 — check PAC on X0 using modifier X1, then strip |
| AUTIB | Authenticate APIB domain | “I, B” | AUTIB X2, X3 |
| AUTDA | Authenticate APDA-signed data pointer | “D, A” | AUTDA X4, X5 |
| AUTDB | Authenticate APDB-signed data pointer | “D, B” | AUTDB X6, X7 |
| AUTGA | Authenticate generic / blob (APGA) | “G” | AUTGA X8, X9, X10 (validate generic) |
| XPACI | Strip PAC (instruction pointer, no validation) | “I” | XPACI X0 — remove PAC from X0 (instruction domain) |
| XPACD | Strip PAC (data pointer, no validation) | “D” | XPACD X4 — remove PAC from data pointer in X4 |
There are specialized / alias forms:
PACIASPis shorthand forPACIA X30, SP(sign the link register using SP as modifier)AUTIASPisAUTIA X30, SP(authenticate link register with SP)- Combined forms like
RETAA,RETAB(authenticate-and-return) orBLRAA(authenticate & branch) exist in ARM extensions / compiler support. - Also zero-modifier variants:
PACIZA/PACIZBwhere the modifier is implicitly zero, etc.
Modifiers
Lengo kuu la modifier ni kuunga PAC kwenye context maalum ili address ile ile iliyosainiwa katika contexts tofauti itolewe PAC tofauti. Ni kama kuongeza salt kwenye hash.
Kwa hivyo:
- modifier ni thamani ya context (register nyingine) inayochanganywa katika hesabu 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 inakuwa imefungwa kwa frame maalum ya stack. Ikiwa unajaribu kutumia LR katika frame tofauti, modifier hubadilika, hivyo uthibitisho wa PAC unashindwa.
- Thamani ile ile ya pointer inayosainiwa chini ya modifiers tofauti hutoa PAC tofauti.
- modifier haipaswi kuwa siri, lakini bora isiwekwe chini ya udhibiti wa mwizi.
- Kwa instructions zinazofanya sign au verify pointers ambapo hakuna modifier muhimu, baadhi ya maumbo hutumia zero au constant iliyofichwa.
Apple / iOS / XNU Customizations & Observations
- Utekelezaji wa PAC wa Apple unajumuisha per-boot diversifiers ili keys au tweaks zibadilike kila boot, kuzuia matumizi tena kati ya boots.
- Pia wana cross-domain mitigations ili PAC iliyosainiwa katika user mode isiweze kutumiwa kwa urahisi katika kernel mode, n.k.
- Kwa Apple M1 / Apple Silicon, reverse engineering ilionyesha kuwa kuna aina tisa za modifier na system registers za Apple kwa udhibiti wa key.
- Apple inatumia PAC katika subsystems nyingi za kernel: return address signing, integrity ya pointers katika kernel data, signed thread contexts, n.k.
- Google Project Zero ilionyesha jinsi chini ya primitive nguvu ya memory read/write katika kernel, mtu angeweza kuunda upya kernel PACs (kwa A keys) kwenye vifaa vya A12-era, lakini Apple ilirekebisha njia nyingi za hilo.
- Katika mfumo wa Apple, baadhi ya keys ni global kwa kernel, wakati process za user zinaweza kupata randomness ya key kwa kila process.
PAC Bypasses
- Kernel-mode PAC: theoretical vs real bypasses
- Kwa kuwa keys za kernel PAC na mantiki zina udhibiti mkali (privileged registers, diversifiers, isolation ya domain), kukuza pointers zilizosasishwa za kernel ni ngumu sana.
- Azad’s 2020 “iOS Kernel PAC, One Year Later” inaripoti kuwa katika iOS 12-13, aligundua baadhi ya bypasses za sehemu (signing gadgets, reuse ya signed states, indirect branches zisizoalindwa) lakini hakuna bypass kamili ya jumla. bazad.github.io
- Apple’s “Dark Magic” customizations zinapunguza zaidi uso wa kukumbwa (domain switching, per-key enabling bits). i.blackhat.com
- Kuna CVE iliyojulikana 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 implemention; sio njia za jumla.
Hivyo kernel PAC inaonekana kuwa thabiti sana, ingawa sio kamili.
- User-mode / runtime PAC bypass techniques
Hizi ni za kawaida zaidi, na zinaonyesha dosari katika jinsi PAC inatumiwa au kutumika 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 pre-linked ya system frameworks na libraries. Kwa sababu inashirikiwa sana, function pointers ndani ya shared cache zimekuwa “pre-signed” kisha kutumika na processes nyingi. Wachuuzi walenga pointers hizi tayari-zisizo-sahihi kama “PAC oracles”.
-
Mbinu fulani za bypass hujaribu kutoa au kutumia pointers zilizosasishwa za A-key zilizopo katika shared cache na kuzitumia katika gadgets.
-
Hotuba “No Clicks Required” inaelezea kujenga oracle juu ya shared cache ili kubaini addresses za comparative na kuziunganisha na pointers zilizosasishwa ili kupita PAC. saelo.github.io
-
Pia, imports za function pointers kutoka shared libraries katika userspace ziligundulika kuwa hazijalindwa vya kutosha na PAC, kuruhusu mwizi kupata function pointers bila kubadilisha saini zao. (Project Zero bug entry) bugs.chromium.org
2.2 dlsym(3) / dynamic symbol resolution
-
Mojawapo ya bypass inayojulikana ni kuita
dlsym()kupata function pointer ambayo tayari imesasishwa (ilisainiwa na A-key, diversifier zero) kisha kuitumia. Kwa kuwadlsyminarudisha pointer inayosainiwa halali, kuitumia kunavunja haja ya kuunda PAC bandia. -
Blog ya Epsilon inaelezea jinsi baadhi ya bypasses zinatumia hili: kuita
dlsym("someSym")hurudisha pointer iliyosasishwa na inaweza kutumika kwa indirect calls. blog.epsilon-sec.com -
Synacktiv’s “iOS 18.4 — dlsym considered harmful” inaelezea bug: baadhi ya symbols zilizorekebishwa kupitia
dlsymkwenye iOS 18.4 hurudisha pointers ambazo zimesainiwa vibaya (au zikiwa na diversifiers yenye mdudu), kutoa nafasi ya kupitisha PAC bila kutarajiwa. Synacktiv -
Mantiki ya dyld kwa dlsym ni pamoja na: wakati
result->isCode, wanayasaini pointer iliyorejeshwa na__builtin_ptrauth_sign_unauthenticated(..., key_asia, 0), yaani context zero. blog.epsilon-sec.com
Kwa hivyo, dlsym mara nyingi ni vector katika bypass za user-mode PAC.
2.3 Other DYLD / runtime relocations
-
Loader ya DYLD na mantiki ya dynamic relocation ni tata na wakati mwingine inachukua pages kuwa read/write kwa muda ili kufanya relocations, kisha kuzirudisha read-only. Wachuuzi wanatumia madirisha haya. Hotuba za Synacktiv zinaelezea “Operation Triangulation”, bypass ya PAC inayotegemea timing kupitia dynamic relocations. Synacktiv
-
Pages za DYLD sasa zinahifadhiwa na SPRR / VM_FLAGS_TPRO (bendera za ulinzi kwa dyld). Lakini matoleo ya awali yaliwa na ulinzi dhaifu. Synacktiv
-
Katika mnyororo za exploit za WebKit, DYLD loader mara nyingi huwa lengo la bypass ya PAC. Slides zinataja kuwa bypass nyingi za PAC zimewalenga DYLD loader (kupitia relocation, interposer hooks). Synacktiv
2.4 NSPredicate / NSExpression / ObjC / SLOP
-
Katika mnyororo za userland, runtime methods za Objective-C kama
NSPredicate,NSExpressionauNSInvocationzinatumika kusafirisha simu za udhibiti bila kuonekana wazi kwa uundaji wa pointer bandia. -
Kwenye iOS za zamani (kabla ya PAC), exploit ilitumia fake NSInvocation objects kuita selectors yoyote kwenye memory iliyodhibitiwa. Kwa PAC, mbinu hizi zilihitaji marekebisho. Lakini tekniki SLOP (SeLector Oriented Programming) ilipanuliwa chini ya PAC pia. Project Zero
-
Mbinu ya asili ya SLOP iliruhusu kuunganisha simu za ObjC kwa kuunda invocations bandia; bypass inategemea kwamba ISA au selector pointers wakati mwingine hazilindwa kikamilifu na PAC. Project Zero
-
Katika mazingira ambapo pointer authentication inatumika kwa sehemu, methods / selectors / target pointers huenda si kila wakati zinalindwa na PAC, kuacha nafasi ya bypass.
Example Flow
Example 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 hubadilisha anwani ya kurudi kwenye stack. Mshambuliaji anaandika anwani ya gadget lengwa lakini hawezi kuhesabu PAC sahihi. Wakati function inarudisha, `AUTIA` ya CPU inatoa kosa kwa sababu ya kutolingana kwa PAC. Mnyororo unashindwa.
Uchambuzi wa Project Zero juu ya A12 (iPhone XS) ulibainisha jinsi Apple inavyotumia PAC na mbinu za kutengeneza PAC ikiwa mshambuliaji ana primitive ya kusoma/kuandika kumbukumbu.
</details>
### 9. **Branch Target Identification (BTI)**
**Introduced with ARMv8.5 (later hardware)**
BTI ni kipengele cha vifaa kinachokagua **indirect branch targets**: wakati wa kutekeleza `blr` au call/jump zisizo za moja kwa moja, lengwa lazima ianzie na **BTI landing pad** (`BTI j` au `BTI c`). Kuruka ndani ya anwani za gadget ambazo hazina landing pad husababisha exception.
Utekelezaji wa LLVM unaeleza aina tatu za maagizo ya BTI na jinsi zinavyolingana na aina za matawi.
| 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 zinaingiza maagizo ya BTI (C, J, au JC) katika kila indirect-branch target halali (kuanza kwa functions au blocks zinazofikiwa kwa jumps) ili indirect branches zifaulu tu kwa maeneo hayo.
- **Direct branches / calls** (yaani anwani imara `B`, `BL`) hazina vizuizi vya BTI. Dhana ni kwamba kurasa za code zinatambulika kama za kuaminika na mshambuliaji hawezi kuzibadilisha (hivyo direct branches ni salama).
- Pia, maagizo ya **RET / return** kwa ujumla hayazuiliwi na BTI kwa sababu anwani za kurudi zinalindwa kwa PAC au mechanisms za return signing.
#### Mechanism and enforcement
- Wakati CPU inakayakamilisha decode ya **indirect branch (BLR / BR)** kwenye ukurasa uliotajwa kama “guarded / BTI-enabled,” inakagua kama instruction ya kwanza kwenye anwani ya lengwa ni BTI halali (C, J, au JC kama inaruhusiwa). Ikiwa si hivyo, hutokea **Branch Target Exception**.
- Ufadhili wa encoding wa maagizo ya BTI umeundwa kutumia tena opcodes zilizohifadhiwa awali kwa NOPs (katika toleo la ARM la awali). Hivyo binaries zilizo na BTI zinaletwa nyuma ya compatibility: kwenye hardware bila BTI maagizo hayo hufanya kazi kama NOPs.
- Compiler passes zinazoongeza BTIs huviingiza tu pale panapohitajika: 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 kwamba BTI haingiziwi kwa *blocks* zote — ni zile tu ambazo zinaweza kuwa branch targets (mfano kutoka switch / jump tables).
#### BTI + PAC synergy
PAC inalinda thamani ya pointer (chanzo) — inahakikisha mnyororo wa indirect calls / returns haujaingiliwa.
BTI inahakikisha kwamba hata pointer halali lazima ilenge entry points zilizoelezwa ipasavyo.
Kwa pamoja, mshambuliaji anahitaji pointer halali iliyo na PAC sahihi na pia lengwa lazima liwe na BTI kuwekwa hapo. Hii inafanya kukusanya gadgets za exploit kuwa ngumu zaidi.
#### Example
<details>
<summary>Example</summary>
Exploit inajaribu kupindisha hadi gadget kwa `0xABCDEF` ambayo haianzi na `BTI c`. CPU, baada ya kutekeleza `blr x0`, inakagua lengwa na inatoa kosa kwa sababu imaelekezo ya kwanza haijumuishi landing pad halali. Hivyo gadgets nyingi zinakuwa hazitumiki isipokuwa zina 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** kinachozuia **code yenye nafasi ya juu** (EL1 au EL2) kutoka **kusoma au kuandika** kumbukumbu iliyotajwa kama inayoonekana kwa user (EL0), isipokuwa PAN imezimwa wazi.
- Dhana ni: hata kama kernel imegandishwa au kuibiwa, haiwezi kwa urahisi kurejelea pointers za user-space bila kwanza *kuzima* PAN, hivyo kupunguza hatari za exploits za aina ya **`ret2usr`** au matumizi mabaya ya buffers zinazosimamiwa na user.
- Wakati PAN imewezeshwa (PSTATE.PAN = 1), maagizo yoyote ya privileged load/store yanayofikia anwani za virtual zilizotajwa kama “accessible at EL0” hutasababisha **permission fault**.
- Kernel, wakati inapotakiwa kwa uhalali kufikia kumbukumbu ya user (mfano ku-copy data kwenda/kutoka user buffers), lazima **kwa muda ifanye disable PAN** (au itumie maagizo ya “unprivileged load/store”) ili kuruhusu upatikanaji huo.
- Katika Linux on ARM64, msaada wa PAN uliletwa takriban 2015: patches za kernel ziliongeza utambuzi wa kipengele hicho, na kubadilisha `get_user` / `put_user` n.k. kwa aina zilizofunga PAN wakati wa ufikiaji wa kumbukumbu za user.
**Key nuance / limitation / bug**
- Kama ilivyotajwa na Siguza na wengine, mdogo wa spec (au tabia isiyo wazi) katika muundo wa ARM inamaanisha kwamba **execute-only user mappings** (`--x`) huenda **zisisababisha PAN**. Kwa maneno mengine, ikiwa ukurasa wa user umepangwa kuwa executable tu bila ruhusa ya kusoma, jaribio la kernel kusoma linaweza kupita PAN kwa sababu architecture inachukulia “accessible at EL0” inahitaji ruhusa ya kusoma, sio tu executable. Hii inasababisha bypass ya PAN katika usanidi fulani.
- Kwa sababu hiyo, ikiwa iOS / XNU inaruhusu pages za user kuwa execute-only (kama baadhi ya JIT au code-cache setups zinavyoweza kufanya), kernel inaweza kwa bahati mbaya kusoma kutoka kwao hata PAN ikiwa imewezeshwa. Hii ni eneo wazo kwa utata linalojulikana kwenye baadhi ya mifumo ya ARMv8+.
#### PXN (Privileged eXecute Never)
- **PXN** ni bit ya page table (kwingine katika page table entries, leaf au block entries) inayoashiria kuwa ukurasa hauwezi kutekelezeka wakati wa mtiririko wa kipengele cha juu (yaani wakati EL1 inatekeleza).
- PXN inazuia kernel (au code yoyote ya privileged) kutoka kuruka au kutekeleza maagizo kutoka kwenye pages za user hata kama udhibiti umebadilishwa. Kwa kufanya hivyo, inazuia redirection ya control-flow ya kiwango cha kernel kwenda kwenye memory ya user.
- Kwa pamoja na PAN, hii inahakikisha:
1. Kernel haiwezi (kwa default) kusoma au kuandika data ya user-space (PAN)
2. Kernel haiwezi kutekeleza code ya user-space (PXN)
- Kwenye format ya page table ya ARMv8, entries za leaf zina bit ya `PXN` (na pia `UXN` kwa unprivileged execute-never) katika bits za sifa.
Hivyo hata ikiwa kernel ina function pointer iliyoharibika ikielekezwa kwenye memory ya user, na ikajaribu kuruka huko, bit ya PXN itasababisha fault.
#### Memory-permission model & how PAN and PXN map to page table bits
Kuelewa jinsi PAN / PXN zinavyofanya kazi, unahitaji kuona jinsi translation na modeli ya ruhusa ya ARM inavyofanya kazi (imefupishwa):
- Kila page au block entry ina fields za sifa zikiwemo **AP[2:1]** kwa access permissions (read/write, privileged vs unprivileged) na bits za **UXN / PXN** kwa restrictions za execute-never.
- Wakati PSTATE.PAN ni 1 (imewezeshwa), hardware inatekeleza semantics zilizorekebishwa: upatikanaji wa privileged kwenye pages zilizotajwa kama “accessible by EL0” (yaani user-accessible) unazuiwa (fault).
- Kwa sababu ya mdogo wa spec uliotajwa, pages ambazo zimewekwa kuwa execute-only (bila ruhusa ya kusoma) huenda zisihesabiwe kama “accessible by EL0” chini ya utekelezaji fulani, hivyo kupitisha PAN.
- Wakati PXN ya ukurasa imewekwa, hata kama fetch ya instruction inatoka kwa privilege ya juu, utekelezaji unakatazwa.
#### Kernel usage of PAN / PXN in a hardened OS (e.g. iOS / XNU)
Katika muundo wa kernel ulioimarishwa (kama vile Apple inaweza kutumia):
- Kernel inawasha PAN kwa default (hivyo code ya privileged imecapped).
- Katika njia ambazo zinahitaji kwa uhalali kusoma au kuandika buffers za user (mfano syscall buffer copy, I/O, read/write user pointer), kernel kwa muda **huuzima PAN** au hutumia maagizo maalumu kupitisha kibali.
- Baada ya kumaliza ufikiaji wa data za user, lazima iwashe PAN tena.
- PXN inatekelezwa kupitia page tables: pages za user zina PXN = 1 (hivyo kernel haiwezi kuzitekeleza), pages za kernel hazina PXN (hivyo code ya kernel inaweza kutekelezwa).
- Kernel lazima ihakikishe kuwa hakuna njia za code zinazosababisha flow ya utekelezaji kuingia katika maeneo ya memory ya user (ambayo ingeruhusu kuepuka PXN) — hivyo mnyororo za exploit zinazotegemea “kuruka hadi shellcode inayodhibitiwa na user” zinazuiliwa.
Kwa sababu ya bypass ya PAN kupitia execute-only pages, katika mfumo halisi, Apple inaweza kuzima au kushindwa kuruhusu pages za user kuwa execute-only, au kufunika mdogo wa specification.
#### Attack surfaces, bypasses, and mitigations
- **PAN bypass via execute-only pages**: kama ilivyotajwa, spec ina pengo: pages za user zenye execute-only (bila ruhusa ya kusoma) zinaweza kutokuwa “accessible at EL0,” hivyo PAN haitazuia kernel kusoma kutoka kwa pages hizo katika utekelezaji fulani. Hii inampa mshambuliaji njia isiyo ya kawaida ya kupeleka data kupitia sehemu za “execute-only”.
- **Temporal window exploit**: ikiwa kernel inaizima PAN kwa dirisha lenye muda mrefu kuliko linavyohitajika, race au njia mbaya inaweza kutumia nafasi hiyo kufanya ufikiaji usiohitajika wa kumbukumbu za user.
- **Forgotten re-enable**: ikiwa njia za code zisiharibu waliacha kuirudisha PAN, operesheni za baadaye za kernel zinaweza kufanya ufikiaji wa kumbukumbu za user isivyofaa.
- **Misconfiguration of PXN**: kama page tables hazitegesi PXN kwenye pages za user au zikimpa mapping isiyo sahihi, kernel inaweza kudanganywa kuruka kwenye code ya user-space.
- **Speculation / side-channels**: kama ilivyo kwa bypass za speculative, kunaweza kuwa na athari za microarchitectural zinazosababisha ukiukwaji wa muda mfupi wa PAN / PXN checks (hata hivyo mashambulizi kama hayo yanategemea sana muundo wa CPU).
- **Complex interactions**: Katika vipengele vya juu zaidi (mfano JIT, shared memory, maeneo ya code ya just-in-time), kernel huhitaji udhibiti mzuri kuruhusu ufikiaji fulani wa memory au utekelezaji katika maeneo yaliyopangwa na user; kubuni hayo salama chini ya vikwazo vya PAN/PXN si jambo rahisi.
#### Example
<details>
<summary>Code Example</summary>
Hapa kuna mifano ya pseudo-assembly inayoonyesha kuwasha/kuzima PAN karibu na ufikiaji wa memory ya user, na jinsi fault inaweza kutokea.
</details>
// 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>Example</summary>
A kernel vulnerability tries to take a user-provided function pointer and call it in kernel context (i.e. `call user_buffer`). Under PAN/PXN, that operation is disallowed or faults.
</details>
---
### 11. **Top Byte Ignore (TBI) / Pointer Tagging**
**Introduced in ARMv8.5 / newer (or optional extension)**
TBI means the top byte (most-significant byte) of a 64-bit pointer is ignored by address translation. This lets OS or hardware embed **tag bits** in the pointer’s top byte without affecting the actual address.
- TBI stands for **Top Byte Ignore** (sometimes called *Address Tagging*). It is a hardware feature (available in many ARMv8+ implementations) that **ignores the top 8 bits** (bits 63:56) of a 64-bit pointer when performing **address translation / load/store / instruction fetch**.
- In effect, the CPU treats a pointer `0xTTxxxx_xxxx_xxxx` (where `TT` = top byte) as `0x00xxxx_xxxx_xxxx` for the purposes of address translation, ignoring (masking off) the top byte. The top byte can be used by software to store **metadata / tag bits**.
- This gives software “free” in-band space to embed a byte of tag in each pointer without altering which memory location it refers to.
- The architecture ensures that loads, stores, and instruction fetch treat the pointer with its top byte masked (i.e. tag stripped off) before performing the actual memory access.
Thus TBI decouples the **logical pointer** (pointer + tag) from the **physical address** used for memory operations.
#### Why TBI: Use cases and motivation
- **Pointer tagging / metadata**: You can store extra metadata (e.g. object type, version, bounds, integrity tags) in that top byte. When you later use the pointer, the tag is ignored at hardware level, so you don’t need to strip manually for the memory access.
- **Memory tagging / MTE (Memory Tagging Extension)**: TBI is the base hardware mechanism that MTE builds on. In ARMv8.5, the **Memory Tagging Extension** uses bits 59:56 of the pointer as a **logical tag** and checks it against an **allocation tag** stored in memory.
- **Enhanced security & integrity**: By combining TBI with pointer authentication (PAC) or runtime checks, you can force not just the pointer value but also the tag to be correct. An attacker overwriting a pointer without the correct tag will produce a mismatched tag.
- **Compatibility**: Because TBI is optional and tag bits are ignored by hardware, existing untagged code continues to operate normally. The tag bits effectively become “don’t care” bits for legacy code.
#### Example
<details>
<summary>Example</summary>
A function pointer included a tag in its top byte (say `0xAA`). An exploit overwrites the pointer low bits but neglects the tag, so when the kernel verifies or sanitizes, the pointer fails or is rejected.
</details>
---
### 12. **Page Protection Layer (PPL)**
**Introduced in late iOS / modern hardware (iOS ~17 / Apple silicon / high-end models)** (some reports show PPL circa macOS / Apple silicon, but Apple is bringing analogous protections to iOS)
- PPL is designed as an **intra-kernel protection boundary**: even if the kernel (EL1) is compromised and has read/write capabilities, **it should not be able to freely modify** certain **sensitive pages** (especially page tables, code-signing metadata, kernel code pages, entitlements, trust caches, etc.).
- It effectively creates a **“kernel within the kernel”** — a smaller trusted component (PPL) with **elevated privileges** that alone can modify protected pages. Other kernel code must call into PPL routines to effect changes.
- This reduces the attack surface for kernel exploits: even with full arbitrary R/W/execute in kernel mode, exploit code must also somehow get into the PPL domain (or bypass PPL) to modify critical structures.
- On newer Apple silicon (A15+ / M2+), Apple is transitioning to **SPTM (Secure Page Table Monitor)**, which in many cases replaces PPL for page-table protection on those platforms.
Here’s how PPL is believed to operate, based on public analysis:
#### Use of APRR / permission routing (APRR = Access Permission ReRouting)
- Apple hardware uses a mechanism called **APRR (Access Permission ReRouting)**, which allows page table entries (PTEs) to contain small indices, rather than full permission bits. Those indices are mapped via APRR registers to actual permissions. This allows dynamic remapping of permissions per domain.
- PPL leverages APRR to segregate privilege within kernel context: only the PPL domain is permitted to update the mapping between indices and effective permissions. That is, when non-PPL kernel code writes a PTE or tries to flip permission bits, the APRR logic disallows it (or enforces read-only mapping).
- PPL code itself runs in a restricted region (e.g. `__PPLTEXT`) which is normally non-executable or non-writable until entry gates temporarily allow it. The kernel calls PPL entry points (“PPL routines”) to perform sensitive operations.
#### Gate / Entry & Exit
- When the kernel needs to modify a protected page (e.g. change permissions of a kernel code page, or modify page tables), it calls into a **PPL wrapper** routine, which does validation and then transitions into the PPL domain. Outside that domain, the protected pages are effectively read-only or non-modifiable by the main kernel.
- During PPL entry, the APRR mappings are adjusted so that memory pages in the PPL region are set to **executable & writable** within PPL. Upon exit, they are returned to read-only / non-writable. This ensures that only well-audited PPL routines can write to protected pages.
- Outside PPL, attempts by kernel code to write to those protected pages will fault (permission denied) because the APRR mapping for that code domain doesn’t permit writing.
#### Protected page categories
The pages that PPL typically protects include:
- Page table structures (translation table entries, mapping metadata)
- Kernel code pages, especially those containing critical logic
- Code-sign metadata (trust caches, signature blobs)
- Entitlement tables, signature enforcement tables
- Other high-value kernel structures where a patch would allow bypassing signature checks or credentials manipulation
The idea is that even if the kernel memory is fully controlled, the attacker cannot simply patch or rewrite these pages, unless they also compromise PPL routines or bypass PPL.
#### Known Bypasses & Vulnerabilities
1. **Project Zero’s PPL bypass (stale TLB trick)**
- A public writeup by Project Zero describes a bypass involving **stale TLB entries**.
- The idea:
1. Allocate two physical pages A and B, mark them as PPL pages (so they are protected).
2. Map two virtual addresses P and Q whose L3 translation table pages come from A and B.
3. Spin a thread to continuously access Q, keeping its TLB entry alive.
4. Call `pmap_remove_options()` to remove mappings starting at P; due to a bug, the code mistakenly removes the TTEs for both P and Q, but only invalidates the TLB entry for P, leaving Q’s stale entry live.
5. Reuse B (page Q’s table) to map arbitrary memory (e.g. PPL-protected pages). Because the stale TLB entry still maps Q’s old mapping, that mapping remains valid for that context.
6. Through this, the attacker can put writable mapping of PPL-protected pages in place without going through PPL interface.
- This exploit required fine control of physical mapping and TLB behavior. It demonstrates that a security boundary relying on TLB / mapping correctness must be extremely careful about TLB invalidations and mapping consistency.
- Project Zero commented that bypasses like this are subtle and rare, but possible in complex systems. Still, they regard PPL as a solid mitigation.
2. **Other potential hazards & constraints**
- If a kernel exploit can directly enter PPL routines (via calling the PPL wrappers), it might bypass restrictions. Thus argument validation is critical.
- Bugs in the PPL code itself (e.g. arithmetic overflow, boundary checks) can allow out-of-bounds modifications inside PPL. Project Zero observed that such a bug in `pmap_remove_options_internal()` was exploited in their bypass.
- The PPL boundary is irrevocably tied to hardware enforcement (APRR, memory controller), so it's only as strong as the hardware implementation.
#### Example
<details>
<summary>Code Example</summary>
Here’s a simplified pseudocode / logic showing how a kernel might call into PPL to modify protected pages:
```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 / Replacements / Future
- 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:
- 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).
- 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.
- 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.
- 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.
- 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.
- 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>
#### Mipaka & changamoto
- **Intrablock overflows**: Ikiwa overflow inabaki ndani ya allocation hiyo hiyo (haivuki boundary) na tag inabaki ileile, tag mismatch hautaikamata.
- **Tag width limitation**: Bit chache tu (mfano 4 bits, au domain ndogo) zinapatikana kwa tag — namespace ni ndogo.
- **Side-channel leaks**: Ikiwa tag bits zinaweza kuwa leaked (kupitia cache / speculative execution), mshambuliaji anaweza kujifunza tags sahihi na kupitisha ulinzi. Apple’s tag confidentiality enforcement inalenga kupunguza hili.
- **Performance overhead**: Ukaguzi wa tag kila load/store unaongeza gharama; Apple lazima iboreshe hardware ili kupunguza overhead.
- **Compatibility & fallback**: Kwenye hardware ya zamani au sehemu zisizounga mkono EMTE, lazima kuwe na fallback. Apple inadai MIE inawezeshwa tu kwenye vifaa vinavyounga mkono.
- **Complex allocator logic**: Allocator inapaswa kusimamia tags, retagging, kuoanisha mipaka, na kuzuia mis-tag collisions. Mbugu katika mantiki ya allocator yanaweza kuleta udhaifu.
- **Mixed memory / hybrid areas**: Sehemu za memory zinaweza kubaki untagged (legacy), na kufanya interoperability kuwa ngumu.
- **Speculative / transient attacks**: Kama ilivyo kwa ulinzi mwingi wa microarchitectural, speculative execution au micro-op fusions zinaweza kuvuka ukaguzi kwa muda mfupi au ku-leak tag bits.
- **Limited to supported regions**: Apple inaweza kutekeleza EMTE tu katika maeneo maalum yaliyo hatarini (kernel, security-critical subsystems), si kote.
---
## Maboresho muhimu / tofauti ikilinganishwa na MTE ya kawaida
Haya ni maboresho na mabadiliko Apple anayasisitiza:
| Sifa | Original MTE | EMTE (Apple’s enhanced) / MIE |
|---|---|---|
| **Check mode** | Inaunga mkono synchronous na asynchronous modes. Katika async, tag mismatches taarifa hutolewa baadaye (delayed) | Apple inasisitiza **synchronous mode** kwa default—tag mismatches zinakamatwa mara moja, hakuna dirisha la kuchelewa/race. |
| **Coverage of non-tagged memory** | Accesses kwa non-tagged memory (mfano globals) zinaweza kupitisha checks katika baadhi ya utekelezaji | EMTE inahitaji kwamba accesses kutoka eneo lenye tag kwenda non-tagged memory pia zithibitishe uelewa wa tag, kufanya iwe ngumu kupitisha kwa kuchanganya allocations. |
| **Tag confidentiality / secrecy** | Tags zinaweza kuonekana au kuwa leaked kupitia side channels | Apple inaongeza **Tag Confidentiality Enforcement**, ambayo inajaribu kuzuia kuvuja kwa tag values (kupitia speculative side-channels n.k.). |
| **Allocator integration & retagging** | MTE inaacha sehemu kubwa ya mantiki ya allocator kwa software | Secure typed allocators za Apple (kalloc_type, xzone malloc, n.k.) zinashirikiana na EMTE: wakati memory inapotengwa au kuachiliwa, tags zinadhibitiwa kwa granulariti nzuri. |
| **Always-on by default** | Kwenye platform nyingi, MTE ni hiari au imezimwa kwa default | Apple inawasha EMTE / MIE kwa default kwenye hardware inayounga mkono (mfano iPhone 17 / A19) kwa kernel na mchakato wengi wa user-space. |
Kwa kuwa Apple inasimamia hardware na software stack yote, inaweza kutekeleza EMTE kwa ukali, kuepuka matatizo ya performance, na kufunga njia za side-channel.
---
## Jinsi EMTE inavyofanya kazi kwa vitendo (Apple / MIE)
Hapa kuna maelezo ya juu-level jinsi EMTE inavyofanya kazi chini ya MIE ya Apple:
1. **Tag assignment**
- Wakati memory inapotengwa (mfano ndani ya kernel au user space kupitia secure allocators), **secret tag** inatolewa kwa block hiyo.
- Pointer inayorudishwa kwa user au kernel ina tag hiyo katika high bits (ikitumia TBI / top byte ignore mechanisms).
2. **Tag checking on access**
- Kila mara load au store inapotekelezwa kwa pointer, hardware inakagua kwamba tag ya pointer inaendana na tag ya block ya memory (allocation tag). Ikiwa inatofautiana, inatoa fault mara moja (kwa kuwa synchronous).
- Kwa sababu ni synchronous, hakuna dirisha la “delayed detection”.
3. **Retagging on free / reuse**
- Wakati memory inarejeshwa (free), allocator hubadilisha tag ya block (hivyo pointers za zamani zenye tag za zamani hazitafanana tena).
- Use-after-free pointer itakuwa na stale tag na itasababisha mismatch wakati inatumiwa.
4. **Neighbor-tag differentiation to catch overflows**
- Allocations jirani zinapewa tags tofauti. Ikiwa buffer overflow inavuka na kuingia ndani ya memory ya jirani, tag mismatch itasababisha fault.
- Hii ni yenye nguvu hasa katika kukamata overflows ndogo ambazo zinavuka boundary.
5. **Tag confidentiality enforcement**
- Apple lazima apewe kinga dhidi ya kuvuja kwa tag values (kwa kuwa kama mshambuliaji atajua tag, anaweza kutengeneza pointers zenye tags sahihi).
- Wanajumuisha ulinzi (microarchitectural / speculative controls) ili kuepuka kuvuja kwa tag bits.
6. **Kernel and user-space integration**
- Apple inatumia EMTE si tu katika user-space bali pia ndani ya kernel / vipengele muhimu vya OS (kukuza kinga dhidi ya memory corruption ya kernel).
- Hardware/OS inahakikisha sheria za tag zinatumika hata wakati kernel inatekeleza kwa niaba ya user space.
Kwa kuwa EMTE imejengwa ndani ya MIE, Apple inatumia EMTE katika synchronous mode katika maeneo muhimu ya mashambulizi, si kama chaguo la hiari au mode ya debugging.
---
## Exception handling in XNU
Wakati **exception** inapotokea (mfano, `EXC_BAD_ACCESS`, `EXC_BAD_INSTRUCTION`, `EXC_CRASH`, `EXC_ARM_PAC`, n.k.), **Mach layer** ya kernel ya XNU inawajibika kuikamata kabla haijageuka kuwa signal ya mtindo wa UNIX (kama `SIGSEGV`, `SIGBUS`, `SIGILL`, ...).
Mchakato huu unahusisha tabaka kadhaa za propagation na handling ya exception kabla ya kufikishwa user space au kubadilishwa kuwa BSD signal.
### Exception Flow (High-Level)
1. **CPU triggers a synchronous exception** (mfano, invalid pointer dereference, PAC failure, illegal instruction, n.k.).
2. **Low-level trap handler** inaendesha (`trap.c`, `exception.c` katika XNU source).
3. The trap handler huita **`exception_triage()`**, ambayo ni nyenzo kuu ya Mach exception handling.
4. `exception_triage()` inaamua jinsi ya kupitisha exception:
- Kwanza kwa **thread's exception port**.
- Kisha kwa **task's exception port**.
- Kisha kwa **host's exception port** (mara nyingi `launchd` au `ReportCrash`).
Ikiwa hakuna miongoni mwa ports hizi zinazoshughulikia exception, kernel inaweza:
- **Kuiteleza kuwa BSD signal** (kwa processes za user-space).
- **Panic** (kwa exceptions za kernel-space).
### Core Function: `exception_triage()`
Kazi `exception_triage()` inapitisha Mach exceptions hadi mnyororo wa watendaji waliowezekana hadi mmoja atakayeshughulikia au hadi mwisho iwe fatal. Imefafanuliwa katika `osfmk/kern/exception.c`.
```c
void exception_triage(exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt);
Mtiririko wa Kawaida wa Miito:
exception_triage() └── exception_deliver() ├── exception_deliver_thread() ├── exception_deliver_task() └── exception_deliver_host()
Ikiwa zote zitashindwa → hutatuliwa na bsd_exception() → hubadilishwa kuwa ishara kama SIGSEGV.
Bandari za Exception
Kila object ya Mach (thread, task, host) inaweza kujisajili bandari za exception, 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 gani inayotaka kupokea)
- A port name (Mach port to receive messages)
- A behavior (how the kernel sends the message)
- A flavor (which thread state to include)
Debuggers and Exception Handling
A debugger (e.g., 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 handle (kuendelea, kubadilisha registers, kuruka instruction) au not handle exception.
- Kama debugger haitashughulikia, exception inasambaa kwa ngazi inayofuata (task → host).
Flow of EXC_BAD_ACCESS
-
Thread inafanya dereference ya pointer isiyo halali → CPU inaleta Data Abort.
-
Kernel trap handler inaita
exception_triage(EXC_BAD_ACCESS, ...). -
Ujumbe umetumwa kwa:
-
Thread port → (debugger inaweza kuingilia breakpoint).
-
Kama debugger inaepuka → Task port → (process-level handler).
-
Kama imepuuzwa → Host port (kawaida ReportCrash).
- Kama hakuna anayeshughulikia →
bsd_exception()hubadilisha kuwaSIGSEGV.
PAC Exceptions
Wakati Pointer Authentication (PAC) inashindwa (signature haifanani), special Mach exception inaibuliwa:
EXC_ARM_PAC(type)- Codes zinaweza kujumuisha maelezo (kwa mfano, aina ya key, aina ya pointer).
Kama binary ina flag TFRO_PAC_EXC_FATAL, kernel inachukulia kushindwa kwa PAC kama fatal, ikiepuka kuingiliwa na debugger. Hii ni kuzuia attackers kutumia debuggers kuvuka ukaguzi wa PAC na imewezeshwa kwa platform binaries.
Software Breakpoints
A software breakpoint (int3 on x86, brk on ARM64) hutekelezwa kwa kusababisha fault ya makusudi.
Debugger hushika hili kupitia exception port:
- Hubadilisha instruction pointer au memory.
- Hurejesha instruction ya awali.
- Unaendelea utekelezaji.
Mekanismo hii ndicho kinachokuwezesha “kukamata” PAC exception — isipokuwa TFRO_PAC_EXC_FATAL imewekwa, katika kesi hiyo haiwahi kufika kwa debugger.
Conversion to BSD Signals
Kama hakuna handler anayekubali exception:
-
Kernel inaita
task_exception_notify() → bsd_exception(). -
Hii inaweka ramani Mach exceptions kwa signals:
| Mach Exception | Signal |
|---|---|
| EXC_BAD_ACCESS | SIGSEGV or SIGBUS |
| EXC_BAD_INSTRUCTION | SIGILL |
| EXC_ARITHMETIC | SIGFPE |
| EXC_SOFTWARE | SIGTRAP |
| EXC_BREAKPOINT | SIGTRAP |
| EXC_CRASH | SIGKILL |
| EXC_ARM_PAC | SIGILL (on non-fatal) |
### Key Files in XNU Source
osfmk/kern/exception.c→ Msingi waexception_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 (Pre-iOS 15 / Pre-A12 era)
Kernel ilitumia zone allocator (kalloc) iliyogawanywa katika fixed-size “zones.” Kila zone ilihifadhi tu allocations za daraja moja ya ukubwa.
From the screenshot:
| Zone Name | Element Size | Example Use |
|---|---|---|
default.kalloc.16 | 16 bytes | Struct ndogo sana za kernel, pointers. |
default.kalloc.32 | 32 bytes | Small structs, object headers. |
default.kalloc.64 | 64 bytes | IPC messages, tiny kernel buffers. |
default.kalloc.128 | 128 bytes | Medium objects like parts of OSObject. |
| … | … | … |
default.kalloc.1280 | 1280 bytes | Large structures, IOSurface/graphics metadata. |
Ilivyofanya kazi:
- Kila ombi la allocation lime zungushwa hadi juu kwa ukubwa wa zone karibu kabisa. (Mfano, ombi la 50-byte linaingia katika zone
kalloc.64). - Memory katika kila zone ilihifadhiwa kwenye free list — vipande vilivyofunguliwa na kernel vilirudi kwenye zone hiyo.
- Kama utapita buffer ya 64-byte, utaandika juu ya kitu kinachofuata katika zone hiyo.
Hivyo ndicho kilichofanya heap spraying / feng shui kuwa mzuri sana: unaweza kutabiri majirani wa vitu kwa kupiga allocations za daraja moja ya ukubwa.
The freelist
Ndani ya kila kalloc zone, vitu vilivyotolewa hazivirudishw langsung kwenye mfumo — vilielekezwa kwenye freelist, linked list ya vipande vinavyopatikana.
-
Wakati chipu ilipotolewa, kernel iliandika pointer mwanzoni mwa chipu hiyo → anwani ya chipu inayofuata ya bure katika zone ileile.
-
Zone ilihifadhi HEAD pointer kwa chipu ya kwanza bure.
-
Allocation daima ilitumia HEAD ya sasa:
-
Pop HEAD (rudisha memory hiyo kwa muomba).
-
Sasisha HEAD = HEAD->next (iliyohifadhiwa kwenye header ya chipu iliyotolewa).
-
Kutoa kuliweka vipande tena:
-
freed_chunk->next = HEAD -
HEAD = freed_chunk
Kwa hiyo freelist ilikuwa tu linked list iliyojengwa ndani ya memory iliyotolewa 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)
Kutumia freelist
Kwa sababu bytes 8 za kwanza za free chunk = freelist pointer, mshambuliaji anaweza kuharibu:
-
Heap overflow into an adjacent freed chunk → overwrite its “next” pointer.
-
Use-after-free write into a freed object → overwrite its “next” pointer.
Kisha, kwenye allocation inayofuata ya ukubwa huo:
-
The allocator pops the corrupted chunk.
-
Follows the attacker-supplied “next” pointer.
-
Returns a pointer to arbitrary memory, enabling fake object primitives or 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 yenye ufanisi mkubwa kabla ya hardening: predictable neighbors kutoka kwa heap sprays, raw pointer freelist links, na kukosekana kwa type separation kulimruhusu mshambuliaji kuendeleza UAF/overflow bugs hadi kupata arbitrary kernel memory control.
Heap Grooming / Feng Shui
Lengo la heap grooming ni kuunda muundo wa heap ili wakati mshambuliaji atakayesababisha overflow au use-after-free, object lengwa (victim) iwe karibu sana na object inayodhibitiwa na mshambuliaji.
Kwa njia hiyo, wakati uharibifu wa memory unatokea, mshambuliaji anaweza kuandika juu ya object ya victim kwa data anayoidhibiti kwa uaminifu.
Hatua:
- Spray allocations (fill the holes)
- Kwa muda, kernel heap inavunjika: baadhi ya zones zina mapengo ambapo objects za zamani ziliwekwa free.
- Mshambuliaji anafanya allocations nyingi za dummy ili kujaza mapengo haya, hivyo heap inakuwa “packed” na inaweza kutabirika.
- Force new pages
- Mara mapengo yamejazwa, allocations zijazo lazima zijitokeze kutoka kwa new pages zilizoongezwa kwenye zone.
- Pages safi zinamaanisha objects zitawekwa pamoja, sio kuenea kwenye memory iliyovunjika.
- Hii inamruhusu mshambuliaji kuwa na udhibiti bora wa neighbors.
- Place attacker objects
- Mshambuliaji sasa anafanya spray tena, akitengeneza objects nyingi zinazodhibitiwa na mshambuliaji kwenye new pages hizo.
- Objects hizi zina ukubwa na nafasi zinazotabirika (kwa kuwa zote zinahusishwa na zone ileile).
- Free a controlled object (make a gap)
- Mshambuliaji kwa makusudi anafanya free moja ya objects zake mwenyewe.
- Hii inaumba “hole” kwenye heap, ambayo allocator baadaye itaitumia kwa allocation inayofuata ya ukubwa huo.
- Victim object lands in the hole
- Mshambuliaji anasababisha kernel kuallocate victim object (ile wanayotaka kuhatarisha).
- Kwa kuwa hole ndiyo slot ya kwanza inayopatikana kwenye freelist, victim inawekwa hasa pale mshambuliaji alipoifungua object yake.
- Overflow / UAF into victim
- Sasa mshambuliaji ana objects anazodhibiti karibu na victim.
- Kwa kuoverflow kutoka kwa moja ya objects zao (au kutumia tena freed object), wanaweza kuandika kwa uaminifu juu ya fields za memory za victim kwa values walizochagua.
Kwa nini inafanya kazi:
- Zone allocator predictability: allocations za ukubwa sawa daima zinatoka kwenye zone ileile.
- Freelist behavior: allocations mpya zinatumia chunk iliyotolewa hivi karibuni kwanza.
- Heap sprays: mshambuliaji anajaza memory kwa content inayotabirika na kudhibiti muundo.
- Matokeo: mshambuliaji anadhibiti wapi victim object itawekwa na data gani itakayoonekana karibu nayo.
Modern Kernel Heap (iOS 15+/A12+ SoCs)
Apple ilifanya hardening kwenye allocator na kufanya heap grooming kuwa ngumu zaidi:
1. From Classic kalloc to kalloc_type
- Before: zone moja
kalloc.<size>ilikuwepo kwa kila size class (16, 32, 64, … 1280, nk). Kila object ya ukubwa huo iliwekwa pale → attacker objects zingeweza kukaa karibu na privileged kernel objects. - Now:
- Kernel objects zinaallocate kutoka kwa typed zones (
kalloc_type). - Kila aina ya object (mfano,
ipc_port_t,task_t,OSString,OSData) ina zone yake ya kujitolea, hata kama zina ukubwa sawa. - Mapping kati ya object type ↔ zone inazalishwa kutoka kwa kalloc_type system wakati wa compilation.
Mshambuliaji hawezi tena kuhakikisha kwamba data inayodhibitiwa (OSData) itakuwa adjacent na sensitive kernel objects (task_t) za ukubwa mmoja.
2. Slabs and Per-CPU Caches
- Heap imegawanywa katika slabs (pages za memory zilizokatwa katika chunks za ukubwa fasta kwa zone hiyo).
- Kila zone ina per-CPU cache kupunguza contention.
- Allocation path:
- Jaribu per-CPU cache.
- Ikiwa tupu, chukua kutoka global freelist.
- Ikiwa freelist tupu, allocate slab mpya (ukurasa mmoja au zaidi).
- Faida: decentralization hii inafanya heap sprays zisitabiriki, kwa kuwa allocations zinaweza kutimizwa kutoka kwa caches za CPUs tofauti.
3. Randomization inside zones
- Ndani ya zone, elements zilizotolewa hazirudishiwi kwa mpangilio rahisi wa FIFO/LIFO.
- XNU ya kisasa inatumia encoded freelist pointers (safe-linking kama Linux, iliyotangazwa ~iOS 14).
- Kila freelist pointer ime-XOR-encoded na cookie ya siri ya zone.
- Hii inazuia mshambuliaji kuunda fake freelist pointer endapo wanapata write primitive.
- Baadhi ya allocations zinaweza kuwekwa kwa nasibu ndani ya slab, hivyo spraying haisihi kuhakikisha adjacency.
4. Guarded Allocations
- Baadhi ya kernel objects muhimu (mfano, credentials, task structures) zinaletwa katika guarded zones.
- Zones hizi zinaongeza guard pages (memory isiyopangwa) kati ya slabs au kutumia redzones karibu na objects.
- Kila overflow ndani ya guard page husababisha fault → panic ya mara moja badala ya uharibifu usioonekana.
5. Page Protection Layer (PPL) and SPTM
- Hata kama unadhibiti freed object, huwezi kubadilisha sehemu zote za kernel memory:
- PPL (Page Protection Layer) inasema kwamba sehemu fulani (mfano, code signing data, entitlements) ni read-only hata kwa kernel yenyewe.
- Kwenye A15/M2+ devices, nafasi hii imebadilishwa/imeongezwa na SPTM (Secure Page Table Monitor) + TXM (Trusted Execution Monitor).
- Tabaka hizi zilizothibitishwa kwa hardware zinamaanisha mshambuliaji hawawezi kuendeleza kutoka heap corruption moja hadi kufanya patch yoyote ya critical security structures.
- (Added / Enhanced): pia, PAC (Pointer Authentication Codes) inatumiwa kwenye kernel kulinda pointers (hasa function pointers, vtables) ili kuifanya kuwa ngumu kuziforge au kuziharibu.
- (Added / Enhanced): zones zinaweza kutekeleza zone_require / zone enforcement, yaani object iliyoFree inaweza kurudishwa tu kupitia zone sahihi ya typed; free isiyo sahihi kati ya zones inaweza kusababisha panic au kukataliwa. (Apple inamaanisha hili kwenye posts zao za memory safety)
6. Large Allocations
- Sio allocations zote zinapitishwa kupitia
kalloc_type. - Maombi makubwa sana (juu ~16 KB) hupita typed zones na hutolewa moja kwa moja kutoka kernel VM (kmem) kupitia page allocations.
- Hizi hazitabiriki sana, lakini pia ni ngumu ku-exploit, kwa kuwa hazishiriki slabs na objects nyingine.
7. Allocation Patterns Attackers Target
Hata na uvikaji hivi, mshambuliaji bado wanatafuta:
- Reference count objects: endapo utaweza kuathiri retain/release counters, unaweza kusababisha use-after-free.
- Objects with function pointers (vtables): kuharibu moja bado kunaweza kutoa control flow.
- Shared memory objects (IOSurface, Mach ports): hizi bado ni targets kwa kuwa zinavuka user ↔ kernel.
Lakini — tofauti na zamani — huwezi tu kufanya spray ya OSData na kutegemea itakuwa karibu na task_t. Unahitaji type-specific bugs au info leaks kufanikiwa.
Example: Allocation Flow in Modern Heap
Tuseme userspace inaita IOKit kuallocate OSData object:
- Type lookup →
OSDatainaendeshwa kwenyekalloc_type_osdatazone (size 64 bytes). - Angalia per-CPU cache kwa elements za bure.
- Ikiwa imetupwa → rudisha moja.
- Ikiwa tupu → nenda kwenye global freelist.
- Ikiwa freelist tupu → allocate slab mpya (ukurasa wa 4KB → 64 chunks za 64 bytes).
- Rudisha chunk kwa mtumiaji.
Freelist pointer protection:
- Kila chunk iliyofungwa huhifadhi address ya chunk ijayo ya bure, lakini imekodishwa na key ya siri.
- Kuandika juu ya field hiyo kwa data ya mshambuliaji haitafanya kazi isipokuwa ukijua key.
Comparison Table
| Feature | Old Heap (Pre-iOS 15) | Modern Heap (iOS 15+ / A12+) |
|---|---|---|
| Allocation granularity | Fixed size buckets (kalloc.16, kalloc.32, etc.) | Size + type-based buckets (kalloc_type) |
| Placement predictability | High (same-size objects side by side) | Low (same-type grouping + randomness) |
| Freelist management | Raw pointers in freed chunks (easy to corrupt) | Encoded pointers (safe-linking style) |
| Adjacent object control | Easy via sprays/frees (feng shui predictable) | Hard — typed zones separate attacker objects |
| Kernel data/code protections | Few hardware protections | PPL / SPTM protect page tables & code pages, and PAC protects pointers |
| Allocation reuse validation | None (freelist pointers raw) | zone_require / zone enforcement |
| Exploit reliability | High with heap sprays | Much lower, requires logic bugs or info leaks |
| Large allocations handling | All small allocations managed equally | Large ones bypass zones → handled via VM |
Modern Userland Heap (iOS, macOS — type-aware / xzone malloc)
Katika vituo vya hivi karibuni vya Apple OS (hasa iOS 17+), Apple ilianzisha allocator ya userland yenye usalama zaidi, xzone malloc (XZM). Hii ni analog ya user-space kwa kernel’s kalloc_type, ikitumia type awareness, metadata isolation, na memory tagging safeguards.
Goals & Design Principles
- Type segregation / type awareness: kuunganisha allocations kwa type au matumizi (pointer vs data) ili kuzuia type confusion na cross-type reuse.
- Metadata isolation: kutenganisha heap metadata (mfano free lists, size/state bits) kutoka kwa payloads za object ili out-of-bounds writes zisizoweza kuharibu metadata.
- Guard pages / redzones: kuweka pages zisizopangwa au padding karibu na allocations ili kugundua overflows.
- Memory tagging (EMTE / MIE): kufanya kazi pamoja na hardware tagging kugundua use-after-free, out-of-bounds, na upatikanaji batili.
- Scalable performance: kudumisha overhead ndogo, kuepuka fragmentation kupita kiasi, na kusaidia allocations nyingi kwa sekunde kwa latency ndogo.
Architecture & Components
Hapa chini ni vipengele vikuu katika xzone allocator:
Segment Groups & Zones
- Segment groups zinaigawa address space kwa makundi ya matumizi: mf.
data,pointer_xzones,data_large,pointer_large. - Kila segment group ina segments (range za VM) zinazohifadhi allocations kwa category 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 za object, kupunguza uharibifu kutoka kwa overflows.
- Segments zinagawanywa katika chunks (slices) ambazo kwa upande wake zinasagwa katika blocks (allocation units). Chunk huhusishwa na size class na segment group maalum (yaani blocks zote ndani ya chunk zina ukubwa & category sawa).
- Kwa allocations ndogo/za kati, itatumia chunks za ukubwa fasta; kwa kubwa/huge, inaweza ku-map kwa tofauti.
Chunks & Blocks
- Chunk ni eneo (kwa kawaida pages kadhaa) lililotengwa kwa allocations za size class moja ndani ya group.
- Ndani ya chunk, blocks ni slots zinazopatikana kwa allocations. Freed blocks zinatajwa kupitia metadata slab — mf. kupitia bitmaps au free lists zilizohifadhiwa out-of-line.
- Kati ya chunks (au ndani), guard slices / guard pages zinaweza kuwekwa (mf. slices zisizopangwa) ili kugundua writes nje ya mipaka.
Type / Type ID
- Kila allocation site (au wito kwa malloc, calloc, nk) inaambatanishwa na type identifier (nyenzo ya
malloc_type_id_t) ambayo inaelezea aina ya object inayopatikana. Type ID hii inapitishwa kwa allocator, inayotumia kuchagua zone / segment inayofaa kwa allocation. - Kwa sababu ya hili, hata kama allocations mbili zina ukubwa sawa, zinaweza kwenda katika zones tofauti kabisa ikiwa aina zao zinatofautiana.
- Katika toleo la mwanzo la iOS 17, APIs zote hazikuwa type-aware kikamilifu; Apple ilirekebisha udhaifu huo katika iOS 18.
Allocation & Freeing Workflow
Hapa kuna mtiririko wa juu wa jinsi allocation na deallocation zinavyofanya kazi katika xzone:
- malloc / calloc / realloc / typed alloc imetangazwa na ukubwa na type ID.
- Allocator inatumia type ID kuchagua segment group / zone sahihi.
- Ndani ya zone/segment, inatafuta chunk yenye free blocks za size iliyoombwa.
- Inaweza kushauriana na local caches / per-thread pools au free block lists kutoka metadata.
- Ikiwa hakuna free block, inaweza allocate chunk mpya katika zone hiyo.
- Metadata slab inasasishwa (free bit inafutwa, bookkeeping).
- Ikiwa memory tagging (EMTE) inatumika, block iliyorudishwa inapata tag, na metadata inasasishwa kuonyesha hali yake ya “live”.
- Wakati
free()inaitwa:
- Block inatambulishwa kama freed katika metadata (kupitia OOL slab).
- Block inaweza kuwekwa kwenye free list au kuwekwa pooled kwa reuse.
- Hiari, block contents zinaweza kufutwa au kuchomwa (poisoned) kupunguza leak au exploitation ya use-after-free.
- Hardware tag inayohusishwa na block inaweza kuharibiwa au kure-tagged.
- Ikiwa chunk nzima inakuwa free (blocks zote zimetolewa), allocator inaweza kudai chunk hiyo (kuifungua au kurudisha kwa OS) wakati kuna shinikizo la memory.
Security Features & Hardening
Hizi ni defenses zilizojengwa ndani ya userland xzone:
| Feature | Purpose | Notes |
|---|---|---|
| Metadata decoupling | Prevent overflow from corrupting metadata | Metadata lives in separate VM region (metadata slab) |
| Guard pages / unmapped slices | Catch out-of-bounds writes | Helps detect buffer overflows rather than silently corrupting adjacent blocks |
| Type-based segregation | Prevent cross-type reuse & type confusion | Even same-size allocations from different types go to different zones |
| Memory Tagging (EMTE / MIE) | Detect invalid access, stale references, OOB, UAF | xzone works in concert with hardware EMTE in synchronous mode (“Memory Integrity Enforcement”) |
| Delayed reuse / poisoning / zap | Reduce chance of use-after-free exploitation | Freed blocks may be poisoned, zeroed, or quarantined before reuse |
| Chunk reclamation / dynamic unmapping | Reduce memory waste and fragmentation | Entire chunks may be unmapped when unused |
| Randomization / placement variation | Prevent deterministic adjacency | Blocks in a chunk and chunk selection may have randomized aspects |
| Segregation of “data-only” allocations | Separate allocations that don’t store pointers | Reduces attacker control over metadata or control fields |
Interaction with Memory Integrity Enforcement (MIE / EMTE)
- MIE ya Apple (Memory Integrity Enforcement) ni hardware + OS framework inayoweka Enhanced Memory Tagging Extension (EMTE) katika mode ya daima-on, synchronous katika maeneo makubwa ya attack surface.
- xzone allocator ni msingi muhimu wa MIE katika user space: allocations zinazofanywa kupitia xzone zinapata tags, na upatikanaji unasemwa na hardware.
- Katika MIE, allocator, assignment ya tag, usimamizi wa metadata, na enforcement ya tag confidentiality vimeunganishwa kuhakikisha kwamba makosa ya memory (mf. stale reads, OOB, UAF) yanagunduliwa mara moja, si kutumiwa baadaye.
- If you like, I can also generate a cheat-sheet or diagram of xzone internals for your book. Do you want me to do that next?
- :contentReference[oai:20]{index=20}
(Old) Physical Use-After-Free via IOSurface
Ghidra Install BinDiff
Download BinDiff DMG from https://www.zynamics.com/bindiff/manual and 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
- Go to the page https://ipsw.me/ and download the iOS versions you want to diff. These will be
.ipswfiles. - Decompress until you get the bin format of the kernelcache of both
.ipswfiles. You have information on how to do this on:
macOS Kernel Extensions & Kernelcache
- Open Ghidra with
ghidraRun, create a new project and load the kernelcaches. - Open each kernelcache so they are automatically analyzed by Ghidra.
- Then, on the project Window of Ghidra, right click each kernelcache, select
Export, select formatBinary BinExport (v2) for BinDiffand export them. - 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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
HackTricks

