Introduction: Unlocking the Android Virtual Device Core
Android Virtual Device (AVD) system images are the backbone of any Android emulation or containerized environment like Anbox or Waydroid. While readily available, these pre-built images often come with limitations that can hinder advanced development, security research, or specific compatibility needs. This expert-level guide delves into the intricate process of reverse engineering AVD system images, empowering you to unpack, modify, and repack these critical components. Mastering this skill grants unparalleled control over your virtual Android environments, allowing for custom kernel integration, root access, library modifications, performance tweaks, or tailored configurations essential for specialized projects.
By the end of this tutorial, you will have a comprehensive understanding of the tools and techniques required to deeply customize AVD images, fostering a new level of flexibility for your Android development and research endeavors.
Understanding Android System Image Structure
Android system images are typically composed of several partitions, each serving a specific purpose. For AVDs, the most common images you’ll encounter include:
system.img: Contains the Android OS framework, core applications, libraries, and binaries. This is our primary target for modification.vendor.img: Houses hardware abstraction layer (HAL) implementations and other vendor-specific components.product.img: Contains product-specific resources and apps.ramdisk.img: A small root filesystem loaded into RAM during boot, responsible for initializing the system and mounting other partitions.
These images are usually stored in a sparse format to save disk space, meaning they only store non-zero data blocks. To work with them, we first need to convert them into a raw, mountable disk image format.
Prerequisites and Essential Tools
To follow this guide, you will need a Linux-based operating system (Ubuntu or Debian recommended) and several command-line utilities:
simg2img: Converts Android sparse images to raw disk images. Part ofandroid-tools-fsutils.img2simg: Converts raw disk images back to sparse format. Also part ofandroid-tools-fsutils.mount/umount: Standard Linux commands for managing filesystems.rsync: A versatile file copying tool, crucial for preserving permissions and ownership during content transfer.e2fsprogs: Provides utilities likemkfs.ext4for creating EXT4 filesystems.du: Disk usage utility for calculating directory sizes.- Android SDK Platform Tools: Specifically
adbfor interacting with the emulator.
Install the necessary tools:
sudo apt update
sudo apt install android-tools-fsutils rsync e2fsprogs
Step 1: Unpacking the System Image
First, locate your AVD system image files. They are typically found in your AVD directory, often under ~/.android/avd/YOUR_AVD_NAME.avd/. The image files are usually named system.img, vendor.img, etc.
For this tutorial, we will focus on system.img. Navigate to your AVD directory and convert the sparse image to a raw image:
cd ~/.android/avd/YOUR_AVD_NAME.avd/
simg2img system.img system.raw.img
Next, create a mount point and mount the raw image:
sudo mkdir /mnt/system_original
sudo mount -o loop system.raw.img /mnt/system_original
Now, to safely make modifications, we’ll copy the entire content of the mounted filesystem to a new working directory:
mkdir ~/system_working
sudo rsync -a --progress /mnt/system_original/ ~/system_working/
Once the copy is complete, unmount the original raw image:
sudo umount /mnt/system_original
Step 2: Modifying the System Image Content
All your modifications will now be performed within the ~/system_working/ directory. Here are some common modification examples:
Example 1: Modifying build.prop
The build.prop file contains system-wide build parameters. You might want to enable additional debug options, change device properties, or set system flags. For instance, to enable root ADB:
cd ~/system_working
sudo nano build.prop
Add or modify the following lines (adjust as needed):
ro.debuggable=1
ro.secure=0
persist.sys.usb.config=mtp,adb
adb.root=1
Example 2: Adding a Custom Binary or Script
Let’s say you want to add a custom script that runs early in the boot process (note: /etc/init.d support might require further system modifications on newer Android versions, but this demonstrates the file placement process). Create a simple script:
cd /tmp
nano custom_boot_script.sh
Content for custom_boot_script.sh:
#!/system/bin/sh
# This custom script runs during boot
echo "Custom boot script executed successfully!" > /data/local/tmp/custom_boot.log
setprop custom.property.value "my_custom_data"
# Example: Replace a system utility (use with extreme caution)
# cp /data/local/tmp/my_custom_ls /system/bin/ls
# chmod 755 /system/bin/ls
Now, copy it into your working system image directory and set appropriate permissions:
sudo cp /tmp/custom_boot_script.sh ~/system_working/etc/init.d/99custom_boot
sudo chmod 755 ~/system_working/etc/init.d/99custom_boot
Remember to set correct permissions (`chmod`) and ownership (`chown`) for any files you add or modify. Incorrect permissions can lead to boot failures or unexpected behavior.
Step 3: Repacking the Modified System Image
Once all modifications are complete within ~/system_working/, it’s time to repack it into a new sparse image.
First, calculate the exact size required for your new raw image based on the modified contents. We’ll use du to get the directory size in kilobytes, then convert to bytes, and ensure we have enough blocks.
cd ~
NEW_SIZE_KB=$(sudo du -sk system_working/ | awk '{print $1}')
NEW_SIZE_BYTES=$((NEW_SIZE_KB * 1024))
BLOCK_SIZE=4096 # Standard EXT4 block size
BLOCK_COUNT=$(( (NEW_SIZE_BYTES + BLOCK_SIZE - 1) / BLOCK_SIZE )) # Round up block count
Now, we’ll create a new raw EXT4 image from the system_working directory using genext2fs. This tool is excellent for building a filesystem image directly from a directory structure while preserving metadata.
NEW_RAW_IMAGE="new_system.raw.img"
genext2fs -d system_working -b "${BLOCK_COUNT}" -N 0 -i 1024 "${NEW_RAW_IMAGE}"
-d system_working: Specifies the directory containing the filesystem data.-b BLOCK_COUNT: Sets the number of blocks in the filesystem.-N 0: Instructsgenext2fsto automatically calculate the number of inodes.-i 1024: Sets the ratio of bytes-per-inode, ensuring sufficient inodes for files.
Finally, convert the newly created raw image back into a sparse image format that AVDs expect:
NEW_SPARSE_IMAGE="new_system.img"
img2simg "${NEW_RAW_IMAGE}" "${NEW_SPARSE_IMAGE}"
Step 4: Deploying and Testing the Custom Image
The final step is to deploy your custom new_system.img to your AVD. Navigate back to your AVD’s directory:
cd ~/.android/avd/YOUR_AVD_NAME.avd/
It’s crucial to back up your original system.img before replacing it:
mv system.img system.img.bak
Now, copy your new image into place:
mv ~/new_system.img .
Start your Android Emulator:
emulator -avd YOUR_AVD_NAME
Once the emulator boots, use adb shell to verify your modifications:
adb shell
cat /system/build.prop | grep "ro.debuggable"
ls /system/etc/init.d/99custom_boot
cat /data/local/tmp/custom_boot.log # Check if script ran
For Anbox or Waydroid, the deployment process might involve replacing the system.img file within their respective image directories, often located in /var/lib/anbox/images/ or specific Waydroid installation paths. Consult their documentation for precise integration steps, as they sometimes use raw images directly (new_system.raw.img) instead of sparse ones.
Conclusion
Reverse engineering AVD system images offers a gateway to profound control over your Android emulation environments. By mastering the process of unpacking, modifying, and repacking these critical binaries, you can tailor Android to your exact specifications, whether for specialized application testing, custom ROM development, security vulnerability research, or optimizing compatibility with containerized solutions like Anbox and Waydroid. While powerful, remember that system-level modifications carry risks; always back up your original images and proceed with caution to maintain system stability and functionality.
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 →