Skip to content

ActivitiesCache.db-wal: Warum die WAL-Datei zählt

Wie das SQLite-Write-Ahead-Log die jüngste Windows-Timeline-Aktivität in ActivitiesCache.db-wal verbirgt, wie Checkpoints arbeiten und wie man es auswertet.

Veröffentlicht am 7 Min. Lesezeit

Kurz gesagt. ActivitiesCache.db läuft im WAL-Modus von SQLite: Bestätigte Änderungen landen in ActivitiesCache.db-wal und erreichen die Hauptdatei erst bei einem Checkpoint (standardmäßig, wenn das WAL 1.000 Seiten erreicht). Auf einem laufenden oder kürzlich genutzten System steht die jüngste Aktivität oft nur im WAL. Sichern Sie beide Dateien zum selben Zeitpunkt, öffnen Sie die Originale nie mit einem normalen SQLite-Client und verwenden Sie einen Parser, der bestätigte Frames einspielt und anzeigt, welche Zeilen aus dem WAL stammen.

Wenn Sie aus dieser Serie nur eines mitnehmen, dann das: Eine Windows Timeline ohne ihr WAL ist eine Timeline, die zu früh endet. Und „zu früh“ heißt meist „kurz vor dem Vorfall“, weil der Vorfall jung ist.

Wie Write-Ahead-Logging funktioniert

Das Write-Ahead-Log von SQLite kehrt das klassische Journal um. Statt Originalseiten beiseitezulegen und Änderungen in die Datenbank zu schreiben, lässt SQLite die Datenbank unberührt und hängt geänderte Seiten an eine separate -wal-Datei an. Eine Transaktion gilt als bestätigt, sobald ihr Commit-Datensatz im WAL steht (sqlite.org/wal.html).

Leser suchen jede Seite zuerst im WAL und greifen sonst auf die Datenbankdatei zurück. Das Zurückschreiben der Seiten in die Datenbank heißt Checkpoint. Standardmäßig löst SQLite ihn automatisch aus, wenn ein Commit das WAL über 1.000 Seiten wachsen lässt (sqlite.org). kacos2000 beobachtete dasselbe bei dieser Datenbank und stellte in den untersuchten Dateien eine Seitengröße von 4.096 Byte fest (kacos2000).

Diagramm: Datenbankseiten p1 bis p6, WAL-Frames für p3, p7 und ein bestätigtes p5, gefolgt von einem unbestätigten p6, das ignoriert wird; die zusammengeführte Ansicht nimmt p3, p5 und p7 aus dem WAL
Bestätigte WAL-Frames überdecken Datenbankseiten; unbestätigte Frames werden ignoriert.

Was das für Timeline bedeutet:

SituationWo die neuesten Zeilen stehen
Benutzer aktiv, WAL unter der Checkpoint-SchwelleNur im WAL
Checkpoint gerade gelaufenIn der Datenbank; das WAL kann zurückgesetzt und wiederverwendet werden
Letzte Verbindung sauber geschlossenZurückgeschrieben; das WAL wird „normalerweise“ gelöscht (sqlite.org)
Absturz, Stromausfall, Stecker gezogenDas WAL kann mit bestätigten, nicht zurückgeschriebenen Transaktionen auf der Platte bleiben (sqlite.org)

Eine Timeline-Zeile wird nicht nur einmal eingefügt. Eine Fokussitzung (Typ 6) wird aktualisiert, solange sie andauert: EndTime und activeDurationSeconds wachsen. Auch diese Aktualisierungen landen zuerst im WAL. Das WAL bestimmt also nicht nur, welche Zeilen existieren, sondern auch, was sie aussagen.

Im Inneren der WAL-Datei

Das Format ist in der SQLite-Dateiformatspezifikation dokumentiert:

StrukturGrößeRelevante Felder
WAL-Header32 ByteMagic, Seitengröße, Checkpoint-Sequenznummer, Salt-1, Salt-2, Prüfsumme
Frame-Header24 ByteSeitennummer, Datenbankgröße nach dem Commit (nur bei Commit-Frames ungleich null), Salts, kumulative Prüfsumme
Frame-Inhalteine SeiteDie neue Version dieser Datenbankseite

Ein Frame ist nur gültig, wenn seine Salts zum Header passen und seine kumulative Prüfsumme stimmt. Ein Frame mit einem Feld „Datenbankgröße“ ungleich null ist ein Commit-Frame: Er schließt eine Transaktion ab. Frames nach dem letzten Commit-Frame gehören zu einer nie bestätigten Transaktion und müssen ignoriert werden (sqlite.org).

Nach einem Checkpoint, wenn der nächste Schreiber das WAL zurücksetzt, wird Salt-1 erhöht und Salt-2 zufällig neu gesetzt, was die alten Frames ungültig macht. Laut Spezifikation kann die Datei dabei gekürzt werden, muss aber nicht (sqlite.org). Genau hier liegt die forensische Chance: Frames früherer Generationen können hinter den aktuellen noch vorhanden sein.

Warum ein normaler SQLite-Client das falsche Werkzeug ist

ActivitiesCache.db mit einer gewöhnlichen SQLite-Bibliothek zu öffnen, funktioniert, und sie liest sogar das WAL mit, wenn es neben der Datenbank liegt. Das Problem ist, was danach passiert. Laut SQLite-Dokumentation führt die zuletzt geschlossene Verbindung einen letzten Checkpoint aus und löscht dann das WAL und die zugehörige Shared-Memory-Datei (sqlite.org/wal.html).

