The definitive Amcache.hve forensic reference: every key, every value, every timestamp

Amcache.hve is the richest single execution-artefact source on a modern Windows host, and one of the most misunderstood. This is the field-by-field reference for the artefact itself. Every key. Every value. Every timestamp. What the schema looked like in each Windows release, and which claims about Amcache are not actually true.

For tool-level documentation, see the AmcacheParser complete guide and the output columns reference.

1. What Amcache.hve actually is#

A registry hive written by Windows's Application Compatibility / Program Compatibility Assistant subsystem. Not a security artefact by design. Microsoft uses it to feed compatibility telemetry into the Customer Experience Improvement Program and the Compatibility Appraiser, both of which exist to decide which installed software might break on upgrade.

The reason it matters in DFIR is a side effect of that purpose. To assess whether a program is safe to upgrade, Windows enumerates programs, drivers, devices, and files on the machine. That enumeration, with hashes, paths, publishers, sizes, and timestamps, is what lands in Amcache.hve.

Path#

C:\Windows\AppCompat\Programs\Amcache.hve

With a .LOG1 / .LOG2 transaction-log pair alongside. Both logs must be replayed into the hive before parsing if the hive was not cleanly unmounted. Modern tools (AmcacheParser, the browser parser, RegRipper) do this for you, but never delete the .LOG files before triage. They may hold the writes that contain your evidence.

Who writes it#

  • compatTelRunner.exe, driven by the scheduled task \Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser.
  • Also touched by aeinv.dll (Application Experience Inventory) and the broader CompatTelemetry stack.

Default cadence is daily on Windows 10/11 workstations and on logon, but it varies by build, GPO, and battery state. Do not assume Amcache data is real-time. A binary executed five minutes before shutdown may never appear. One executed an hour before may appear with a KeyLastWriteTimestamp reflecting the appraiser run, not the execution.

Acquisition#

The hive is held open at runtime. To grab a live copy you need raw NTFS access:

  • KAPE with the Amcache target.
  • Velociraptor Windows.Registry.Amcache.
  • FTK Imager > File System > C:\Windows\AppCompat\Programs.
  • RawCopy64.exe, CopyRawFiles.ps1.
  • From an E01 / AFF4 / VHDX image, just read the file normally.

Volume Shadow Copies (vssadmin list shadows) often give you an earlier hive containing evidence that has since rolled off the current one.

2. Schema evolution: Windows 7 through Windows 11#

Amcache's schema has shifted a lot. Walk into a case expecting Windows 10 1607 keys on a Windows 7 hive and you will think the artefact is empty. It is not. It just looks different.

Windows version Amcache present? Dominant schema
Windows 7 RTM / SP1 (pre-KB2952664) No (uses RecentFileCache.bcf) n/a
Windows 7 SP1 + KB2952664 (2015) Yes Root\File\{VolumeGUID}\{FileRef} + Root\Programs
Windows 8 / 8.1 Yes Root\File + Root\Programs
Windows 10 1507 - 1511 Yes Root\File + Root\Programs (transitional)
Windows 10 1607 (Anniversary) Yes Root\InventoryApplicationFile and the wider Inventory* family
Windows 10 1703 - 1809 Yes Inventory schema stable; minor field additions
Windows 10 1903 - 22H2 Yes Inventory schema, LongPathHash, more driver fields
Windows 11 21H2 / 22H2 / 23H2 / 24H2 Yes Inventory schema, expanded device records, more PnP detail

The 1607 jump is the biggest. Pre-1607 hives have a handful of keys with maybe a dozen values each. Post-1607 hives have ten-plus top-level Inventory* containers, each with rich nested data.

Legacy schema (Win7 → Win10 1511)#

Root\
 File\
  {Volume GUID}\
   {NTFS File Reference}\
    ... values ...
 Programs\
  {ProgramId}\
   ... values ...
 Orphan\
 Generic\

Values under each File\{Vol}\{FileRef} are numbered (0, 1, 2, 101, etc.). The mapping is documented in Willi Ballenthin's 2013/2015 research and reproduced in the Mandiant blog. Highlights:

Value Meaning
0 Product name
1 Company name
2 PE FileVersion
3 Language LCID
5 BinaryFileVersion
6 BinaryProductVersion
c FileDescription
f PE LinkDate (FILETIME)
11 Last modified (FILETIME)
12 Created (FILETIME)
15 Full path
17 Last modified (alternative FILETIME slot)
100 ProgramId
101 FileId (SHA-1 with 0000 prefix)

