payload-dumper-rust 🦀
A fast and efficient Android OTA payload dumper written in Rust.
What does this do?
Ever downloaded an Android OTA update or custom ROM and needed to extract the system images from it? That's what this tool does. Android OTA files contain a payload.bin that packs all the partition images (like boot, system, vendor, etc.). This tool unpacks them so you can flash, modify, or analyze them.
Why should you use this?
- Fast: Parallel extraction uses all your CPU cores
- Memory efficient: Streams data instead of loading everything into RAM
- Network smart: Extract directly from URLs without downloading the whole file
- Flexible: Works with payload.bin files, ROM ZIPs, or direct URLs
- Reliable: Verifies extracted partitions to catch corruption
- Cross-platform: Linux, Windows, macOS, even Android (Termux)
Installation
Quick Install (Recommended)
Linux / macOS / Termux:
Windows (PowerShell):
powershell -NoExit -ExecutionPolicy Bypass -Command "Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/rhythmcache/payload-dumper-rust/main/scripts/install.ps1' | Invoke-Expression"
Download Pre-built Binaries
Grab the latest binary for your platform from releases.
Build from Source
Have Rust installed? Just run:
Or clone and build:
Binary will be at target/release/payload_dumper
Usage
Simple Examples
Extract everything from a payload file:
Extract from a ROM ZIP (no need to unzip first!):
Extract from a URL (downloads only what's needed):
Only extract specific partitions:
List what's inside without extracting:
Real-World Use Cases
Need just the boot image from a URL? (No need to download 3GB!)
This will only download the parts containing the boot partition (~50-100MB) instead of the entire 3GB file.
Extract with custom thread count:
Get metadata in JSON format:
# Creates metadata_dir/payload_metadata.json (~100KB)
Get FULL metadata (includes all operation details, can be large):
# Creates metadata_dir/payload_metadata.json (~1000KB)
Skip verification (faster but risky):
Sequential extraction (for debugging or low-memory systems):
Custom User-Agent for URLs:
All Options
Usage: payload_dumper [OPTIONS] <PAYLOAD_PATH>
Arguments:
<PAYLOAD_PATH> Path to payload.bin, ROM ZIP file, or direct URL
Options:
-o, --out <OUT> Output directory [default: output]
-i, --images <IMAGES> Comma-separated partition names to extract
-t, --threads <THREADS> Number of threads for parallel processing
-l, --list List all partitions without extracting
-m, --metadata[=<MODE>] Save metadata as JSON:
--metadata Compact mode (~100KB)
--metadata=full Full mode with all details
-P, --no-parallel Disable parallel extraction
-n, --no-verify Skip hash verification (faster but risky)
-U, --user-agent <AGENT> Custom User-Agent for HTTP requests
-h, --help Show help
-V, --version Show version
How It Works
Point it at a payload file (or ZIP/URL containing one), tell it what you want, and it extracts the partition images for you. Fast and simple.
Why Extract from URLs?
When you extract from a URL, it only downloads the parts it needs instead of the whole file.
Example: Want just the boot image from a 3GB OTA? This tool downloads ~150MB instead of 3GB. Perfect for:
- Quick partition extraction without full downloads
- CI/CD pipelines that need specific images
- Slow internet connections
- Saving bandwidth
Building from Source
Requirements:
- Rust toolchain (install from rustup.rs)
Build:
With all features:
Available features:
remote_zip- Extract from URLs (enabled by default)local_zip- Extract from local ZIP files (enabled by default)metadata- Metadata extraction support (enabled by default)
Troubleshooting
"Server doesn't support range requests"
- Some servers don't support partial downloads. Try downloading the file first.
Out of memory errors
- Try
--no-parallelor reduce--threadscount.
Extraction is slow
- Check if
--no-parallelis enabled. Remove it for faster extraction. - For remote extraction, slow speeds might be due to server throttling.
Credits
- Inspired by vm03/payload_dumper
- Protocol buffer definitions from Android's update_engine
License
Found a bug? Open an issue on GitHub.
Want to contribute? PRs are welcome!