Android Hardware Reverse Engineering

JTAG/SWD for eMMC: Advanced Techniques for Raw Memory Extraction on Android

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction to eMMC Memory Extraction

The quest for digital evidence and low-level system understanding often leads to the core of an Android device’s storage: the embedded MultiMediaCard (eMMC). Unlike traditional hard drives, eMMC is directly soldered to the device’s mainboard, making direct physical access challenging. Raw memory extraction from eMMC is crucial for advanced forensics, malware analysis, and vulnerability research, providing an unparalleled view into the operating system, user data, and firmware. While chip-off forensics is an option, it’s destructive and requires specialized equipment. This article delves into non-destructive, advanced techniques for eMMC raw memory extraction using JTAG (Joint Test Action Group) and SWD (Serial Wire Debug) interfaces, offering a powerful alternative for acquiring a complete dump of an Android device’s internal storage.

Understanding eMMC and Android Storage Architecture

eMMC serves as the primary storage solution for most Android devices, integrating a flash memory controller and NAND flash memory into a single package. The Android operating system partitions this storage into various logical units for system, user data, cache, and recovery. From a forensic perspective, gaining raw access to these partitions, including any hidden or unallocated space, is paramount. The eMMC controller manages wear leveling, error correction, and block management, abstracting the complexities of NAND flash from the SoC. Our goal is to leverage debug interfaces to bypass the Android OS and communicate directly with the SoC’s memory controller, which in turn manages the eMMC.

JTAG/SWD: The Gateway to Embedded Systems

JTAG and SWD are industry-standard debug interfaces primarily used for testing, programming, and debugging embedded systems. They provide a low-level communication channel directly to the System-on-Chip (SoC) processor, offering control over CPU execution, register access, and direct memory access (DMA). For eMMC extraction, JTAG/SWD allows us to:

  • Halt the SoC’s execution.
  • Read and write to arbitrary memory addresses.
  • Control peripheral registers, including those of the eMMC controller.
  • Potentially load and execute custom code on the target SoC.

These capabilities are fundamental to initiating and managing raw data transfers from the eMMC via the SoC’s memory bus.

Identifying and Accessing JTAG/SWD Test Points

1. Physical Inspection and Pinout Discovery

Locating JTAG/SWD test points typically involves careful physical inspection of the Android device’s PCB. Look for:

  • Unpopulated headers (e.g., 2×5 or 2×10 pin arrays).
  • Small, often unlabeled test pads (TPs) which might be organized in a discernible pattern.
  • Areas near the SoC, memory chips, or power management ICs.

Once potential points are identified, determining their function (TRST, TCK, TMS, TDI, TDO for JTAG; SWDIO, SWCLK for SWD) is the next critical step. Methods include:

  • Schematic Analysis: If available, device schematics or service manuals are the most reliable source.
  • X-ray Imaging: Can reveal traces from the SoC to hidden test points.
  • Continuity Testing: Using a multimeter to trace connections from the SoC’s ball grid array (BGA) package to identified test pads.
  • Tools like JTAGulator/Bus Pirate: These devices can help automate the process of identifying JTAG pins by scanning for common pin configurations and responses.

Precision soldering is often required to attach fine wires to these delicate test pads. Use thin enamel-coated magnet wire and a low-temperature soldering iron.

2. Establishing Connection with Debug Probe

Once pinouts are identified and wired, a debug probe is needed to interface with the PC. Popular choices include:

  • SEGGER J-Link: Widely supported, robust, and often used for professional development.
  • OpenOCD compatible probes: Such as FT2232H-based adapters (e.g., Bus Blaster) or custom ARM-JTAG/SWD adapters.
  • Lauterbach TRACE32: High-end solution for complex debugging scenarios.

For this example, we’ll assume an OpenOCD setup. First, verify connectivity:

openocd -f interface/jlink.cfg -f target/stm32f4x.cfg # (or appropriate target cfg)

If successful, OpenOCD will connect and report target status.

Interfacing with the SoC and eMMC for Data Extraction

The core concept is to use the debug interface to instruct the SoC’s memory controller to read blocks from the eMMC and transfer them to an accessible memory region (e.g., internal SRAM or external DDR) that we can then dump via JTAG/SWD. This often involves:

1. Halting the CPU and Initializing the Debugger

# In OpenOCD GDB server console (telnet localhost 4444) or via GDB client:target remote localhost:3333 # Connect GDB to OpenOCDgdb> monitor reset halt # Reset and halt the CPUgdb> monitor init # Initialize the target (might be implicit)

2. Identifying eMMC Controller Registers and Memory Map

This is the most device-specific part. You’ll need SoC documentation (datasheets, TRMs) to find:

  • The base address of the eMMC controller.
  • Registers for command, argument, response, and data transfer.
  • The SoC’s internal memory map, especially the addresses of SRAM/DDR.

Without specific documentation, reverse engineering firmware images for eMMC driver code can reveal register usage.

3. Raw Block Data Acquisition Workflow

The general procedure involves a loop of:

  1. Configure the eMMC controller to read a specific block (e.g., using CMD17 for single block read or CMD18 for multiple block read).
  2. Initiate the read operation by writing to the appropriate command register.
  3. Wait for the read to complete (monitor status registers).
  4. Read the data from the SoC’s internal buffer (SRAM/DDR) where the eMMC controller places the data, using JTAG/SWD memory read commands.
  5. Transfer the read data to your host PC.
  6. Increment the block address and repeat until the entire eMMC is dumped.

Example GDB commands to read memory (assuming data is buffered at 0x20000000 and you want to read 1024 bytes):

gdb> dump binary memory emmc_block_0000.bin 0x20000000 0x20000400 # Dumps 1KB

For a full dump, this needs to be scripted. A Python script using gdb.execute() or interacting directly with OpenOCD’s telnet interface (port 4444) is ideal. Here’s a conceptual Python-OpenOCD snippet:

import telnetlibimport timeHOST =

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 →
Google AdSense Inline Placement - Content Footer banner