
Turn Android SMS JSON Backup into Readable Chat Archives
Table of Contents
TL;DR
- I pull an uncompressed Android SMS backup with adb and keep it encrypted with AES-256.
- I unpack the backup with Android Backup Extractor, unzip the Zlib files, and get five JSONs.
- I use a custom Bash viewer (smsviewer.sh) that leverages FZF and jq to browse conversations in the terminal.
- I can export the cleaned chat to plain-text file.
Why this matters
When I’m chasing a lead or verifying an alibi, I have to sift through millions of SMS messages. Raw backup.ab files are a wall of binary and JSON that even the most patient analyst can’t read. They’re encrypted, split, and compressed. If you can turn that chaos into a clean, scroll-able archive, you save hours of manual work and reduce the chance of overlooking a critical message.
Core concepts
The process is a chain of four transformations:
| Step | Tool | Purpose | Limitation |
|---|---|---|---|
| 1 | adb | Pull an encrypted, optionally uncompressed, Android backup | adb backup is deprecated on newer Android versions and may not work on the latest builds. |
| 2 | Android Backup Extractor | Unpacks the proprietary .ab into a .tar of app data | Only supports Android 5+ backups; you must provide the device password. |
| 3 | decompress.sh (Python 3 + Zlib) | Decompresses five zlib-compressed files into plain JSON | Requires a recent Python 3 installation; decompression can be slow on large backups. |
| 4 | smsviewer.sh (FZF + jq) | Interactive terminal viewer that renders colored chat, sorts by timestamp, and exports text | Works only with the com.android.providers.telephony package and SMS-only backups. |
I call the final product a human-readable chat archive. It’s a simple list of messages, sorted by timestamp, with the contact name, direction, and a color that tells you whether it was sent or received.
How to apply it
I broke the workflow into three phases: setup, extraction, and viewing.
1. Set up the environment
# 1. Update the package list
sudo apt update
# 2. Install the command-line fuzzy finder
sudo apt install -y fzf # [junegunn/fzf — FZF (2025)]
# 3. Install jq for JSON processing
sudo apt install -y jq # [stedolan/jq — jq (2025)]
# 4. Verify Java is present (required by ABE)
java --version # [OpenJDK — Java Runtime Environment (2025)]
# 5. Grab the latest Android Backup Extractor JAR
wget https://github.com/nelenkov/android-backup-extractor/releases/download/abe-5.0.0/AndroidBackupExtractor.jar
If you’re on a fresh Kali image, Java is usually pre-installed, but I always double-check.
2. Pull an encrypted, uncompressed backup
# List the backup-able packages to make sure the SMS provider is available
adb shell pm list packages | grep com.android.providers.telephony
# Pull the backup. The --no-compress flag keeps the file size small.
adb backup -f backup.ab --no-compress com.android.providers.telephony
During the backup you’ll see a confirmation prompt on the phone. If you want the backup to stay encrypted, set a password. The backup will be an AES-256 blob – the file header says it’s Android backup version 5 – and will look like gibberish:
backup.ab
└─ 0x00000000: 0x78 0x9c 0x5d 0x7a 0x5e 0x... (encrypted)
3. Unpack the backup
# ABE requires Java, so we run it with the JAR we downloaded
java -jar AndroidBackupExtractor.jar unpack backup.ab backup.tar
ABE will ask for the password you set earlier. After a few seconds you’ll have backup.tar, which contains:
apps/com.android.providers.telephony/_manifest
apps/com.android.providers.telephony/d_f/000000_sms_backup
apps/com.android.providers.telephony/d_f/000001_sms_backup
...
The _backup files are still zlib-compressed. You need to decompress them.
4. Decompress with Python 3
# The repo ships a small helper script; just run it
chmod +x decompress.sh
./decompress.sh
decompress.sh pulls zlib from Python 3 and expands each file into decompressed/000000.json, decompressed/000001.json, …, decompressed/000004.json. The JSON structure looks like:
{
"thread_id": 123456,
"timestamp": 1678923456000,
"address": "+15551234567",
"body": "Hey, are you coming?",
"type": 1
}
All timestamps are in milliseconds since the epoch. To read them as normal dates, you can let smsviewer.sh do the math.
5. View the archive in the terminal
chmod +x smsviewer.sh
./smsviewer.sh
The script boots up FZF, shows you a list of unique contacts, and lets you pick one. Once a contact is selected, the rest of the script:
- Joins all JSON files belonging to that thread.
- Sorts by timestamp (ascending).
- Converts the epoch milliseconds to human-readable UTC (YYYY-MM-DD HH:MM).
- Colors messages: blue for sent, green for received.
- Paginates with less -R.
The output feels like a normal chat app:
[2023-03-14 09:12] +15551234567 : Hey, are you coming?
[2023-03-14 09:13] +15551234567 : I’m on the way!
When you’re done, press Ctrl-X to export the conversation to a plain-text file (conversation.txt). The file is ready for forensic report or for importing into a spreadsheet.
Pitfalls & edge cases
| Problem | Why it happens | Mitigation |
|---|---|---|
| adb backup fails on Android 12+ | The command is officially deprecated and may be blocked by a device lock screen. | Use adb backup -f on a rooted device or use ADB over Wi-Fi with adb root if you have root. |
| Backup password lost | If you forget the password, the encrypted .ab is useless. | Store the password in a secure password manager. |
| Decompression errors | Zlib errors if the file is corrupted or truncated. | Verify the SHA-256 of the .ab against the one shown in the ABE output. |
| Timestamps in UTC vs local | The raw timestamps are in UTC; your local time zone may differ. | Convert to your local zone with date -d @ |
| Very large backups | 10 GB+ backups can take hours to unpack and decompress. | Use a fast SSD, and run the script in a screen or tmux session to avoid session drops. |
I’ve seen people get stuck on the “cannot find java” error. That usually means the $JAVA_HOME variable isn’t set, or the JRE is older than Java 11 – ABE requires Java 11 or newer.
Quick FAQ
| Question | Answer |
|---|---|
| What is ADB? | Android Debug Bridge is a command-line tool that lets you communicate with an Android device, including pulling backups. Android Developers — ADB (2025) |
| Why is adb backup deprecated? | Google moved to encrypted cloud backups; the command is still usable on older Android versions but may not work on the latest builds. |
| Can I use this on iOS? | No. iOS uses a completely different backup format; you’ll need a different toolchain. |
| Does smsviewer.sh support MMS? | No, it only parses the sms table. For MMS you’ll need a separate extractor or the official “SMS Backup & Restore” app export. |
| How long does decompression take? | Depends on backup size; a 5 GB backup with 5 Zlib files typicaly takes 10–15 minutes on a mid-range laptop. |
| Can I run the entire pipeline with one script? | Yes, the Backup2Chat repo ships a run_all.sh that automates steps 2–5. |
| What if my backup is compressed with –compress? | You’ll have to pass –no-compress during the backup. If you already have a compressed file, you’ll have to decrypt it first and then decompress the zip archive. |
Conclusion
The key takeaway: if you’re a forensic analyst, penetration tester, or even an Android developer who wants to audit their own SMS history, you can convert a raw Android backup into a clean, color-coded chat archive in under an hour. The workflow hinges on four main tools—ADB, Android Backup Extractor, Python 3/Zlib, and a custom Bash viewer. Keep the tools up to date, secure your backup password, and you’ll have a reproducible pipeline that turns binary mess into a readable conversation you can export and analyze.
Next steps for me:
- Add a time-zone flag to smsviewer.sh so the timestamps match my local clock.
- Write a quick wrapper that pulls, extracts, and opens the viewer in one go.
- Share a Docker image that bundles all dependencies so the process is repeatable on any Linux distro.
If you’re new to Kali Linux, start by installing the packages above and experiment with a small backup. Once you’re comfortable, try it on a real case and see how much time you save.
References
- [junegunn/fzf — FZF (2025)]
- [stedolan/jq — jq (2025)]
- [OpenJDK — Java Runtime Environment (2025)]
- [Android Developers — ADB (2025)]
- [nelenkov/android-backup-extractor — Android Backup Extractor (2025)]
- [DouglasFreshHabian/Backup2Chat — Backup2Chat (2026)]
- [Zlib — Zlib Library (2025)]
- [Python.org — Python 3 (2025)]





