Skip to content

Forensique de Windows.db : SQLite, WAL et base gather

L'index de Windows 11 en forensique : comment s'articulent Windows.db, Windows.db-wal et Windows-gather.db, ce que révèle le WAL et comment le préserver.

Publié le 7 min de lecture

En bref. Sous Windows 11, l'index Windows Search est une base SQLite en mode WAL (journal d'écriture anticipée). Windows.db contient le magasin de propriétés (SystemIndex_1_PropertyStore + _Metadata). Windows.db-wal contient les transactions validées pas encore checkpointées dans la base. Windows-gather.db (+ son propre WAL) contient les tables du gatherer, SystemIndex_Gthr et SystemIndex_GthrPth. Collectez-les ensemble. Lisez la base avec le WAL pour l'état actuel, et comparez avec la base sans le WAL pour voir ce que les dernières transactions ont ajouté, modifié ou retiré. N'ouvrez jamais les originaux dans un client SQLite classique : il peut checkpointer et effacer cet historique.

Les fichiers

FichierContenu
Windows.dbSystemIndex_1_PropertyStore (WorkId, ColumnId, Value) et SystemIndex_1_PropertyStore_Metadata (ColumnId → nom de propriété, type de stockage)
Windows.db-walJournal WAL de Windows.db
Windows.db-shmIndex en mémoire partagée du WAL. Inutile ; reconstruit à partir du WAL.
Windows-gather.dbSystemIndex_Gthr (ScopeID, DocumentID, FileName, LastModified, TransactionFlags…) et SystemIndex_GthrPth (Scope, Parent, Name)
Windows-gather.db-walJournal WAL de la base gather
Windows-usn.db et autresBases annexes

Les noms de tables et de colonnes proviennent de recherches publiques : l'article de Stroz Friedberg de 2023 et l'article de Kaspersky sur les artefacts de Windows 11. Microsoft ne documente pas le schéma. Les octets 18 et 19 de l'en-tête SQLite valent tous deux 2 quand une base est en mode WAL : un moyen rapide de confirmer qu'il vous faut le fichier -wal.

Comment fonctionne le WAL (ce qui compte)

D'après la documentation WAL de SQLite et la spécification du format de fichier :

  • Une écriture ne modifie pas Windows.db. SQLite ajoute les nouvelles versions des pages modifiées à Windows.db-wal, sous forme de trames (frames).
  • Une transaction est validée quand sa dernière trame est écrite avec un marqueur de commit (la taille de la base après validation).
  • Un lecteur qui cherche une page prend la dernière trame validée de cette page dans le WAL ; s'il n'y en a pas, il lit la page dans la base.
  • Un checkpoint recopie la dernière version de chaque page dans la base. Par défaut, il a lieu quand le WAL atteint 1 000 pages, ou quand la dernière connexion se ferme.
  • Après un checkpoint, le WAL n'est normalement pas tronqué. SQLite recommence à écrire depuis le début et change les sels (salts) de l'en-tête. Les trames de la génération précédente situées au-delà de la nouvelle position d'écriture restent sur le disque jusqu'à être écrasées.

Chaque trame a un en-tête de 24 octets avec le numéro de page, le marqueur de commit, les deux sels et une somme de contrôle cumulative. C'est ainsi qu'un lecteur sait quelles trames sont valides, validées et actuelles.

Ce que cela apporte à l'enquêteur

1. L'état actuel

La base plus le WAL (trames validées uniquement), c'est ce que lirait le service Windows Search lui-même. C'est la vue sur laquelle rapporter. Sans le WAL, vous regardez peut-être un index vieux de quelques minutes, heures ou jours. En pratique, cela peut signifier que justement les fichiers créés pendant l'incident manquent.

2. Ce qui a changé récemment

Comparez la base seule avec la base plus le WAL :

ÉlémentLecture
Dans les deux, identiqueInchangé depuis le dernier checkpoint
Seulement avec le WALIndexé par une transaction récente : nouveau fichier, emplacement nouvellement indexé
Dans les deux, propriétés différentesRéindexé récemment : fichier modifié, consulté, renommé ou déplacé
Seulement sans le WALRetiré par une transaction récente : probablement supprimé ou exclu

Le Windows Search Index Parser fait cette comparaison pour vous et marque les éléments uniquement dans le WAL et modifiés dans le WAL. Il ne liste pas encore le troisième cas séparément ; comparer des exports avec et sans le WAL le fait apparaître.

3. Les anciennes versions de pages

