Prefetch, AmCache, ShimCache: a quick reference for program-execution evidence

4 min read

TL;DR. Priority order I actually use on triage: Prefetch (strongest when enabled), BAM/DAM (per-user last execution on Win10+, criminally underused), AmCache (SHA-1 identification), ShimCache (existence anchor), UserAssist (Explorer-initiated launches only). No single artifact closes a case. Triangulate or stop claiming execution.

There is no single Windows artifact that perfectly answers "did this program run, when, and by whom?" Anyone who tells you otherwise has either not worked enough cases or is selling something. What works is a short list of artifacts that each cover a piece of the question and a habit of cross-referencing.

The short list

ArtifactLocationRecordsReliability for execution
PrefetchC:\Windows\Prefetch\*.pfPath, run count, last 8 run times, loaded filesVery high. Only written on process start.
AmCacheC:\Windows\AppCompat\Programs\Amcache.hvePath, SHA-1, size, publisher, install + first-runHigh. Explicit execution timestamps.
ShimCacheSYSTEM hive …\Session Manager\AppCompatCachePath, file mtimeMedium. Proves existence; often (not always) implies execution.
UserAssistNTUSER.DAT …\UserAssist (registry)Per-user GUI program launches via ExplorerHigh, but user-launched only, ROT13-encoded names.
BAM / DAMSYSTEM hive …\bam\State and …\dam\StatePer-user last execution time of every binaryVery high. Win10+, easy to parse, often missed.

Reading them in priority order

1. Prefetch first. A .pf file is the closest thing Windows has to a "this ran" receipt. Up to eight run times, total run count, list of loaded modules. Workstation SKUs leave Prefetch on by default. Eric Zimmerman's PECmd is the canonical parser. The Prefetch parser covers the format if you want to roll your own.

2. BAM / DAM second. Background and Desktop Activity Moderator throttle background apps and keep per-user, per-binary "last execution" timestamps in the SYSTEM hive under …\Services\bam\State and …\Services\dam\State. Present on Windows 10 and 11, low-noise, easy to read. I have closed cases on BAM rows that nobody on the original IR team had bothered to pull.

3. AmCache third. Backs Prefetch on servers (where Prefetch is often disabled) and on hosts where the attacker cleared the Prefetch folder. SHA-1 hashes are the killer feature: when the file is deleted, the hash is your only handle for VirusTotal and threat intel. See ShimCache vs AmCache.

4. ShimCache fourth. Existence anchor, not execution claim. The proof-of-execution post covers the reasoning.

5. UserAssist last. Strong evidence of interactive launch via Explorer. Blind to anything launched from a shell, scheduled task, or service. Useful when the question is "did the user click this?" Read with any registry tool that handles ROT13; the registry parser decodes it inline.

Things that bite

  • Prefetch can be off. SSDs, server SKUs, and group policy all disable it. Empty Prefetch is not evidence of absence.
  • AmCache rotates. Old entries age out. Pull the hive early in triage.
  • ShimCache timestamps are file mtime. Not execution time. Not flush time. The file's mtime. Re-read that until it sticks.
  • UserAssist is ROT13. Trivial to decode but trips up casual readers.
  • BAM is underused. Maybe the cleanest "did this binary run for this user?" signal on modern Windows.

Other artifacts worth knowing about depending on the case: RecentFileCache (Win7 legacy), SRUM for network and process resource usage over 30 days, jump lists and LNK files for shell activity, the MFT and USN journal for filesystem-level timelines.

Tooling

For full-fidelity offline parsing, the Eric Zimmerman tool suite is the de-facto standard. AppCompatCacheParser, AmcacheParser, PECmd, RBCmd, all reliable. Velociraptor handles live triage at fleet scale. For ShimCache specifically, the Shimcache Parser reads a hive directly in the browser without installing anything.

Further reading

Related articles