Modern schema (Win10 1607+)#

Root\
 InventoryApplication\
  {ProgramId}\     <- installed-program record
 InventoryApplicationFile\
  {Name|FileId}\    <- per-file record
 InventoryApplicationShortcut\
 InventoryApplicationFramework\
 InventoryApplicationDriver\
 InventoryDeviceContainer\
 InventoryDevicePnp\
 InventoryDeviceInterface\
 InventoryDriverBinary\
 InventoryDriverPackage\
 InventoryMiscellaneousUUPInfo\
 Programs\        <- legacy, often still present
 File\          <- legacy, often empty on modern OS
 Orphan\
 Generic\

Modern sub-keys carry named values, not numeric, which makes them much easier to read. The rest of this post is the field-by-field reference for those values.

3. Root\InventoryApplicationFile (the workhorse)#

One sub-key per file Windows has inventoried. Where attacker binaries, side-loaded DLLs, and ad-hoc tooling tend to appear.

Value Type Meaning Forensic note
Name string File name e.g. mimikatz.exe.
LowerCaseLongPath string Full path (lower-cased) Single most useful pivot.
LongPathHash string Internal path-dedup hash Useful for joining records across reboots.
FileId string "0000" + SHA-1(first 31 MiB) Strip 0000 for VT / TI lookups.
Publisher string X.509 CN or PE company resource Empty = unsigned.
Version string PE FileVersion
BinFileVersion string PE VS_FIXEDFILEINFO.dwFileVersion
BinProductVersion string PE VS_FIXEDFILEINFO.dwProductVersion
ProductName string PE resource ProductName
ProductVersion string PE resource ProductVersion
LinkDate string or FILETIME PE TimeDateStamp Attacker-controlled. Group by it, do not date by it.
BinaryType string pe32, pe64, pe32_arm64, pe32_managed, ... Filter for native PE when threat hunting.
Size dword/qword File size in bytes
Language dword PE resource LCID
IsPeFile dword (0/1) Is this a PE? Almost always 1 here.
IsOsComponent dword (0/1) Windows-shipped binary Filter to 0 to cut noise.
ProgramId string 44-char identity hash of parent app Empty/zero = unassociated.
Usn qword USN journal sequence number at inventory
AppxPackageFullName string UWP package full name Store apps.
AppxPackageRelativeId string UWP package-relative ID

Two FileId formats#

Two formats coexist:

  • 0000 + 40 hex - SHA-1 of the first 31 MiB. Dominant since Windows 8.
  • 0001 + 32 hex - MD5. Rare, mostly historical.

When pivoting to threat intel, always check the prefix and strip it. Submitting the raw FileId to VirusTotal returns zero hits and wastes meaningful triage time.

Associated vs unassociated#

A file with a non-empty ProgramId matching an existing InventoryApplication sub-key is "associated". Windows linked it to an installed product. A file with blank or zero ProgramId is "unassociated".

Attacker tooling is almost always unassociated. Filtering InventoryApplicationFile to unassociated entries with a LowerCaseLongPath under \Users\, \AppData\, \ProgramData\, \Temp\, or \PerfLogs\ is the cheapest, most productive triage filter on a typical commodity-malware case.

4. Root\InventoryApplication (installed-program records)#

One sub-key per registered application (MSI installs, Add/Remove Programs, Store apps).

Value Meaning
Name Display name
Version Application version
Publisher Publisher string
RootDirPath Install directory
Source MSI, AddRemoveProgram, WindowsUpdate, ...
InstallDate Install date (string or FILETIME)
Type Application, OptionalFeature, ...
Language LCID
MsiPackageCode MSI package GUID
MsiProductCode MSI product GUID
RegistryKeyPath Uninstall key (SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\...)
UninstallString Command-line to uninstall
OSVersionAtInstallTime Windows version at install
InstallDateArpLastModified Add/Remove last-modified date
PackageFullName UWP full name

InstallDateArpLastModified is underused. If a row's InstallDate and its ARP-last-modified value diverge by months, you may be looking at a replaced binary (think DLL side-load through a legitimate installer left behind by IT).

5. Root\InventoryDriverBinary (kernel-mode artefacts)#

