1 Why phones are different
A USB stick hands you every sector, and you image it with dd. A phone does not. Its storage is
soldered in, encrypted with keys held inside the device, and protected by the operating system. What you can
copy depends on the method, the OS version and whether the phone is unlocked. That is why mobile work starts with
the question what level of acquisition do I have?
Once you have the files, the next surprise is how uniform they are. Almost every app keeps its data in SQLite databases, with a few property lists (iOS), XML preferences (Android) and JSON files around them. If you can read SQLite at the byte level, you can read most of a phone.
-wal + -shm; live rows, freeblocks, free pages, old WAL framesThe examples on these pages come from invented sample files: a chat app called Chatter (contacts Alex and
Sam), an Android backup, an iOS-style backup manifest and a location cache. They were written with Python's
sqlite3 module, so the bytes are what a real app would leave behind.
2 The pages
As on the file-system pages, every hex view is interactive: click a field to see its bytes, click a byte to see its field, and follow the → rows.
adb, Android backups, iTunes/Finder backups and why the -wal file matters.
SQLiteHeader, pages, b-trees, cells, varints and serial types; freeblocks and the freelist.
WAL & deleted chatsFrames, salts, checkpoints, and reading deleted messages from old frames.
LocationLocation caches, Takeout-style exports, epochs, time zones and accuracy radii.
3 Android and iOS at a glance
| Android | iOS | |
|---|---|---|
| App data | /data/data/<package>/ with databases/, shared_prefs/, files/ | /private/var/mobile/Containers/Data/Application/<UUID>/ with Documents/, Library/ |
| Shared storage | /sdcard/ (photos, downloads), readable over adb | Photos and files only through the system apps or a backup |
| Backup format | adb backup → .ab (header + zlib + tar), deprecated | iTunes/Finder backup folder: Manifest.db plus files named by SHA-1 |
| Settings files | XML in shared_prefs/ | Binary or XML property lists (.plist) |
| Typical timestamps | Unix milliseconds | Cocoa time: seconds since 2001-01-01 |
| System databases | e.g. mmssms.db (SMS), contacts2.db | e.g. sms.db, AddressBook.sqlitedb |
Paths and file names change between OS versions and apps. Treat this table as a starting point and verify on the version in front of you.
4 Ground rules
- Hash first. Hash every acquired file before you open anything, and work on copies.
- Databases come in threes.
chat.db,chat.db-walandchat.db-shmbelong together. Copy and hash all three. - Opening is writing. A normal SQLite tool may apply the WAL to the main file and delete it, which destroys exactly the old data you are looking for. The WAL page explains why.
- Record the method. Write down the acquisition level, tool and version, and the OS version. They decide what could be in your copy and what could not.
5 Warm-up
Two quick checks before the deep-dive pages.
An app keeps its chats in chat.db, in WAL mode. Which files do you acquire and hash?
See the ground rules in section 4.
All three. The newest rows and older versions of pages may exist only in the
-wal file. The -shm file is only an index into the WAL, but it records which frames
were in use when you copied the files, so it belongs to the evidence too.
An iOS database stores the time 810369000.5. From which moment does it count
seconds?
Check the "Typical timestamps" row of the table in section 3. As Unix seconds, 810 million would be a date in 1995.
iOS and macOS use Cocoa time, seconds since 2001-01-01 00:00 UTC, often with a fraction. 810,369,000.5 s after 2001-01-01 is 2026-09-06 06:30:00.5 UTC. The Location page converts between the formats.