ShimCache (AppCompatCache)¶
What ShimCache is¶
Windows' Application Compatibility subsystem caches executable paths and metadata while evaluating compatibility/shim behavior. The cache survives files being renamed, removed, or disconnected with a removable volume. Its layout and available fields differ across Windows XP through Windows 11.
ShimCache is valuable for historical path discovery and, where the format has a reliable execution flag, additional execution support. The cached time is normally the file's last-modified time, not the time Windows saw or ran it.
Best conclusion: Windows observed the path for compatibility
processing. An entry alone is presence/observation evidence; use Executed only where supported.
Location and collection¶
The bytes are in the SYSTEM registry hive, commonly under:
Collect SYSTEM, SYSTEM.LOG1, and SYSTEM.LOG2. Juntei reads all control sets and identifies
Select\Current where possible.
The newest live entries may not be in the hive
Windows can hold ShimCache updates in memory and flush them during shutdown/reboot. A hive copied from a running system may not contain the newest observations. The cache's registry last-write time helps describe when it was saved, but is not a per-entry execution time.
Analyst cautions¶
- A cache entry by itself is not proof of execution.
Executedcan beYes,No, orNA; available semantics depend on the format/version.LastModifiedTimeUTCbelongs to the referenced file, not the observation or execution.- Order is useful but not a universal precise timeline; duplicates occur across control sets/slack.
FromSlackentries were recovered outside the active cache and require additional caution.- A dirty
SYSTEMwithout usable logs may omit current records. Read the recovery summary. - Findings indicate suspicious naming/path patterns, not malware verdicts.
Parse with Juntei¶
Usage: juntei parse-registry shimcache <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find SYSTEM hives
-f, --file <FILE> Parse SYSTEM or a raw AppCompatCache value
--no-logs Do not replay SYSTEM.LOG1/SYSTEM.LOG2
Output:
-o, --output <FILE> Save records
-t, --output-type <TYPE> csv, json, or jsonl
juntei parse-registry shimcache -f SYSTEM -o shimcache.csv
juntei parse-registry shimcache -d evidence/ -t jsonl \
| jq 'select(.Executed == true or (.Findings | length > 0))'
Output fields¶
| Field | Interpretation |
|---|---|
ControlSet |
Numeric control set holding the cache. Compare IsCurrent before choosing one. |
CacheEntryPosition |
Position/order within the decoded cache. Useful for relative ordering, not a time. |
Path |
Cached executable/package path. Primary hunting pivot. |
LastModifiedTimeUTC |
File modification time stored in the entry—not execution/observation time. |
Executed |
Yes, No, or NA according to supported format flags. Use only with version context. |
Duplicate |
Same entry was already seen in an earlier control set or slack; helps prevent double-counting. |
SourceFile |
Input hive/raw value. Essential across hosts. |
FromSlack |
Entry recovered from cache-value slack rather than active list. Lower confidence and possibly older. |
CacheFormat |
Decoded Windows/cache layout. Governs field availability and semantics. |
CacheLastWrittenUTC |
Registry key/cache save time. It is shared context, not each entry's run time. |
InsertFlags, ShimFlags |
Raw compatibility flags; Executed is Juntei's interpreted result where supported. |
DataSize |
Size of this entry's data, useful for structural validation. |
Machine |
Architecture recorded by newer formats (x64, x86, ARM64). |
FileSize, LastUpdateTimeUTC |
Windows XP-specific cached metadata where present. |
PackageName, PackageVersion, PackagePublisherID |
Packaged-application identity in supported entries. Publisher ID is context, not signature proof. |
Findings |
Juntei anomaly codes such as relocated system binary or suspicious staging path. Leads only. |
RegistryPath, RegistryValueName |
Exact hive key/value source. Preserve for validation. |
CacheValueSize |
Whole registry value size, not the individual entry's DataSize. |
IsCurrent |
Whether this entry's control set equals SYSTEM\Select\Current; empty if not safely known. |
SelectCurrent, SelectDefault, SelectLastKnownGood, SelectFailed |
Raw SYSTEM\Select control-set numbers for context and recovery analysis. |
JSON/JSONL additionally preserves entry data, tags, packaged-app subrecords, structured findings, cache problems, and recovery details.
Investigation strategy¶
- Prefer the current control set but retain other sets and slack as historical evidence.
- Search paths and findings; do not use
LastModifiedTimeUTCas execution time. - Where
Executed == Yes, corroborate with Prefetch, SRUM, event logs, or other runtime traces. - Match paths against
$MFT/USN to determine creation, deletion, and metadata history. - Report whether transaction logs were replayed and whether the live cache may not have been flushed.