Introduction: The Power of PMIC Fault Injection
Power Management Integrated Circuits (PMICs) are critical components in modern Android devices, orchestrating power delivery, charging, voltage regulation, and power sequencing. Manipulating PMIC registers can induce various power-related faults, which is invaluable for security testing, hardware debugging, and understanding device resilience. This guide delves into automating PMIC fault injection on custom Android targets using Python scripts for register write injection.
By directly altering PMIC operational parameters, we can simulate conditions like brownouts, unexpected power cycles, or voltage fluctuations, potentially uncovering vulnerabilities in device drivers, bootloaders, or even physical hardware. The focus here is on identifying PMIC registers and crafting Python scripts to perform targeted, automated writes via the Android Debug Bridge (ADB).
Understanding PMICs and Android Interaction
A PMIC acts as the central power hub, managing power distribution to various subsystems like the CPU, GPU, memory, and peripherals. Communication between the Android operating system (specifically the Linux kernel) and the PMIC typically occurs over low-level serial interfaces such as I2C or SPI.
Android’s kernel includes drivers that abstract these hardware interfaces, allowing higher-level software to request power state changes or monitor power parameters. Our goal is to bypass these high-level abstractions or leverage existing low-level tools to directly manipulate the PMIC registers, which are essentially memory locations within the PMIC that control its functions.
Why Fault Injection?
- Security Research: Uncover power-related side-channel vulnerabilities, bypass security mechanisms, or trigger unexpected device states.
- Hardware Debugging: Pinpoint hardware issues related to power sequencing, voltage stability, or component resilience under stress.
- Reliability Testing: Evaluate a device’s robustness against power disturbances or abnormal operating conditions.
Identifying PMIC Registers on a Custom Target
The most challenging aspect of PMIC fault injection is identifying the correct I2C/SPI bus, device address, and relevant registers without public datasheets. For custom Android targets, this often involves a degree of reverse engineering.
Method 1: Device Tree (DTB/DTS) Analysis
Modern Android devices use Device Trees (DTB) to describe hardware. You can extract and decompile the DTB from a rooted device or its firmware image.
- Extract DTB: On a rooted device, the DTB is often found at
/sys/firmware/fdtor embedded within the kernel image. You might need to pull the kernel image (zImage,Image.gz) and extract the DTB blob. - Decompile DTB: Use
dtc(Device Tree Compiler) to decompile the DTB to a human-readable DTS file.adb pull /path/to/dtb_file.dtb.raw ./dtb.dtbdtc -I dtb -O dts -o dtb.dts dtb.dtb - Search for PMIC Entries: In the
dtb.dtsfile, look for I2C or SPI nodes. Common PMIC vendor prefixes includeqcom,pm8xxx(Qualcomm),ti,tpsxxxx(TI),maxim,maxxxxx(Maxim), or generalregulatornodes. These entries often specify the I2C bus number, device address, and sometimes even register configurations.
Method 2: Kernel Source Code Review
If kernel source code for your device or a similar platform is available, it’s an invaluable resource.
- Locate PMIC Drivers: Search for drivers in
drivers/regulator/,drivers/mfd/, or directly indrivers/power/. - Examine Driver Code: Look for structures defining register maps, I2C/SPI probe functions, and specific register bit definitions (e.g., controlling LDOs, buck converters, charging states). Drivers often use the Linux kernel’s
regmapAPI, which centralizes register access.
Method 3: On-Device Probing with i2c-tools
On a rooted Android device, `i2c-tools` (specifically i2cdetect, i2cset, i2cget) can be used, although direct access might be restricted by SELinux or driver implementations.
- Install
i2c-tools: Many custom ROMs or rooted devices include these. If not, you might need to compile them for your device’s architecture or push pre-compiled binaries. - Identify I2C Buses: Run
i2cdetect -lto list available I2C buses. - Scan for Devices: For each bus, run
i2cdetect -y <bus_num>to scan for devices. PMICs often reside at common I2C addresses (e.g., 0x48, 0x68).
Note: Directly using i2cset/i2cget might be blocked by kernel drivers that claim exclusive access to PMIC registers. In such cases, a custom kernel module might be necessary for direct low-level access, but for many basic injections, i2cset often works if the address isn’t actively protected.
Developing the Python Injection Script
Our Python script will leverage ADB to execute i2cset commands on the target Android device. This allows us to automate complex sequences of register writes.
Prerequisites:
- Python 3 installed on your host machine.
- ADB installed and configured.
- Rooted Android device with developer options and USB debugging enabled.
i2c-tools(specificallyi2cset) available on the Android device.
Python Script Structure
The core of the script will be calling adb shell i2cset. The command syntax is typically:
adb shell i2cset -y <bus_number> <device_address> <register_address> <value> [mode]
-y: Suppress interaction.<bus_number>: The I2C bus (e.g., 0, 1, 2).<device_address>: The PMIC’s I2C address (e.g., 0x48).<register_address>: The specific PMIC register to write to (e.g., 0x01).<value>: The byte value to write (e.g., 0x00, 0xFF).[mode]: Optional. ‘b’ for byte (default), ‘w’ for word, ‘i’ for I2C block.
Example Python Script for Automated PMIC Fault Injection
import subprocessimport timeimport sysdef run_adb_command(command): try: result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True) return result.stdout.strip() except subprocess.CalledProcessError as e: print(f
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 →