01The question
Can messages deleted from the chat with one contact be recovered from the handset, and over what period is recovery reliable?
02Background
In a fictional dispute at Delta Lojistik, one party says a chat thread was deleted. A full file-system extraction of the Android device was provided. The examination is limited to recovery and interpretation of the database; it does not address how the extraction was obtained.
03Constraints
- Only a file-system extraction was available, not a physical image, so unallocated flash space could not be carved.
- The database uses WAL journaling; recovery depends on whether a checkpoint had flushed the log.
- End-to-end transport encryption does not affect on-device recovery; the local database stores messages in readable form for the app.
04Evidence received
05Examination method
Preserve the database and its journal together
The main database and its -wal and -shm companions were copied as a set and hashed. Opening the database without the WAL present would have shown a stale view; the WAL holds pages not yet written back into the main file.
Read live rows and the schema
The message table's columns (identifier, chat key, direction, timestamp in milliseconds, text, media reference) were read so that recovered fragments could be interpreted the same way as live rows. The chat with the contact was identified by the contact's row in the chat list.
Recover deleted rows from the WAL and free list
Deleting a message marks its row's cell as free inside the b-tree page; the bytes often remain until the page is reused. The WAL frames and the freeblock chains in the main file were parsed to recover message text and timestamps that no longer appear in a normal query. Each recovered row was tagged with the page and offset it came from.
WhatsApp for Android messages (msgstore.db)Hex viewer and data inspectorTimestamp decoder
Convert timestamps and bound the reliable period
Millisecond timestamps were converted to UTC. Live rows gave a continuous record up to a point; recovered rows filled part of the gap. The earliest safely recoverable message set the start of the reliable window; older deletions whose pages had been overwritten could not be recovered and were reported as a gap, not as absence of messages.
WhatsApp for Android messages (msgstore.db)Timestamp decoderLocal time to UTC
06Findings
Established
Deleted messages exchanged with the contact were recovered for a bounded period, with text, direction and UTC timestamps.
BasisRecovered rows match the live table schema and carry page/offset references; timestamps are consistent with surrounding live rows.
Established
Some earlier messages in the thread could not be recovered because their database pages had been reused.
BasisThe free-list and WAL no longer held those pages' prior contents.
Probable
The thread was deleted as a block rather than message by message over time.
BasisRecovered rows cluster on a small set of freed pages with close free timings, which fits a single bulk deletion better than scattered deletions.
07Limits
- Recovery is partial by nature; non-recovery of a message is not proof it never existed.
- Without a physical image, data in unallocated flash outside the database file could not be examined.
- Recovered text is attributed to the account on the device; it does not by itself prove who was holding the phone.
- A message's local timestamp reflects the device clock, which can be wrong or changed.
08Report excerpt
Forty-one messages that do not appear in a normal query were recovered from freed pages of msgstore.db and from WAL frames, each tagged with its page and offset. They cover 2026-… to 2026-…. Messages before that date in this thread could not be recovered: their pages had been reused, so we report a gap, not an absence.
09Lessons
- Always preserve the -wal and -shm files with the database; without them the view is stale.
- Tag every recovered row with its page and offset so the recovery can be repeated and checked.
- Report non-recovery as a gap with its cause, never as proof a message did not exist.