Windows.edb ou Windows.db : l'index de Windows 10 et 11
Comment l'index Windows Search est passé du Windows.edb (ESE) de Windows 10 au Windows.db (SQLite) de Windows 11 : tables, structure, WAL et impact en DFIR.
En bref. Même modèle de données, conteneur différent. Windows 10 et antérieurs stockent l'index dans un seul fichier ESE, Windows.edb, avec une ligne large par élément dans SystemIndex_PropertyStore et des colonnes nommées comme 4447-System_ItemPathDisplay. Windows 11 le répartit dans des fichiers SQLite : Windows.db contient SystemIndex_1_PropertyStore sous forme de lignes étroites (WorkId, ColumnId, Value) plus une table de métadonnées qui nomme chaque ColumnId, et Windows-gather.db contient les tables gather. Les deux conservent les modifications récentes hors du fichier principal (journaux ESE contre WAL SQLite). Un parseur doit repivoter les lignes Windows 11 en un enregistrement par élément et lire le WAL, sinon il vous montre un index périmé.
Vue d'ensemble
| Windows 10 et antérieurs | Windows 11 | |
|---|---|---|
| Fichier principal | Windows.edb | Windows.db |
| Moteur | ESE (JET Blue) | SQLite |
| Table du magasin de propriétés | SystemIndex_PropertyStore (Windows 8+), SystemIndex_0A (Vista / 7) | SystemIndex_1_PropertyStore |
| Structure | Une ligne large par élément, une colonne par propriété | Une ligne par (WorkId, ColumnId, Value) |
| Noms des propriétés | Dans les noms de colonnes : 4447-System_ItemPathDisplay | Dans SystemIndex_1_PropertyStore_Metadata (Id, UniqueKey, Name…) |
| Tables gather | SystemIndex_Gthr, SystemIndex_GthrPth dans le même fichier | Mêmes tables dans Windows-gather.db |
| Modifications récentes | Journaux de transactions MSS*.log, base parfois « dirty » | Windows.db-wal, Windows-gather.db-wal |
| Enregistrements supprimés | Entrées « defunct » et pages libres dans le fichier ESE | Pages de la freelist, freeblocks, anciennes trames WAL |
| Documentation Microsoft | Propriétés documentées, schéma non | Propriétés documentées, schéma non |
L'emplacement ne change pas : C:\ProgramData\Microsoft\Search\Data\Applications\Windows\. Le guide de dépannage de Microsoft parle de Windows.edb sous Windows 10 et de Windows.db sous Windows 11. Les sources publiées ne s'accordent pas sur la version exacte de Windows 11 qui a changé de format. Une machine mise à niveau peut aussi traîner un ancien fichier. Regardez ce qui se trouve réellement dans le dossier et les en-têtes de fichier (SQLite format 3 contre la signature ESE) plutôt que de déduire à partir du numéro de version.
Windows 10 : une seule table très large
Dans Windows.edb, SystemIndex_PropertyStore possède une colonne par propriété connue de l'indexeur, soit plusieurs centaines. Les noms de colonnes portent un préfixe numérique et le nom canonique de la propriété, avec des underscores à la place des points :
WorkID
4447-System_ItemPathDisplay
4414-System_FileName
4498-System_Size
4520-System_Search_GatherTime
4516-System_Search_AutoSummary
...
(Les numéros varient d'une base à l'autre. Fiez-vous toujours au nom après le tiret.)
La plupart des colonnes sont vides pour la plupart des lignes : c'est exactement le rôle des colonnes « tagged » d'ESE, des valeurs éparses qui n'occupent aucune place quand elles sont absentes. Les valeurs longues, comme un gros extrait de contenu, peuvent être stockées hors de la ligne dans un arbre de valeurs longues séparé, et beaucoup de colonnes texte sont compressées. Le fonctionnement sur disque est décrit dans les bases d'ESE pour les analystes forensiques.
Windows Vista et 7 utilisaient une table SystemIndex_0A avec un encodage des valeurs qui leur est propre. Si vous travaillez sur ces systèmes, vérifiez que votre parseur le prend en charge. Le Windows Search Index Parser ne décode pas encore cet encodage.
Windows 11 : des lignes de propriétés
Windows.db normalise les mêmes données. Un fichier ressemblerait à ceci dans SystemIndex_1_PropertyStore :
| WorkId | ColumnId | Value |
|---|---|---|
| 532 | 4447 | C:\ProgramData\Intel\creds.txt |
| 532 | 4498 | D6 00 00 00 00 00 00 00 (214) |
| 532 | 4520 | FILETIME sur 8 octets |
| 532 | 4516 | FIN-SQL01 sa / … |
Et SystemIndex_1_PropertyStore_Metadata vous indique que le ColumnId 4447 est System.ItemPathDisplay, avec une UniqueKey du type 4447-System_ItemPathDisplay (la même chaîne que le nom de colonne ESE) et un type de stockage. Les travaux de Stroz Friedberg de 2023 et l'article de Kaspersky sur les artefacts de Windows 11 décrivent tous deux cette structure.
Conséquences pour l'analyse :
- Il faut pivoter. Un
SELECT *vous donne une soupe de propriétés. Regroupez par WorkId, joignez les métadonnées et transformez chaque ColumnId en champ nommé. - Les valeurs sont typées par les métadonnées, pas par la colonne. Les recherches publiques, et le décodage du parseur, traitent le type de stockage 11 comme une chaîne et le 12 comme un entier little-endian sur 8 octets ou un FILETIME. Microsoft ne documente pas ces codes : un parseur rigoureux devine pour le reste et conserve les octets bruts.
- Attention au type de table. Une table dont la clé est (WorkId, ColumnId) peut être déclarée
WITHOUT ROWID; ses lignes vivent alors dans un b-tree d'index et non dans un b-tree de table. Les lecteurs SQLite légers qui ne parcourent que les tables à rowid ne verraient rien. Le parseur gère les deux. - Les chemins de dossiers viennent de la base gather.
SystemIndex_GthrPthest un arbre de noms d'étendues (Scope, Parent, Name). Reconstruisez le chemin complet en remontant les parents, puis ajoutez leFileNamedeSystemIndex_Gthr.
Les tables gather : même principe dans les deux
SystemIndex_Gthr contient une ligne par document connu du crawler : ScopeID, DocumentID, FileName, LastModified, TransactionFlags et d'autres. SystemIndex_GthrPth fournit l'arbre des étendues. L'article de Stroz Friedberg liste ces colonnes pour les deux versions. Le DocumentID correspond au WorkId du magasin de propriétés : c'est ainsi qu'on relie les deux.
Sous Windows 11, elles sont dans un fichier séparé avec son propre WAL. Si vous n'avez collecté que Windows.db, vous perdez la reconstruction des chemins et, surtout, la comparaison « présent dans le magasin de propriétés mais absent de la table gather », l'un des meilleurs indicateurs de fichier supprimé.
Modifications récentes : journaux contre WAL
Les deux moteurs journalisent avant d'écrire, mais les conséquences forensiques diffèrent.
ESE écrit d'abord les modifications dans MSS*.log et les applique plus tard à Windows.edb. Une base copiée à chaud est marquée dirty shutdown. Les dernières modifications ne sont que dans les journaux tant que vous ne les rejouez pas avec esentutl /r. Voir réparer un Windows.edb en dirty shutdown.
SQLite ajoute les pages validées à Windows.db-wal. Elles sont intégrées à la base lors d'un checkpoint, par défaut quand le WAL atteint 1 000 pages ou à la fermeture de la dernière connexion, selon la documentation SQLite. Les lecteurs consultent d'abord le WAL. Il n'y a pas d'étape de « rejeu » pour l'analyste : un parseur qui comprend le WAL lit simplement la version la plus récente de chaque page. Mieux : en comparant la base avec et sans le WAL, on sait quels éléments ont été ajoutés ou modifiés par les transactions les plus récentes. Le Windows Search Index Parser marque pour cette raison les éléments uniquement dans le WAL ou modifiés dans le WAL. Voir l'analyse forensique de Windows.db : SQLite et le WAL.
Lequel est le plus simple à exploiter ?
Pour un analyste forensique, Windows 11 est plus facile à lire et plus difficile à lire complètement.
- Plus facile : SQLite est documenté et chaque langage a son lecteur. Vous pouvez vérifier la sortie d'un parseur avec
sqlite3sur une copie en quelques minutes. - Plus difficile : le pivot, les blobs typés, la base gather séparée et le WAL doivent tous être corrects, et les codes de type de stockage ne sont pas documentés.
- ESE est l'inverse : un format plus lourd (catalogue, arbres B+, colonnes tagged, valeurs longues, compression), mais un fichier autonome dont la structure est bien documentée par libesedb.
Ce que fait l'outil avec chacun
Le Windows Search Index Parser traite les deux dans le navigateur :
- Windows.db : son propre lecteur SQLite + WAL (compatible WITHOUT ROWID), pivote
SystemIndex_1_PropertyStoreen un élément par WorkId, jointWindows-gather.dbsur DocumentID, reconstruit les chemins et marque les éléments présents uniquement dans le WAL ou modifiés dans le WAL. Un WAL appartenant à une autre base est détecté et ignoré. Le DDL exact de Windows 11 n'étant pas documenté, la reconstruction des chemins et une partie du décodage reposent sur des recherches publiques et des heuristiques. - Windows.edb : son propre lecteur ESE en lecture seule (catalogue, arbres B+, colonnes fixes / variables / tagged, valeurs longues, compression 7 bits et XPRESS) qui lit
SystemIndex_PropertyStoreet les tables gather. Réserve honnête : ce lecteur n'a été validé jusqu'ici que sur des bases synthétiques. Traitez sa sortie comme une piste et confirmez les constatations clés avec un autre outil.