Introduction to TrustZone and Secure World Extraction
ARM TrustZone technology is a system-wide approach to security, creating two virtual processors running on a single physical core: the Normal world and the Secure world. The Normal world hosts general-purpose operating systems like Android or Linux, while the Secure world runs a Trusted Execution Environment (TEE) operating system and Trusted Applications (TAs) to handle sensitive operations such as secure boot, DRM, and biometric authentication. Extracting code from the Secure world is a critical step in security research, allowing analysts to uncover vulnerabilities, understand proprietary implementations, and evaluate the overall security posture of a device.
This tutorial provides a detailed, step-by-step guide to building your own TrustZone extraction toolchain. We will focus on the methodologies and tools required to dump secure memory regions and analyze their contents, primarily targeting ARMv8-A (AArch64) architectures. Be aware that this process often involves low-level hardware access and specific device vulnerabilities, making it a challenging but rewarding endeavor.
Prerequisites for TrustZone Extraction
Before embarking on this journey, ensure you have the following:
- Hardware: Target ARMv8-A device (e.g., Android phone, IoT device), JTAG/SWD debugger (e.g., Segger J-Link, FT2232H-based adapter), soldering equipment, multimeter, logic analyzer (optional).
- Software: Linux-based workstation, OpenOCD, GNU Debugger (GDB), binutils (objdump, readelf), disassembler/decompiler (Ghidra or IDA Pro), hex editor.
- Knowledge: Strong understanding of ARM architecture (AArch64), embedded systems, memory management units (MMU), basic reverse engineering principles, and familiarity with secure boot processes.
Understanding TrustZone Architecture at a Glance
TrustZone operates on privilege levels (EL0-EL3). The Secure Monitor (EL3) acts as a gateway between the Normal world (typically EL1/EL0) and the Secure world (EL1/EL0). Communication happens via Secure Monitor Calls (SMC). The TEE OS (e.g., OP-TEE, Trusty) runs in the Secure world and manages Trusted Applications (TAs). Our goal is to extract the code for the Secure Monitor, the TEE OS, and any TAs.
Step 1: Gaining Low-Level Hardware Access
The first and often most challenging step is to gain low-level access to the device’s CPU. This typically involves:
- JTAG/SWD Debugging: Identifying and soldering to debug pads on the device’s PCB. This provides direct access to the CPU’s internal registers and memory.
- UART Console Access: Useful for interacting with bootloaders or early kernel stages, which might offer memory dump commands or expose vulnerabilities.
- Bootloader Exploits: Leveraging vulnerabilities in the device’s bootloader (e.g., memory corruption, unsigned code execution) to gain control and dump memory from the Normal world, potentially allowing access to Secure world regions through MMU misconfigurations.
For this tutorial, we will assume successful JTAG access, as it offers the most direct path to memory extraction.
Step 2: Identifying TrustZone Components and Memory Regions
With JTAG access, you need to identify where the Secure Monitor, TEE OS, and TAs reside in memory. Key indicators include:
- Bootloader Logs: UART output often reveals memory maps or loading addresses for secure components.
- Device Tree Blobs (DTB): Can sometimes contain memory region definitions.
- Known Architecture Layouts: Many ARM SoCs follow similar memory layouts. The Secure Monitor (e.g., ARM Trusted Firmware-A’s BL31) typically loads very early, often at 0x0 or a low address in the secure memory space. The TEE OS usually resides in a dedicated, often non-cacheable, physical memory region.
/proc/iomem(if device boots to Linux with root): While this shows Normal world memory, it can hint at reserved regions that might be secure.
A common starting point for AArch64 secure world code is within the 0x0 – 0x100000 range (for BL31) or higher up, in dedicated RAM regions (e.g., 0x40000000 – 0x4xxxxxxx).
Step 3: Dumping Secure Memory Regions via JTAG
Using OpenOCD and GDB, you can connect to the target and dump its memory. First, configure OpenOCD for your debugger and target CPU. A simplified configuration might look like this:
# openocd.cfg example for a generic ARMv8-A target with FT2232H JTAG# adapter driver_ftdi ft2232h# interface configuration interface ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_channel 0 ftdi_layout_init 0x0018 0x001b ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020# JTAG scan chain configuration transport select jtag adapter_khz 10000# CPU target configuration set _TARGETNAME riscv target create $_TARGETNAME aarch64 -endian little -chain-position $_TARGETNAME.cpu core_state aarch64 target smp disable gdb_port 3333 init reset halt
Run OpenOCD with your configuration:
openocd -f openocd.cfg
Then, connect GDB:
aarch64-none-elf-gdb -ex "target remote localhost:3333"
Once connected, you can use GDB’s dump binary memory command to extract memory regions. For example, to dump 1MB starting at address 0x0:
(gdb) dump binary memory secure_monitor.bin 0x0 0x100000
Repeat this for all identified secure memory regions (e.g., TEE OS base address, known TA load addresses). You might need to experiment with different addresses and sizes.
Step 4: Analyzing the Dumped Firmware
With the raw binary dumps, it’s time for static analysis:
- Load into Disassembler: Import the binary into Ghidra or IDA Pro. Specify the correct architecture (ARMv8-A, AArch64) and the base address from which it was dumped.
- Identify Entry Points: Look for the reset vector or known entry points (e.g., `_start` or the address where the Secure Monitor is expected to begin execution).
- Search for SMC Handlers: TrustZone heavily relies on SMC instructions (`SMC #0`) for Normal world to Secure world communication. Analyze the code preceding and following these instructions to understand the Secure Monitor’s services.
- Identify TEE OS Structures: If you’ve dumped a TEE OS (like OP-TEE or Trusty), look for known ELF headers or specific magic values that indicate the start of the TEE OS image or embedded Trusted Applications.
- Function Identification: Start identifying functions based on calls, loops, and common instruction patterns. Pay close attention to functions that handle memory, cryptography, or inter-world communication.
Step 5: Extracting TrustZone Applications (TAs)
Trusted Applications are the individual services running within the TEE OS. They are often embedded within the TEE OS image or stored as separate files in a secure filesystem (though typically encrypted on disk).
- If embedded in TEE OS dump: TAs are often ELF binaries themselves. Look for ELF magic numbers (`ELF`) or specific TA headers/structures defined by the TEE OS (e.g., OP-TEE TAs have a specific header structure including a UUID).
- Parsing TA Headers: TEEs like OP-TEE define a structure for TAs, including a UUID and entry points. You can write a small script to scan the dumped TEE OS image for these headers and extract the TA binaries. For example, an OP-TEE TA header includes `struct ta_head` which contains the TA’s UUID.
// Pseudocode for scanning OP-TEE TA header#define TA_MAGIC 0x4F505441 //
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →