Recovering deleted-binary evidence from Amcache

The single most underrated feature of Amcache.hve is that it outlives the binaries it records. An attacker deletes a tool the moment they no longer need it. Amcache's snapshot of that binary's path, hash, publisher, version, and inventory time typically persists in the hive for weeks or months afterwards.

This page is the practical workflow when the binary is gone and the hive is all you have.

For the artefact background, see the Amcache complete reference. For the comparison context, see Amcache vs Prefetch and Amcache vs Shimcache.

Why Amcache outlives the binary#

The appraiser writes the inventory snapshot once per pass. Once an entry is in Root\InventoryApplicationFile it stays in the hive until:

  • A later appraiser pass actively removes it (the exception, not the rule), or
  • The hive itself is deleted or aged out.

In practice, on a Windows 11 workstation, entries persist for months even after the binary is gone. On long-running workstations, multi-year-old entries are routine.

That makes Amcache the most reliable post-deletion artefact for PE files on Windows.

What you actually recover#

When a binary is deleted, you typically lose:

  • The binary itself.
  • Filesystem timestamps in the MFT (may be wiped or overwritten).
  • The ability to verify the binary's hash directly.

What you keep in Amcache:

Recovered From
Full path at inventory time FullPath / LowerCaseLongPath
SHA-1 of first 31 MiB Hash (strip 0000 from FileId)
File size Size
PE link date LinkDate
Publisher Publisher / PublisherName
Version strings Version, BinFileVersion, ProductVersion
Product name ProductName
Application identity ProgramId
When the appraiser saw it KeyLastWriteTimestamp

Enough to submit the hash to VirusTotal (see Amcache FileId explained), pivot the ProgramId across hosts (see Lateral movement and Amcache ProgramId pivoting), time-bound the drop event via KeyLastWriteTimestamp (see Amcache timestamps explained), and reconstruct the binary's identity even though its bytes are gone.

The post-deletion workflow#

A repeatable workflow for "we think they dropped a tool here, then wiped it".

1. Collect the hive plus transaction logs#

Copy-Item 'C:\Windows\AppCompat\Programs\Amcache.hve'   'C:\Triage\' -Force
Copy-Item 'C:\Windows\AppCompat\Programs\Amcache.hve.LOG1' 'C:\Triage\' -Force
Copy-Item 'C:\Windows\AppCompat\Programs\Amcache.hve.LOG2' 'C:\Triage\' -Force

If you suspect the attacker also touched the live hive, enumerate Volume Shadow Copies and grab each shadow's copy too. See Where Amcache.hve is on disk. On a workstation, two or three shadow copies typically span the last week or two. Each is a separate parse target.

2. Parse with multi-pass#

AmcacheParser.exe `
 -f 'C:\Triage\Amcache.hve' `
 --csv 'C:\Triage\Parsed' `
 --csvf 'HOST01_amcache.csv' `
 --mp

The --mp flag is critical. It recovers orphaned entries the appraiser deassociated but did not fully delete. Some of those are exactly the "just deleted" rows you are looking for.

3. Filter for suspicious unsigned PEs in user-writable paths#

Standard triage filter, with one modification: drop any check that FullPath exists on disk, because the file no longer does.

Import-Csv 'C:\Triage\Parsed\HOST01_amcache_UnassociatedFileEntries.csv' |
 Where-Object {
  $_.IsPeFile -eq 'True' -and
  -not $_.Publisher  -and
  $_.FullPath -match '\\Users\\|\\ProgramData\\|\\AppData\\|\\Temp\\'
 } |
 Select KeyLastWriteTimestamp, FullPath, Hash, Size, LinkDate |
 Sort-Object KeyLastWriteTimestamp

That's the list of dropped (and likely deleted) binaries as the appraiser saw them.

4. Cross-reference against the filesystem#

For each row, check whether the file still exists:

$rows = Import-Csv ... | Where-Object { ... }
$rows | ForEach-Object {
  $exists = Test-Path -LiteralPath $_.FullPath
  [pscustomobject]@{
    Path   = $_.FullPath
    Hash   = $_.Hash
    SeenAt  = $_.KeyLastWriteTimestamp
    OnDisk  = $exists
  }
} | Where-Object { -not $_.OnDisk }

Rows where OnDisk = False are your deleted-binary candidates.

5. Enrich with VirusTotal#

Hash everything, submit, capture results. Even a low-volume lookup against the public API turns up known-bad on a typical infected host.

import csv, requests, time
 
API = 'https://www.virustotal.com/api/v3/files/'
HEADERS = {'x-apikey': '<your-key>'}
 
with open('deleted_candidates.csv', newline='') as f:
  for row in csv.DictReader(f):
    h = row['Hash']
    if not h:
      continue
    r = requests.get(API + h, headers=HEADERS)
    if r.status_code == 200:
      stats = r.json()['data']['attributes']['last_analysis_stats']
      if stats.get('malicious', 0) > 0:
        print(h, row['Path'], stats)
    time.sleep(15)

For files larger than 31 MiB, remember Amcache's hash is a prefix hash, not a whole-file hash. See Amcache FileId explained.

6. Time-bound the drop#

For each confirmed-bad deleted binary, take KeyLastWriteTimestamp ± 1 hour and pull from that window:

  • All other Amcache rows (drivers, devices, other files inventoried in the same window - often the rest of the toolkit).
  • Prefetch (PECmd output). Confirms execution.
  • Security 4688 / Sysmon 1. Process creation with command line.
  • Sysmon 11. File create. Confirms when the file was written.
  • MFT entries for \Users\bob\...\. Filesystem-level corroboration.
  • USN journal entries. The other filesystem journal that often catches what the MFT misses.

You typically reconstruct the entire drop + execute + cleanup sequence from these joins, even though the binary is gone.

Anti-forensics countermeasures#

A few specific attacker techniques and how to detect them.

Drop and delete within an appraiser cycle#

Attacker drops, executes, and deletes within a single appraiser interval (<24h on workstations). The binary may never appear in Amcache.

Detection: cross-reference Prefetch (which records execution in real time, surviving binary deletion) and Sysmon 1 / 11 against Amcache. Binaries in Prefetch / Sysmon but absent from Amcache are intra-appraiser drops.

Direct hive modification#

A capable attacker with admin can edit Amcache.hve to remove specific entries. Uncommon (fiddly, most attackers don't bother) but possible.

Detection: parse the live hive AND every Volume Shadow Copy's version of the hive. Diff them. Entries in shadows but absent from live are evidence of deliberate cleanup. Entries at unexpected offsets in the live hive are evidence of restructuring.

Appraiser sabotage#

Disabling the scheduled task or zeroing AllowTelemetry. Stops new Amcache writes entirely. Old entries remain until they age out. The hive freezes at sabotage time.

Detection: check the appraiser's task history in Microsoft-Windows-TaskScheduler%4Operational.evtx via your EVTX parser. Look at the hive's KeyLastWriteTimestamp distribution. If it stops abruptly and you would expect newer entries, suspect sabotage. Also check HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags and HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection\AllowTelemetry.

Hive deletion#

The blunt instrument. Windows recreates the hive on the next appraiser run, but prior contents are lost from the live system.

Detection: the recreated hive's earliest KeyLastWriteTimestamp is much newer than expected. Compare against Volume Shadow Copies and forensic backups, recover the previous hive from shadows.

What Amcache cannot recover#

Amcache is good. It is not magic.

  • The binary itself. You have a hash and metadata, not bytes.
  • The command line at execution. Use Prefetch's file list and 4688 / Sysmon 1.
  • Network destinations the binary contacted. Use SRUM, firewall logs, EDR network telemetry.
  • The user context. Use 4688 / Sysmon 1.

Amcache is one artefact in the post-deletion toolkit. Pair with the others for a full reconstruction.

Further reading#

Related posts

Back to all posts