TL;DR. Il primo u32 = dimensione dell'header (tipicamente 0x30–0x36). A quell'offset ogni voce inizia con la firma a 4 byte 10ts, seguita da un header di 12 byte e da un corpo di lunghezza variabile: percorso UTF-16LE (con prefisso di lunghezza, non terminato da null), mtime FILETIME e un blob di dati finale. Il flag di esecuzione è stato rimosso in Windows 10.
Ogni versione di Windows dal XP ha portato un layout di ShimCache diverso. La variante Windows 10 / 11 è quella che oggi gli investigatori incontrano più spesso, e anche la più clemente da analizzare — una volta che si conoscono le regole. Questo articolo percorre il formato dall'inizio alla fine.
Il blob da analizzare
Si parte dal valore binario in:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCache
Se hai estratto quel valore dalla hive SYSTEM (vedi dove è memorizzato lo ShimCache), ciò che hai è un singolo blob, tipicamente da decine a centinaia di kilobyte. Il blob contiene una piccola intestazione seguita da una sequenza di voci, ciascuna delle quali inizia con un valore magic noto.
L'intestazione
I primi quattro byte little-endian del blob forniscono l'offset della prima voce. Su Windows 10 / 11 è tipicamente 0x30, 0x34, 0x35 o 0x36, a seconda della build. Alcune hive mettono qui 0x80 — segnale di un layout Windows 8.x che usa la stessa firma di voce 10ts / 00ts.
Un parser difensivo non codifica fissa la dimensione dell'intestazione; legge il primo u32 e valida che il byte a quell'offset sia l'inizio di una voce riconosciuta. Se né 10ts né 00ts compaiono all'offset dichiarato, scansiona in avanti cercando 10ts e riprendi da lì — questo gestisce hive leggermente fuori specifica che i sistemi reali a volte producono.
Una voce Windows 10 / 11, byte per byte
Ogni voce moderna inizia con la firma di quattro byte 10ts (0x31 0x30 0x74 0x73). Il layout completo, in ordine, è:
| Offset | Dimensione | Campo |
|---|---|---|
| 0x00 | 4 | Magic — "10ts" |
| 0x04 | 4 | Sequenza / sconosciuto (spesso ignorato dai parser) |
| 0x08 | 4 | Dimensione dati voce — byte dopo questo campo |
| 0x0C | 2 | Dimensione del percorso in byte (UTF-16LE) |
| 0x0E | N | Byte del percorso (UTF-16LE, senza terminatore) |
| 0x0E + N | 8 | Ultima modifica — FILETIME (100 ns dal 1601-01-01 UTC) |
| 0x16 + N | 4 | Dimensione dei dati finali |
| 0x1A + N | M | Dati finali (di solito vuoti o piccoli) |
La dimensione totale della voce è quindi 0x0C + entry_data_size. La voce successiva inizia immediatamente dopo.
Due note pratiche:
- Il percorso è UTF-16LE e non è terminato da zero. Usa il campo della dimensione del percorso; non leggere fino a un null.
- Il
FILETIMEè il mtime$STANDARD_INFORMATIONdel file, non l'ora di esecuzione del programma. Il post sulla prova di esecuzione spiega perché è importante.
Cosa è stato rimosso in Windows 10
Le versioni precedenti di Windows impacchettavano un flag Executed all'interno di ogni voce. In Windows 10 e 11 è stato rimosso completamente. Non c'è modo, nella cache, di dire se un binario sia stato eseguito davvero — servono Prefetch, AmCache o log eventi per quello.
In pratica
Un parser robusto:
- Valida il magic di quattro byte all'offset annunciato dall'intestazione.
- Itera le voci leggendo il campo dimensione dati e avanzando.
- Decodifica il percorso come UTF-16LE.
- Converte il
FILETIMEnel formato di timestamp che preferisce il tuo tooling a valle (Unix ms è comodo). - Espone l'etichetta del formato OS (Windows 10/11 vs 8.x vs 8.0) per il filtraggio a valle.
Se vuoi un riferimento funzionante, lo Shimcache Parser open source implementa esattamente l'algoritmo qui sopra in Rust e lo invia al tuo browser come WebAssembly — niente server, niente upload.
Parser di riferimento
- AppCompatCacheParser di Eric Zimmerman — l'implementazione C# gold standard che copre ogni variante Windows.
- ShimCacheParser di Mandiant — il proof-of-concept Python originale, utile come riferimento incrociato del formato.
- Velociraptor
Windows.Registry.AppCompatCache— artefatto VQL per la raccolta live. - Windows 10/11 AppCompatCache deep dive (Ø Security) — l'analisi pubblica più completa del layout moderno.