Three paths, in order from cleanest to most-limited:
- Rooted device —
dda partition. Best results. - Non-rooted device —
adb backup→.abfile → NullVeil'sunwrap-absubcommand. - External SD card from the phone — pop the card and treat it as external storage (use the SD card tutorial).
If the phone is rooted or you're working with a development device, you can copy the storage partition straight off. The two interesting partitions are:
- /data/userdata — app data, SQLite databases, app-private files. Usually ext4 or F2FS.
- /sdcard (often a bind-mount of
/data/media) — user files (photos, downloads). FAT or exFAT historically, ext4-backed virtual FAT today.
# On your desktop, pair the phone over adb
adb devices
# List of devices attached
# R3CN10ABCDE device
# Drop into a root shell on the phone
adb shell
su # becomes root# On the phone (in adb shell, as root):
ls -l /dev/block/by-name/ # find the partition we want
# Example output:
# userdata -> /dev/block/sda14
# Stream the partition over adb back to the desktop
exit # leave the root shell first
adb exec-out "su -c 'dd if=/dev/block/by-name/userdata bs=4M'" \
> ~/android-userdata.img 2> ~/dd.logFor very large partitions (128GB+), use --exec-out with pv:
adb exec-out "su -c 'dd if=/dev/block/sda14 bs=4M'" \
| pv -s 60G > ~/android-userdata.imgsha256sum ~/android-userdata.img | tee ~/android-userdata.img.sha256
nullveil info ~/android-userdata.img
# Should report: filesystem ext4 label="userdata" …
# Live + deleted listing
nullveil ls --deleted ~/android-userdata.img
# Recover (ext4 deletion zeroes extent pointers — expect best-effort)
nullveil recover ~/android-userdata.img \
--include-deleted \
--out ~/android-recovered/ \
--verify
# Fall through to signature carving for anything per-FS recovery missed
nullveil carve ~/android-userdata.img \
--out ~/android-carved/ \
--types jpg,png,sqlite,pdf,docx,zip
/sdcardis special. On modern Android (10+),/sdcardis no longer a real partition — it's a FUSE / emulation layer on top of/data/media/0. Dumping/data/media/0/viaadb pull -ais usually easier thandd-ing the underlying block.
On non-rooted Android (5.0 → 11), adb backup produces a single .ab
archive of app data. Android 12+ phased out adb backup for most apps,
but it still works on Android <12 devices and on apps with
android:allowBackup="true".
# On the desktop, with the phone unlocked and USB debugging on:
adb backup -all -apk -obb -shared -system -f phone.ab
# The phone screen asks for a passcode (optional). Leave it empty for an
# unencrypted backup that NullVeil can read directly. If you set a
# password, decrypt it later with abe.jar.This is the feature added specifically for mobile workflows:
nullveil unwrap-ab phone.ab --out ~/phone-extracted/Sample output:
unwrapped Android Backup v5 (deflate compression)
→ 1,247 files, 412 directories, 1.8 GiB bytes
→ /Users/you/phone-extracted/
The layout you get:
~/phone-extracted/
├── apps/
│ ├── com.whatsapp/
│ │ ├── _manifest
│ │ ├── sp/com.whatsapp_preferences.xml
│ │ └── db/msgstore.db
│ ├── com.example.notes/
│ └── …
└── shared/
└── 0/
├── Pictures/
│ ├── IMG_20240301_092314.jpg
│ └── …
└── Documents/
App-private data lives under apps/<package>/; SD-card content lives
under shared/0/.
unwrap-ab produces plain files; there's no filesystem-undelete pass to
do on it (a tar archive doesn't have deleted entries). What you can do
is point downstream tools at individual artefacts:
# WhatsApp messages
sqlite3 ~/phone-extracted/apps/com.whatsapp/db/msgstore.db ".tables"
# Browser history
sqlite3 ~/phone-extracted/apps/com.android.chrome/db/History "SELECT * FROM urls"
# Carve photos that may have been deleted from a SQLite cache
nullveil carve ~/phone-extracted/apps/com.example.gallery/files/cache.db \
--out ~/phone-cache-carve/ \
--types jpg,pngIf you set a password during adb backup, the .ab is AES-256 encrypted
and NullVeil refuses it:
error: this backup is AES-256 encrypted; NullVeil does not decrypt it.
Decrypt with `abe.jar` first, then re-run on the resulting plain .ab
Use Android Backup Extractor
(abe.jar) to decrypt:
java -jar abe.jar unpack phone.ab phone-plain.tar # rewraps as plain tar
# Or, to keep .ab format:
java -jar abe.jar unpack phone.ab phone-plain.ab # plain .abThen run nullveil unwrap-ab phone-plain.ab --out ~/phone-extracted/.
If the phone has a removable SD card and that's where the lost data was, pop the card and use the SD-card recovery tutorial.
The SD card is almost always FAT32 or exFAT and is the cleanest case for NullVeil: full deleted-file recovery, plus carving for media files.
-
adb backupis being phased out. Android 12+ excludes most apps from backups (android:allowBackup="false"is the new default). For modern Android, the rooted-ddpath is increasingly the only productive option. -
Photos in
/sdcard/DCIM. Modern Android storesMediaStoremetadata in/data/data/com.android.providers.media.module/databases/external.db. If a photo "disappears from the Gallery" but is still on disk, what changed is the database row, not the file. Image the database, query it (or use the Photos app's Trash), recover the file. -
F2FS partitions. Newer Android devices use F2FS for
/data. NullVeil detects FAT/NTFS/ext/APFS but not F2FS today. Carving still works — pointnullveil carveat the F2FS image and recover by signature. F2FS undelete support is on the roadmap. -
Encrypted user data. Most modern Android devices have File-Based Encryption (FBE) on
/data. If the device is locked when youdd, the partition image is mostly ciphertext. Image after unlock and ideally while the user is signed in — then the kernel has the key loaded and reads through the encrypted layer return plaintext.
- iOS workflow — the other phone OS.
- Carving deep-dive — what carving can do when filesystem-level recovery falls short.
unwrap-abreference — every flag of the new subcommand.