Retour à tous les articles

Au cœur de la compression MAM

Un fichier .pf Windows XP s'ouvre à l'offset zéro sur l'en-tête SCCA. Vous lisez à partir de là et le format prend sens. Lancez le même parser sur un .pf de Windows 10 et vous obtenez du charabia. La raison tient à trois octets ASCII : MAM.

Quiconque a vu un script Python annoncer fièrement « version 7761 » sur un fichier prefetch moderne a rencontré ce problème. Le script a lu MAM\x04 comme le début d'un en-tête SCCA et a traité M (0x4D) comme l'octet de poids faible d'un u32.

Le framing MAM

À partir de Windows 8, le système d'exploitation compresse chaque fichier prefetch avant que SysMain ne l'écrive sur le disque. Le fichier sur disque commence par un en-tête de framing de huit octets :

offset  size  field
0       3     ASCII signature "MAM"
3       1     compression algorithm (0x04 = Xpress Huffman)
4       4     uncompressed payload size (u32 little-endian)
8       ..    compressed payload

L'octet après MAM identifie l'algorithme COMPRESSION_FORMAT_* utilisé. Microsoft en définit cinq pour cette famille. Prefetch n'utilise que Xpress Huffman (0x04). Le champ de taille indique au décompresseur la taille exacte du tampon de sortie, ce qui est pratique car le payload SCCA n'a pas son propre champ de longueur au même offset.

Le cadre est identique sur Windows 8, 8.1, 10 et 11. Tout ce qui a changé entre versions vit dans les octets SCCA décompressés, pas dans l'enveloppe MAM.

Xpress Huffman en un paragraphe

Xpress Huffman est une variante de LZ77 orientée blocs, spécifiée en [MS-XCA] dans le corpus de spécifications ouvertes de Microsoft. Chaque bloc s'ouvre sur un alphabet Huffman de 256 entrées — un quartet par symbole — définissant les codes d'octets littéraux pour 0..255 ainsi que des codes de longueur de correspondance. Le flux de bits encodé est décodé sous forme de codes Huffman ; chaque symbole produit soit un littéral, soit signale une référence arrière dans la sortie déjà décompressée. Ce n'est pas la variante LZ la plus rapide jamais livrée, mais elle est compacte, déterministe et largement suffisante pour des fichiers de 30 à 100 Ko en général.

Le parser exécuté par ce site (frnsc-prefetch) embarque un décodeur Xpress Huffman en pur Rust, de sorte que toute la pipeline peut tourner dans un module WebAssembly sans appel natif ni recours à l'API spécifique à Windows RtlDecompressBufferEx. La bibliothèque C libscca fait la même chose côté desktop ; PECmd utilise l'implémentation .NET livrée avec le framework.

Pourquoi cela compte en pratique

Tout ce qui essaie de lire du prefetch moderne sans décompresseur Xpress Huffman dans la pipeline va soit planter, soit renvoyer une erreur poliment, soit, au pire, produire silencieusement des sorties erronées. Le nombre de comptes-rendus forensiques toujours figés sur « testé sous Windows 7 » n'est pas nul. J'ai lu des PDF qui annoncent fièrement un payload SCCA v0 parce que le script Python de l'auteur n'a jamais dépassé l'offset 4.

Si votre chaîne d'outils tombe en panne dès que vous collectez du prefetch depuis un endpoint Win10/11, la première chose à vérifier est de savoir si elle gère réellement MAM. PECmd et libscca (avec son binding pyscca) le font. La lignée prefetchparser.py des anciens parsers Python, en général non, selon le fork que vous avez récupéré.

La compression est la partie facile

Une fois le payload décompressé, ce sont les différences au niveau SCCA entre v17, v23, v26, v30 et v31 que votre parser doit vraiment gérer correctement. Huit timestamps d'exécution apparaissant en v26, modifications de la disposition des métriques de fichiers entre v23 et v26, ajustements de padding en v31 : c'est là que les parsers divergent. Le cadre MAM extérieur est un problème réglé depuis une décennie.

Pour aller plus loin

  • Microsoft, spécification de l'algorithme de compression [MS-XCA] Xpress : la référence canonique pour le décodeur.
  • Joachim Metz, documentation libscca : description lisible à la fois du cadre MAM et du payload SCCA sous-jacent.
  • Maxim Suhanov, billets sur les internals de compression Windows : utiles quand il faut déboguer un bloc mal formé.