Amcache vs Prefetch: what each one really proves

Both Amcache and Prefetch tell you something about PE binaries on a Windows host. They are constantly confused, and the confusion produces wrong findings.

The headline:

Prefetch proves execution. Amcache proves presence.

Same binary can appear in both, in only one, or in neither, and the combination you observe is itself the finding.

What each one records#

Prefetch#

C:\Windows\Prefetch\ holds .pf files maintained by the Prefetcher subsystem. A .pf is created the first time the binary runs and updated on subsequent runs. Each .pf contains:

  • Executable name and a Windows-specific path hash (not a content hash).
  • Up to 8 run timestamps (10 on Windows 11).
  • A run count.
  • The list of files (mostly DLLs) the binary loaded in its first ~10 seconds.
  • Volumes referenced.

Prefetch exists to speed up application launches. The forensic value is a side effect: the .pf exists if and only if the binary ran.

Amcache#

A single registry hive (C:\Windows\AppCompat\Programs\Amcache.hve) populated by the Compatibility Appraiser scheduled task. Periodically (~daily on workstations, slower on servers), the appraiser walks the system, inventories every PE binary it finds, and records:

  • Full path, size, SHA-1 of the first 31 MiB.
  • PE metadata (publisher, version, link date, language).
  • Per-application context (ProgramId, install date).
  • Per-driver and per-device context for the relevant categories.

Amcache exists to support Windows's compatibility telemetry pipeline. Forensic value is, again, a side effect.

The fundamental difference#

Question Prefetch Amcache
Did this binary run on this host? Yes, definitive No
Was this binary ever on disk? Only if it ran Yes
When did it run? Up to 8/10 timestamps No
What's its SHA-1? Path hash, not content Yes, content SHA-1
Full path? Recoverable Direct
Survives binary deletion? Yes Yes
Survives reboot? Yes Yes
Survives a competent wipe? No No (but VSS and transaction logs frequently catch it)

The two answer different questions. Where they overlap, they corroborate. Where they diverge, the divergence is information.

The four states#

Both present (the typical case)#

A binary runs, the Prefetcher writes a .pf, the appraiser inventories it on its next pass. Prefetch tells you the run times, Amcache tells you the path, hash, publisher, and metadata. Done.

Amcache only ("present but never ran")#

You find a row in *_UnassociatedFileEntries.csv with no corresponding .pf. Likely reasons:

  • The binary was placed on disk but never executed.
  • The binary ran via rundll32.exe / regsvr32.exe / another loader, which gets the Prefetch hit instead.
  • Prefetch is disabled (rare, governed by PrefetchParameters).
  • The .pf was deleted (anti-forensics, disk cleanup).

"Present but never ran" is a very different finding from "executed". Staged tools, pre-positioned implants, DLLs waiting to be reflectively loaded into another process.

Prefetch only ("ran but no inventory")#

You find a .pf for a binary, but no row in Amcache. Likely reasons:

  • The binary executed between appraiser runs and was deleted before the next pass. The .pf survived. Amcache never saw the file.
  • The binary lived in a path the appraiser does not scan.
  • The appraiser is disabled or has been broken for a while.

This is the stronger signal for deliberate cleanup. The binary lived long enough to run and then disappeared before the next inventory pass. Characteristic of:

  • Cobalt Strike / Sliver / Meterpreter droppers that execute and self-delete.
  • In-memory tooling that wrote a tiny launcher to disk only briefly.
  • Wiper deployment where the operator removed the dropper after success.

Both absent ("never seen")#

A binary appears in neither. Closest you get to "this never happened" but not conclusive:

  • Both artefacts can be wiped by a capable attacker.
  • A binary that never executed and sat on disk between appraiser passes can be absent from both even in benign cases.
  • On servers with the appraiser off, Amcache is empty regardless of what happened.

Hashing trap#

The .pf hash is a Windows path hash, not content. You cannot submit it to VirusTotal. The Amcache hash is a real SHA-1 (of the first 31 MiB) and you can submit it. See Amcache FileId explained.

To get a content hash from Prefetch, you need the binary itself. The .pf does not contain the binary.

How to use both#

  1. Parse both. AmcacheParser for Amcache, PECmd for Prefetch.
  2. Load both CSVs into Timeline Explorer.
  3. Triage from Amcache. Apply the "unsigned PE in user-writable path" filter.
  4. Confirm execution via Prefetch. For each suspicious Amcache row, look for a .pf with the same name.
  5. Cross-reference timestamps. The earlier of "first Prefetch run" and "first Amcache inventory" is your best estimate of when the binary arrived.

For Amcache time-bound pivots, see Amcache timestamps explained.

Decision table#

Your question Look at
Did this binary run? Prefetch
When did it run? Prefetch (up to 8/10 timestamps)
Was it present? Amcache
What's its SHA-1? Amcache Hash
Full path? Amcache FullPath (or recover from Prefetch metadata)
Multiple executions? Prefetch run count
What did it load? Prefetch files-loaded list
Still on disk? Filesystem check; Amcache does not say
Content changed over time? Amcache (same FullPath, different Hash across KeyLastWriteTimestamp)
Present on other hosts? Amcache Hash and ProgramId across collected hives

Anti-forensics#

Both can be tampered with. They have different weaknesses:

  • Prefetch is per-file. Targeted cleanup is easy: delete the .pf.
  • Amcache is monolithic. Cleaning a specific entry takes hive editing.
  • Transaction logs and VSS frequently preserve Amcache history the attacker missed. See Where Amcache.hve is on disk for the VSS recovery flow.

When you suspect tampering, absence of expected entries in both is itself the finding.

Further reading#

Related posts

Back to all posts