ARM64 Assembly (AArch64)
ARM64 là instruction set architecture (ISA) của mọi Apple Silicon chip (A-series, M-series). Mọi code chạy trên iPhone đều là ARM64 machine code.
Tại Sao Cần Học
- Kernel exploits yêu cầu đọc hiểu disassembly để tìm gadgets, hiểu control flow
- PAC bypass cần hiểu PAC instructions (PACIA, AUTIA, …)
- ROP/JOP chains xây dựng từ assembly gadgets
- Debugger (lldb) hiển thị assembly, không phải C
Kiến Thức Cần Nắm
1. Registers
| Register | Mục đích |
|---|---|
X0 - X7 |
Function arguments & return values (X0 = arg1 & return) |
X8 |
Indirect result location (struct return) |
X9 - X15 |
Temporary registers (caller-saved) |
X16 (IP0) |
Intra-procedure scratch, cũng dùng cho PLT/stub calls |
X17 (IP1) |
Intra-procedure scratch |
X18 |
Platform register (reserved trên Apple platforms) |
X19 - X28 |
Callee-saved registers |
X29 (FP) |
Frame pointer |
X30 (LR) |
Link register (return address) |
SP |
Stack pointer (phải luôn 16-byte aligned) |
PC |
Program counter (không truy cập trực tiếp như trên ARM32) |
NZCV |
Condition flags: Negative, Zero, Carry, oVerflow |
Special registers cho iOS exploitation:
W0 - W28: 32-bit view của X0-X28 (lower 32 bits)TPIDR_EL1: Thread-local storage pointer cho kernelTTBR0_EL1/TTBR1_EL1: Translation Table Base Registers (page table pointers)VBAR_EL1: Vector Base Address Register (exception handlers)SCTLR_EL1: System Control Register
2. Instructions Thường Gặp Trong Exploit Analysis
Data Movement:
MOV X0, X1 ; X0 = X1
MOV X0, #0x1234 ; X0 = immediate value
MOVK X0, #0xABCD, LSL #16 ; Move with keep (set bits 16-31)
LDR X0, [X1] ; X0 = *(uint64_t*)X1
LDR X0, [X1, #0x10] ; X0 = *(uint64_t*)(X1 + 0x10)
LDP X0, X1, [SP] ; Load pair from stack
STR X0, [X1] ; *(uint64_t*)X1 = X0
STP X29, X30, [SP, #-0x10]! ; Push FP and LR to stack (pre-index)
Arithmetic & Logic:
ADD X0, X1, X2 ; X0 = X1 + X2
SUB X0, X1, #0x10 ; X0 = X1 - 0x10
AND X0, X1, #0xFF ; X0 = X1 & 0xFF (masking)
ORR X0, X1, X2 ; X0 = X1 | X2
EOR X0, X1, X2 ; X0 = X1 ^ X2 (XOR)
LSL X0, X1, #4 ; X0 = X1 << 4
LSR X0, X1, #4 ; X0 = X1 >> 4 (logical shift)
Branching:
B label ; Unconditional branch
BL function ; Branch with link (function call, LR = return addr)
BR X16 ; Branch to register (indirect jump)
BLR X8 ; Branch with link to register (indirect call)
RET ; Return (branch to LR/X30)
CBZ X0, label ; Branch if X0 == 0
CBNZ X0, label ; Branch if X0 != 0
B.EQ label ; Branch if equal (Z flag set)
B.NE label ; Branch if not equal
B.GT / B.LT / B.GE / B.LE ; Signed comparisons
B.HI / B.LO / B.HS / B.LS ; Unsigned comparisons
Compare:
CMP X0, X1 ; Set flags based on X0 - X1
CMN X0, X1 ; Set flags based on X0 + X1
TST X0, #0x1 ; Set flags based on X0 & 0x1
System:
SVC #0x80 ; Supervisor call (syscall trên iOS/macOS)
MRS X0, CurrentEL ; Read system register
MSR TTBR0_EL1, X0 ; Write system register
ISB ; Instruction Synchronization Barrier
DSB SY ; Data Synchronization Barrier
TLBI ; TLB Invalidate
3. PAC Instructions (A12+)
PACIA X0, X1 ; Sign X0 with key A, context X1
PACIB X0, X1 ; Sign X0 with key B, context X1
PACIZA X0 ; Sign X0 with key A, zero context
AUTIA X0, X1 ; Authenticate X0 with key A, context X1
AUTIB X0, X1 ; Authenticate X0 with key B, context X1
XPACI X0 ; Strip PAC bits from X0 (no auth check)
BRAA X0, X1 ; Authenticate & branch (key A)
BLRAA X0, X1 ; Authenticate & branch with link (key A)
RETAB ; Authenticate LR with key B & return
Ý nghĩa cho exploitation:
PACIA/PACIBthêm cryptographic signature vào pointerAUTIA/AUTIBverify signature — nếu sai → pointer bị corrupt → crashXPACIstrip PAC bits mà không verify — hữu ích khi cần raw address- Signing gadgets dùng
PACIAtrên controlled input → forge valid PAC
4. Calling Convention (AAPCS64 — Apple variant)
Caller:
1. Đặt arguments vào X0-X7 (integer) hoặc D0-D7 (float)
2. Arguments > 8 đẩy lên stack
3. BL function_name (LR = return address)
Callee (function prologue):
STP X29, X30, [SP, #-frame_size]! ; Save FP and LR
MOV X29, SP ; Set up frame pointer
... function body ...
Callee (function epilogue):
LDP X29, X30, [SP], #frame_size ; Restore FP and LR
RET ; Return to caller
Apple-specific:
- X18 reserved (platform register — do not touch)
- Stack phải 16-byte aligned tại mọi thời điểm khi gọi function
- Red zone: 128 bytes dưới SP có thể dùng mà không cần adjust SP (leaf functions)
5. Memory Model
Address space trên ARM64 iOS:
0x0000000000000000 ┐
│ Userspace (TTBR0_EL1)
0x0000007FFFFFFFFF ┘ (~512GB, thực tế iOS giới hạn 0x8000000000 = 32GB)
0xFFFF000000000000 ┐
│ Kernel space (TTBR1_EL1)
0xFFFFFFFFFFFFFFFF ┘
Exception Levels:
EL0 — Userspace (apps, daemons)
EL1 — Kernel (XNU)
EL2 — Hypervisor (SPTM trên iOS 17+; trước đó không dùng)
EL3 — Secure Monitor (iBoot, Secure Enclave communication)
Tài Nguyên Học
Beginner
- Azeria Labs — ARM Assembly Basics (ARM32 nhưng concepts tương tự)
- ARM Developer — Learn the Architecture: AArch64
- ARM Architecture Reference Manual (ARMv8-A) — tài liệu gốc, rất dày nhưng đầy đủ
Intermediate
- Đọc disassembly output từ IDA/Ghidra cho iOS binaries thật
- Viết inline assembly trong C và compile cho arm64
- Debug iOS apps bằng lldb, đọc register state
Advanced
- Phân tích kernel cache disassembly
- Tìm PAC signing/auth gadgets trong system frameworks
- Hiểu exception vector table (VBAR_EL1) và cách kernel handle traps
Bài Tập Thực Hành
- Viết “Hello World” bằng ARM64 assembly cho macOS (nếu có Apple Silicon Mac)
- Disassemble một binary iOS đơn giản bằng IDA/Ghidra, trace execution flow bằng tay
- Identify calling convention trong decompiled code: tìm arguments, return values, stack frame
- Tìm gadgets trong một Mach-O binary: sequences kết thúc bằng RET, BLR, hoặc BR
- Đọc PAC instructions trong kernelcache disassembly và hiểu chúng bảo vệ cái gì