TL;DR. Prefetch is real proof of execution with run counts and run times. ShimCache only proves a file existed and was examined. If you need "did it run, and when?", reach for Prefetch first; if Prefetch is disabled or wiped, ShimCache becomes your fallback existence witness.
ShimCache and Prefetch are constantly compared because both surface "programs on a Windows host." But they are not the same kind of evidence, and treating them as interchangeable produces wrong conclusions. Here is the direct comparison.
At a glance
| ShimCache | Prefetch | |
|---|---|---|
| Location | HKLM\SYSTEM\…\AppCompatCache | C:\Windows\Prefetch\*.pf |
| What it proves | File existed / was examined | File executed |
| Run count | No | Yes |
| Run timestamps | No (only file mtime) | Yes — last 8 run times |
| Files referenced | No | Yes — DLLs, data files loaded |
| Written when | Only at clean shutdown | Within ~10 s of execution |
| Default on servers | Yes | Often disabled |
| Capacity | Up to 1,024 entries | 1,024 .pf files (Win8+) |
Where Prefetch wins
Prefetch is the stronger execution artifact, full stop. Each .pf file gives you the last run time (up to eight on Windows 8+), a total run count, and the list of files the process loaded. That's enough to assert "this binary executed at these times" — something ShimCache can never do, because its only timestamp is the file's last-modified time, not an execution time.
Where ShimCache wins
Prefetch has a critical weakness: it is frequently disabled on servers, on SSD-tuned images, and by attackers (EnablePrefetcher = 0). It is also actively deleted by clean-up tooling. ShimCache, by contrast, is always on and is sensitive enough to record a binary that was dropped and deleted before it ever ran. When Prefetch is empty, ShimCache often still answers "did this file ever touch this host?" — see Does the ShimCache prove a program was executed? for how far that inference can be pushed.
How to use them together
- Both present, paths match: strong execution evidence. Use Prefetch's run times as the event timeline; use ShimCache's mtime only to anchor the file's identity.
- Prefetch only: execution is proven; ShimCache may simply not be flushed yet (it only writes at shutdown — see where ShimCache is stored).
- ShimCache only: the file existed and was examined. Do not claim execution without corroboration — pull AmCache, BAM, and event logs (full matrix here).
- Neither, but you suspect execution: look for anti-forensics. Prefetch deletion plus a missing ShimCache flush is itself a finding, covered in ShimCache anti-forensics.
To read the ShimCache side without installing anything, drop a SYSTEM hive into the Shimcache Parser — fully in-browser.
Further reading
- ZwClose's Prefetch format notes — the reference for the
.pfbinary layout. - Mandiant: leveraging the ShimCache — defines the ShimCache's forensic role.