Anders gesagt: Schon das Hineinschauen kann die Datenbank umschreiben und das WAL vernichten, samt veralteter Frames mit älteren Daten. Faustregeln:

  • Hashen Sie die Originale und arbeiten Sie mit Kopien.
  • Wenn Sie einen SQLite-Client nutzen müssen, öffnen Sie eine Kopie oder verwenden Sie die Modi „read-only“ bzw. „immutable“ auf einer Kopie, die Sie opfern können.
  • Bevorzugen Sie einen Parser, der die Bytes selbst liest und nie schreibt.

Wie der Windows Timeline Parser mit dem WAL umgeht

Der Windows Timeline Parser bringt einen eigenen, rein lesenden SQLite-Leser mit, geschrieben in Rust und nach WebAssembly kompiliert. Er enthält keine SQLite-Engine und keinen Codepfad, der schreibt. Mit dem WAL:

  1. Prüft er Magic, Seitengröße und Header-Prüfsumme des WAL.
  2. Durchläuft er die Frames, solange die Salts passen und die kumulative Prüfsumme stimmt.
  3. Legt er die letzte bestätigte Version jeder Seite über die Datenbank; Frames einer unbestätigten Transaktion werden gezählt und ignoriert.
  4. Wertet er das Ergebnis aus, anschließend die Datenbank ohne WAL, und vergleicht Zeile für Zeile.
  5. Markiert er jede Zeile als Nur im WAL (neu seit dem letzten Checkpoint) oder Im WAL geändert (die Datenbank enthält eine ältere Version).

Außerdem schützt er vor einem klassischen Fehler: einem -wal aus einer anderen Datenbank. Nichts im Dateiformat bindet ein WAL an seine Datenbank; ein naiver Leser würde ein WAL mit gleicher Seitengröße stillschweigend anwenden. Das Werkzeug prüft, ob die eingespielte Datenbank noch eine plausible Timeline ist, und ignoriert das WAL andernfalls mit einer Warnung.

Diese Markierungen machen aus „das WAL zählt“ praktische Triage. Filtern Sie auf Nur im WAL, und Sie sehen die Aktivität seit dem letzten Checkpoint; bei einem im laufenden Zustand gesicherten Rechner sind das oft die letzten Stunden vor der Sicherung.

Was das WAL enthalten kann, das Ihnen niemand zeigt

Drei Arten von Daten können im WAL oder in dessen Umfeld überdauern:

DatenWoWertet dieses Werkzeug sie heute aus?
Bestätigte, nicht zurückgeschriebene ZeilenAktuelle WAL-FramesJa
Unbestätigte TransaktionFrames nach dem letzten CommitGezählt, ignoriert (bewusst)
Ältere SeitenversionenFrames einer früheren Salt-GenerationNein (gemeldet, nicht gecarvt)
Gelöschte ZeilenFreeblocks und Freelist-Seiten der DatenbankNein

Forschung zur SQLite-Wiederherstellung, etwa die auf der DFRWS vorgestellte Arbeit zu bring2lite, zeigt, dass sich gelöschte Datensätze aus diesen Strukturen wiederherstellen lassen (Meng und Baier, 2019). Das Zwischenablage-Carving-Werkzeug von kacos2000 stellt laut Autor gelöschte Einträge sowohl aus der Datenbank als auch aus dem WAL wieder her (kacos2000/WindowsTimeline). Hängt Ihr Fall an gelöschten Timeline-Daten, arbeiten Sie mit einer Kopie und einem Carving-Werkzeug und dokumentieren Sie die Methode getrennt von der Zeitachse der aktiven Datensätze.

Checkliste

  • ActivitiesCache.db und ActivitiesCache.db-wal zum selben Zeitpunkt gesichert (Sicherungsleitfaden).
  • Originale gehasht; Auswertung nur an Kopien.
  • Der Parser meldet, wie viele Frames bestätigt, wie viele ignoriert wurden und warum er stoppte.
  • Der Bericht unterscheidet Zeilen, die nur im WAL stehen, von zurückgeschriebenen Zeilen.
  • Veraltete WAL-Frames und freie Seiten für Carving aufbewahrt, falls Löschungen relevant sind.

FAQ

Was ist ActivitiesCache.db-wal?

Das SQLite-Write-Ahead-Log der Windows-Timeline-Datenbank. Bestätigte Änderungen werden zuerst dort angehängt und erst bei einem Checkpoint nach ActivitiesCache.db kopiert, daher enthält das WAL oft die jüngste Aktivität.

Ist es sicher, ActivitiesCache.db in DB Browser for SQLite zu öffnen?

Nur mit einer Kopie. Eine normale SQLite-Verbindung liest das WAL neben der Datenbank und kann es beim Schließen der letzten Verbindung in die Hauptdatei zurückschreiben und löschen, was die Dateien verändert.

Kann das WAL gelöschte Aktivität enthalten?

Ja, das ist möglich. Alte Frames früherer WAL-Generationen werden durch einen geänderten Salt ungültig, aber nicht zwingend überschrieben, und können ältere Seitenversionen enthalten. Ihre Wiederherstellung erfordert Carving-Werkzeuge; die meisten Parser ignorieren sie.

Verwandte Artikel

Verwandte Artikel

Wo die Beweiskraft von Windows Timeline endet: Ablauf, Einstellungen, gelöschter Verlauf, entfernte Zeilen, fehlendes WAL, Parser-Grenzen und Manipulation.
Feldreferenz zu ActivitiesCache.db: ActivityType 5, 6, 10 und 16, das AppId-JSON, Payload-Schlüssel wie activeDurationSeconds und alle Zeitspalten.
Leitfaden zur Windows-Timeline-Forensik: was ActivitiesCache.db speichert, wo die Datei liegt, warum die -wal-Datei zählt und wie Sie sie auswerten.