Un même WAL peut contenir plusieurs trames pour la même page, issues de transactions successives. De plus, après un checkpoint et un redémarrage du WAL, des trames périmées de la génération précédente (avec d'anciens sels) peuvent subsister en fin de fichier. Les deux sont des sources potentielles de versions anciennes d'enregistrements, y compris d'enregistrements supprimés depuis. Les récupérer exige un outil de carving qui comprend le WAL. Le parseur n'applique que les trames valides et validées de la génération courante et ignore le reste, en indiquant pourquoi (changement de sel, somme de contrôle incorrecte, trames non validées) dans ses avertissements.

La base gather n'est pas optionnelle

Sans Windows-gather.db :

  • Vous perdez les chemins de dossiers issus de l'arbre d'étendues du gatherer. SystemIndex_GthrPth stocke chaque dossier sous la forme (Scope, Parent, Name) ; remonter les parents reconstruit le chemin, et SystemIndex_Gthr.FileName le complète.
  • Vous perdez le contrôle croisé entre magasin de propriétés et table gather (DocumentID = WorkId). Un élément présent dans le magasin mais absent de la table gather est l'un des meilleurs indicateurs « supprimé ? » ; voir les traces de fichiers supprimés.
  • Vous perdez la valeur LastModified propre au gatherer, un second avis sur la date de modification du fichier.

La base gather a son propre WAL. Collectez-le aussi. Le parseur associe Windows-gather.db et son -wal au Windows.db du même dossier : conservez l'arborescence quand vous collectez sur plusieurs machines.

Les erreurs qui détruisent la preuve

  • Ouvrir l'original dans une interface SQLite. La lecture peut être anodine, mais la fermeture de la dernière connexion déclenche par défaut un checkpoint : le WAL est fusionné dans la base et peut être supprimé. Travaillez sur une copie hachée.
  • Copier Windows.db et le WAL à des moments différents. Vous obtenez des trames qui ne correspondent pas aux pages de la base. Un lecteur rigoureux valide sels et sommes de contrôle et écarte le WAL. Le parseur vérifie aussi que le magasin de propriétés obtenu est vraisemblable et ignore, avec un avertissement, un WAL provenant d'une autre base.
  • Arrêter le service pour « déverrouiller » les fichiers. Un arrêt propre ferme les connexions, donc checkpointe. Vous obtenez un Windows.db bien rangé et plus de comparaison avant/après. Voir les options d'acquisition.
  • Donner le fichier -shm à vos outils comme s'il comptait. C'est un cache. Le parseur l'indique comme inutile.

Vérifier un parseur avec sqlite3

Sur une copie du dossier, le shell SQLite vous donne une vérité de référence pour des contrôles ponctuels :

-- property names
SELECT Id, Name FROM SystemIndex_1_PropertyStore_Metadata WHERE Name LIKE 'System.ItemPath%';

-- every property of one item
SELECT m.Name, hex(p.Value), p.Value
FROM SystemIndex_1_PropertyStore p
JOIN SystemIndex_1_PropertyStore_Metadata m ON m.Id = p.ColumnId
WHERE p.WorkId = 532;

Comme le shell applique le WAL, il montre l'état actuel ; copiez la base sans son WAL dans un dossier séparé pour interroger l'état checkpointé. Le shell peut checkpointer en sortant : sans importance sur une copie jetable, et une raison de plus de ne jamais le faire sur l'original.

Les limites honnêtes de l'outil sur ce point

La prise en charge de Windows 11 dans le Windows Search Index Parser repose sur des recherches publiques et a été testée sur des bases SQLite construites comme les vraies, y compris un WAL laissé non checkpointé. Le DDL exact, les codes de type de stockage au-delà du texte (11) et de l'entier / FILETIME (12), la reconstruction des chemins et l'ordre des octets du LastModified gather sont des heuristiques qui doivent encore être validées sur davantage de fichiers Windows.db réels. La récupération d'enregistrements depuis les pages de la freelist, les freeblocks ou les trames WAL périmées est sur la feuille de route, pas dans l'outil.

FAQ

Peut-on ouvrir Windows.db avec DB Browser for SQLite ou le shell sqlite3 ?

Oui, sur une copie. Un client SQLite classique applique le WAL à la lecture et peut le checkpointer dans la base puis le réinitialiser à la fermeture. Cela détruit la comparaison avant/après : ne le faites jamais sur la preuve originale.

Pourquoi mon Windows.db paraît-il presque vide ?

Soit le WAL n'a pas été collecté et l'essentiel du travail récent s'y trouve encore, soit l'outil utilisé ne lit pas les tables WITHOUT ROWID ou ne pivote pas les lignes de propriétés. Vérifiez la taille de Windows.db-wal et essayez un autre lecteur.

Articles liés

Articles liés