The single best source for BYOVD (Bring-Your-Own-Vulnerable-Driver) hunts.

Value Meaning
DriverName Driver file name
DriverInBox True if shipped with Windows
DriverIsKernelMode True for ring-0 drivers
DriverSigned Signed-flag claim. Do not trust blindly.
DriverType Bit flags: legacy / PnP / service / file-system / ...
DriverVersion Driver version string
DriverCompany Company string
Product Product name
ProductVersion Product version
WdfVersion Windows Driver Framework version, if applicable
Service Backing service name
Inf .inf filename
DriverPackageStrongName Strong name
DriverTimeStamp PE link date of the driver
ImageSize Image size in bytes
Hash SHA-1 of the driver

For BYOVD: sort by DriverTimeStamp ascending, filter DriverSigned to true, look at the KeyLastWriteTimestamp of each. Old + signed + recently inventoried is the high-signal set. Cross-reference against loldrivers.io for known-abused names and hashes.

6. Root\InventoryDeviceContainer and Root\InventoryDevicePnp#

InventoryDeviceContainer is the user-facing device list: "Brother HL-L2350DW", "Logitech BRIO", "Samsung Galaxy S22". One sub-key per logical device. Notable values: Categories, DiscoveryMethod, FriendlyName, Manufacturer, ModelName, ModelNumber, IsConnected, IsPaired, Icon.

InventoryDevicePnp is the technical enumeration: one sub-key per device interface, with BusReportedDescription, DeviceClass, DeviceId, InstanceId, Manufacturer, Service, DriverName.

Pair the two on InstanceId to get both the marketing name and the PnP hardware IDs. Often the cheapest answer to "did device X ever attach to this host?" without wading through Setup logs.

7. Root\InventoryApplicationShortcut and minor keys#

  • InventoryApplicationShortcut: one sub-key per .lnk Windows knows about. Carries ShortcutPath, TargetPath, parent ProgramId. Pair with the LNK parser and jump list data for "what did the user pin/launch on $DATE".
  • InventoryApplicationFramework: .NET / runtime framework records.
  • InventoryApplicationDriver: bridge between an installed application and the driver it shipped.
  • InventoryDriverPackage: INF-level package records.
  • InventoryMiscellaneousUUPInfo: Unified Update Platform staging. Rarely relevant.

8. Timestamps: the part everyone gets wrong#

Amcache exposes at least five distinct kinds of "when". They mean different things. Misreading them is the most common error in Amcache findings.

Timestamp Source What it actually says
KeyLastWriteTimestamp Registry last-write of the sub-key Closest thing to "when Amcache observed this". Your authoritative pivot.
LinkDate PE header TimeDateStamp When compiler/linker stamped the binary. Attacker-controlled, frequently faked.
InstallDate (InventoryApplication) Whatever the installer wrote Best-effort; reflects installer behaviour.
InstallDateArpLastModified Add/Remove Programs last-modified Useful for detecting replacement of an existing app.
DriverTimeStamp PE link date of a driver Same caveats as LinkDate.

The KeyLastWriteTimestamp gotcha#

KeyLastWriteTimestamp is the last time the registry key was written, which is the last time the appraiser touched the record. If Windows re-evaluated the file last Tuesday because of a metadata change, the timestamp says Tuesday. Not the date the file was first observed.

So:

  • You cannot assume KeyLastWriteTimestamp is "first seen".
  • You can assume it is "last touched by the appraiser".
  • For "first seen", correlate against shadow copies of prior Amcache hives or against the USN journal entry referenced by Usn.

The "Amcache = execution" myth#

Many older blog posts claim "Amcache proves execution". This is not safe. Maxim Suhanov's 2018 work ("Windows ShellBag and Amcache forensics: just stop relying on single-source signals") demonstrated that the appraiser inventories files that have not executed - files merely present in the directories the appraiser scans.

What Amcache reliably proves:

  • The file existed on the system at inventory time.
  • Its hash, path, publisher, and PE metadata at that moment.

What Amcache does not prove on its own:

  • That the file executed.
  • When the file was first placed on disk.
  • That the user (rather than the system) is responsible.

For execution, corroborate with Prefetch, Sysmon 1, Security 4688, Shimcache, BAM/DAM, UserAssist, or SRUM. Amcache is a great triage artefact and a strong supporting artefact, but it is a weak sole-source execution witness.

