← Retour à l’analyseur

Le format de base ESE derrière SRUDB.dat

ESE en un paragraphe

L’Extensible Storage Engine est la base ISAM embarquée de Microsoft. Chaque fichier est une série de pages de taille fixe (4 ou 8 Ko) qui organisent les données en B-trees, un par table. Les écritures passent d’abord par un journal de transactions pour permettre la récupération après crash en plein flush. Le moteur est mono-processus — seul le service propriétaire a un handle sur le fichier à un moment donné.

Anatomie sur disque

  • Pages — 4 ou 8 Ko, identifiées par un numéro de page 4 octets. La première page contient l’en-tête de la base (signature, taille de page, signature du log).
  • B-trees — un par table. Une page feuille contient les données de ligne ; les pages internes contiennent les plages de clés et pointeurs vers enfants.
  • Catalog — un B-tree spécial (table id 0) qui décrit chaque autre table : son nom, numéro de page racine, et définitions de colonnes.
  • Long values — données de taille variable trop grosses pour tenir en ligne, stockées dans un arbre « long-value » séparé, la ligne ne portant qu’une référence.
  • Journaux de transactions — fichiers .log qui contiennent les écritures non commit. Le fichier checkpoint (.chk) enregistre jusqu’où le moteur a flushé.

Types de colonnes rencontrés

ESE a 19 types de colonnes. Les plus courants dans SRUDB.dat :

IDNomEncodage
1Bit1 octet (0/1)
4Longint signé 32-bit
7IEEEDoublefloat 8 octets (utilisé pour dates OLE)
8DateTimeOLE variant date 8 octets
11LongBinaryoctets variables (souvent compressés XPRESS)
12LongTexttexte UTF-16 / cp1252 variable
14UnsignedLongint non-signé 32-bit
15LongLongint signé 64-bit (souvent FILETIME)
16GUID16 octets bruts (endian mixte)

À noter : la colonne TimeStamp de SRUM est de type 8 (date OLE en f64) tandis que les colonnes événementielles comme ConnectStartTime sont de type 15 (FILETIME en i64). Un parseur doit gérer les deux.

Pourquoi un nouvel outil pour le web

Les lecteurs ESE existants — libesedb en C, strozfriedberg/ese_parser en Rust, Velocidex/go-ese en Go — sont excellents mais ciblent le desktop/serveur.

Pour tourner dans un navigateur via WebAssembly :

  • Le crate Rust ese_parser compile sans accroc sur wasm32-unknown-unknown.
  • Il expose une API Read + Seek, donc un Cursor<Vec<u8>> sur les octets du fichier fonctionne sans couche FS virtuelle.
  • Retirer les features inutilisées (filepath et nt_comparison) amène le payload WASM à ~160 Ko — assez petit pour servir en asset statique.

C’est exactement ce qui alimente l’analyseur SRUM de ce site.

Récupérer une base dirty

Si vous copiez SRUDB.dat pendant que le service SRUM écrit, le fichier est « dirty » — l’en-tête le marque incohérent. Un parseur read-only refusera ou ignorera silencieusement les pages nécessitant un replay du log.

La meilleure parade à l’acquisition est de prendre tout le répertoire sru\ y compris les .log. Une bibliothèque ESE complète (libesedb, esentutl) peut rejouer les logs contre la base dirty et produire une copie cohérente.

Pour aller plus loin

Questions fréquentes

Que signifie ESE ?
Extensible Storage Engine. Microsoft l’appelle aussi Jet Blue en interne. C’est une base ISAM embarquée, transactionnelle, avec pages B-tree.
Où ESE est-il utilisé en dehors de SRUM ?
Active Directory (NTDS.dit), Microsoft Exchange (boîtes mail), le cache Edge / Internet Explorer (WebCacheV01.dat), Windows Search (Windows.edb), et DHCP.
Puis-je ouvrir SRUDB.dat dans Microsoft Access ?
Non. Access utilise Jet Red, un moteur différent. ESE/Jet Blue a son propre format on-disk et requiert un lecteur dédié comme libesedb, ese_parser, ou cet outil navigateur.
Le format ESE est-il documenté ?
Partiellement. Microsoft a open-sourcé le moteur ESE en 2021. Le projet libyal de Joachim Metz maintient la spécification communautaire la plus complète.
Pourquoi les lignes SRUM sont compressées ?
ESE supporte la compression XPRESS par colonne. SRUM l’utilise sur ses payloads variables (l’IdBlob dans SruDbIdMapTable, par exemple) pour garder la base compacte.