Dentro de la compresión MAM
Un archivo .pf de Windows XP abre en el offset cero con la cabecera SCCA. Lees hacia abajo y el formato tiene sentido. Apunta el mismo parser a un .pf de Windows 10 y obtienes basura. La razón son tres bytes ASCII: MAM.
Cualquiera que haya visto un script de Python informar con seguridad "versión 7761" en un archivo prefetch moderno se ha topado con este problema. El script leyó MAM\x04 como inicio de una cabecera SCCA y trató M (0x4D) como el byte bajo de un u32.
El framing MAM
Desde Windows 8, el sistema operativo comprime cada archivo prefetch antes de que SysMain lo escriba en disco. El archivo en disco empieza con una cabecera de framing de ocho bytes:
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
El byte tras MAM identifica qué algoritmo COMPRESSION_FORMAT_* se usó. Microsoft define cinco a lo largo de la familia. Prefetch solo utiliza Xpress Huffman (0x04). El campo de tamaño le indica al descompresor exactamente cuán grande debe ser el búfer de salida, lo cual es práctico porque el payload SCCA no tiene su propio campo de longitud en el mismo offset.
El marco es idéntico en Windows 8, 8.1, 10 y 11. Todo lo que ha cambiado entre versiones vive dentro de los bytes SCCA descomprimidos, no en el envoltorio MAM.
Xpress Huffman en un párrafo
Xpress Huffman es una variante de LZ77 orientada a bloques, especificada como [MS-XCA] en el corpus de especificaciones abiertas de Microsoft. Cada bloque se abre con un alfabeto Huffman de 256 entradas — un nibble por símbolo — que define los códigos de bytes literales para 0..255 más códigos de longitud de coincidencia. El flujo de bits codificado se descodifica como códigos Huffman; cada símbolo emite un literal o señaliza una retro-referencia hacia la salida ya descomprimida. No es la variante LZ más rápida jamás distribuida, pero es compacta, determinista y suficientemente buena para archivos que típicamente pesan entre 30 y 100 KB.
El parser que ejecuta este sitio (frnsc-prefetch) lleva un decodificador Xpress Huffman en Rust puro, de modo que toda la pipeline puede correr dentro de un módulo WebAssembly sin saltos nativos a shell ni la API exclusiva de Windows RtlDecompressBufferEx. La biblioteca en C libscca hace lo mismo en el lado de escritorio; PECmd utiliza la implementación .NET que viene con el framework.
Por qué importa operativamente
Cualquier herramienta que intente leer prefetch moderno sin un descompresor Xpress Huffman en la pipeline o bien se caerá, devolverá un error educado o, en el peor caso, producirá silenciosamente salida incorrecta. El número de informes forenses todavía anclados a "probado en Windows 7" no es cero. He leído PDFs que reportan con confianza un payload SCCA v0 porque el script Python del autor nunca pasó del offset 4.
Si tu cadena de herramientas deja de funcionar al recolectar prefetch de un endpoint Win10/11, lo primero que hay que comprobar es si realmente maneja MAM. Tanto PECmd como libscca (y su binding pyscca) lo hacen. La línea prefetchparser.py de parsers antiguos de Python en general no, dependiendo del fork que cogieras.
La compresión es la parte fácil
Una vez descomprimido el payload, las diferencias a nivel SCCA entre v17, v23, v26, v30 y v31 son lo que tu parser tiene que manejar correctamente. Ocho marcas temporales de ejecución apareciendo en v26, cambios en el layout de métricas de archivos entre v23 y v26, ajustes de relleno en v31: ahí es donde los parsers divergen. El marco exterior MAM es un problema resuelto desde hace una década.
Lecturas adicionales
- Microsoft, especificación del algoritmo de compresión
[MS-XCA]Xpress: la referencia canónica del decodificador. - Joachim Metz, documentación de libscca: descripción legible tanto del marco MAM como del payload SCCA subyacente.
- Maxim Suhanov, publicaciones sobre internals de compresión en Windows: útiles cuando hay que depurar un bloque malformado.