Skip to content

Glossary

Write-ahead log (WAL)

SQLite's journaling mode in which committed changes are appended to a separate -wal file before being copied into the main database at a checkpoint.

The write-ahead log is one of SQLite's journaling modes. Instead of changing the database file directly, SQLite appends each modified page as a frame to a separate file named <database>-wal, and leaves the main file untouched until a checkpoint copies the pages back (sqlite.org). Readers combine both: for each page, they use the newest committed version in the WAL if there is one, and the database file otherwise. A third file, -shm, is a shared-memory index that SQLite can rebuild and that holds no extra evidence.

The WAL starts with a 32-byte header (magic number, page size, checkpoint sequence, two salt values and checksums). Each frame is a 24-byte header followed by one full page. The frame header records the page number, a commit marker, the salts and cumulative checksums, which let a reader ignore uncommitted transactions and frames left over from an older WAL generation.

Why it matters in investigations

wpndatabase.db runs in WAL mode. The newest notifications are therefore often only in wpndatabase.db-wal, and a database copied without its WAL, or at a different moment, loses them or mixes states. The WAL can also hold several versions of the same page: older frames may still contain notification rows that were deleted later, which makes them a source for recovery alongside freeblocks and the freelist.

Example

wpndatabase.db-wal
  WAL header (32 bytes): salt-1, salt-2 ...
  Frame 1: page 5, not a commit frame
  Frame 2: page 4, commit frame     -> transaction 1 committed
  Frame 3: page 4, commit frame     -> newer version of page 4
  Frame 4: page 9, no commit follows -> ignored

Here page 4 exists in three versions: the file's, frame 2's and frame 3's. The parser applies frames 1 to 3, flags rows that are only or differently in the WAL, and carves the older versions for deleted rows.

Load the database with its -wal in the Windows Notification Parser, and follow the acquisition guide to collect both at the same instant.