9. ProgramId and FileId#

ProgramId (44 characters)#

Hash derived from the application's name, version, publisher, and language. Exact algorithm is not officially documented but practically:

  • Same product installed on two machines usually has the same ProgramId.
  • A point-release upgrade usually changes it.
  • It is not a content hash. Two different binaries from the same product share a ProgramId.

Use ProgramId to pivot, never to identify a file.

FileId (0000 + 40 hex)#

The content hash:

FileId = "0000" + SHA1(first 31 MiB of file content)

For files under 31 MiB, FileId[4:] equals the file's full SHA-1. For larger files it is a prefix hash and will not match a whole-file SHA-1. A 200 MB packed installer has a FileId that does not match its full-file SHA-1, and VT lookups keyed on the full hash may miss while lookups on the Amcache value hit (or vice versa). When in doubt, search both.

10. Anti-forensics and tampering#

Amcache can be tampered with. The hive lives on disk and can be modified offline. Patterns:

  • Selective key deletion by a SYSTEM-level actor between appraiser runs.
  • Set-ItemProperty-style writes to plant misleading LinkDate or Publisher values on a binary the attacker wants to look benign.
  • Hive replacement with a hive harvested from a clean machine.
  • Disabling the appraiser scheduled task (visible in Task Scheduler history and Microsoft-Windows-Application-Experience event logs).

Defensive corroborations:

  • .LOG1 / .LOG2 often hold pre-tamper state.
  • Volume Shadow Copies of Amcache.hve from prior days give before/after.
  • The USN journal records writes to the hive file itself.
  • Microsoft-Windows-Application-Experience/Program-Telemetry event log records appraiser runs.

If a hive looks too tidy - sparse InventoryApplicationFile, no unassociated rows, perfect publisher coverage - be suspicious. A normal Windows desktop accumulates thousands of file records over its lifetime.

11. Cross-artefact corroboration#

Amcache is strongest joined to neighbours. The joins that pay off:

Question Join Amcache against
Was this binary actually executed? Prefetch .pf files, Sysmon 1, BAM/DAM, Shimcache, UserAssist
When was it placed on disk? $MFT $STANDARD_INFORMATION and $FILE_NAME, USN journal
Where did it come from? InstallSource in Programs, Zone.Identifier ADS, browser history, email gateway logs
Did it phone home? DNS logs, Sysmon 3, firewall logs, SRUM
What user ran it? Security 4688, BAM/DAM (per-SID), UserAssist (per-NTUSER)
Earlier state of this hive? Shadow Copies, prior backups, KAPE Triage collections

A finding sourced from Amcache plus Prefetch plus Security 4688 is reportable. A finding sourced from Amcache alone is a lead.

12. Tools that read Amcache#

No single tool is best for everything. A working DFIR shop keeps several around.

Tool Strengths Reach for it when
AmcacheParser (Eric Zimmerman) Canonical, well-tested, KAPE-integrated, CSV Bulk processing, KAPE pipelines, court-ready output
RegRipper (amcache.pl) Text reports, narrative timelines You want a human-readable summary
Browser parser (this site) Zero install, client-side WebAssembly, no upload Quick triage, classroom demos, locked-down laptops
Velociraptor Windows.Registry.Amcache Fleet-wide collection and parsing EDR-style sweep across hundreds of hosts
Magnet AXIOM / EnCase GUI + integrated case management Commercial-tool shops
Python python-registry / Rust nt-hive Programmatic Custom pipelines, research

If you want to skip installs entirely, drop a hive on the home page and you will see every key and value in a few seconds. Nothing leaves the browser.

13. Further reading#

Most of what is "known" about Amcache comes from a small number of researchers. If you only have time to read four things:

  • Willi Ballenthin (Mandiant). The original Amcache field mapping for the legacy schema. Still canonical for pre-1607 hives.
  • Andrea Fortuna. Multiple posts walking through the Inventory* schema as it evolved through Windows 10.
  • Maxim Suhanov. Registry-internals work, plus the most rigorous treatment of what Amcache does and does not prove. His work killed the "Amcache = execution" myth.
  • Eric Zimmerman's tool notes. Read AmcacheParser's release notes; that's where new schema fields get publicly documented first.

Then read your own hives. The schema in the wild contains fields no single blog post covers, and the only reliable way to know what your Windows build is recording is to look.

Related posts

Back to all posts