Amcache timestamps explained: KeyLastWriteTimestamp vs LinkDate vs the rest
Amcache exposes multiple distinct timestamps, and confusing them is the single most common mistake new analysts make. Date a finding wrong and the entire timeline collapses. This page is the full reference. Every timestamp, what it actually represents, which one to pivot on for any given question.
For broader context, see the Amcache complete reference. For the surrounding registry structure, see Amcache registry structure.
The timestamps at a glance#
| Timestamp | Source | Represents |
|---|---|---|
KeyLastWriteTimestamp |
Registry key metadata | When the appraiser last wrote this entry. The closest thing to "when Amcache recorded this". |
LinkDate |
PE IMAGE_FILE_HEADER.TimeDateStamp |
When the binary was compiled/linked. Attacker-controllable. |
InstallDate |
InventoryApplication value |
When the application was installed. |
MsiInstallDate |
InventoryApplicationFile value |
When the parent MSI was installed (if any). |
LastModified |
Hive value (schema-dependent) | Last-modified marker, present in some schema versions. |
LastWriteTimestamp (legacy Programs) |
Registry key metadata | Same idea as KeyLastWriteTimestamp, for the legacy Root\Programs schema. |
The single most important rule:
KeyLastWriteTimestampis the "when was this seen on this host" pivot. Everything else is a different question.
KeyLastWriteTimestamp#
The registry-level last-write time of the key containing the entry. Hive metadata. Windows updates it every time the key's contents change.
For Root\InventoryApplicationFile\<entry>, the KeyLastWriteTimestamp is updated whenever the appraiser writes or updates that entry:
- The first time the appraiser inventories a file, the key is created and its
KeyLastWriteTimestampis the inventory time. - If the file's metadata changes between inventories (size, hash, version), the key is rewritten and the timestamp advances.
- If nothing changes between inventories, the timestamp stays put. Even when the appraiser ran again and confirmed the file is still present.
That last point matters: KeyLastWriteTimestamp is not "the most recent time the appraiser saw this file". It is "the most recent time the appraiser wrote about this file". For a stable, unchanged file, the timestamp can be weeks or months old even though the file has been present that entire time.
What KeyLastWriteTimestamp is good for#
- First-seen approximations. For a binary the attacker dropped new on a clean host,
KeyLastWriteTimestampis the appraiser-run time after the drop. Subject to: - The appraiser does not run instantly. Up to ~24h delay on workstations, longer on servers.
- The binary must still be present at appraiser time. Transient binaries deleted before the next pass may never appear.
- Resolution is whatever the appraiser writes. Typically second-precision.
- Time-window joins. Once you have a suspicious entry, take its
KeyLastWriteTimestamp± your chosen window (one hour is a common default) and join all other CSVs (Prefetch, Sysmon, Security 4688) on that window. You get the full story of what happened around the inventory event. - Detecting binary replacement. If two
InventoryApplicationFilerows share the sameFullPathbut have differentHashvalues and differentKeyLastWriteTimestampvalues, the binary at that path changed between those two times. Sort by timestamp to see the sequence.
What KeyLastWriteTimestamp is not good for#
- "When did this binary first exist on disk?" That's a filesystem question.
$STANDARD_INFORMATION.CreationTimein the MFT.KeyLastWriteTimestampis at best an upper bound: the file existed on disk no later than the timestamp, probably earlier. - "When did this binary execute?" Amcache records presence, not execution. Use Prefetch.
- Sub-second precision. Don't draw conclusions from milliseconds.
LinkDate#
The PE-header TimeDateStamp. The value the linker stamped into the binary's IMAGE_FILE_HEADER at compile/link time. Every PE has one.
What LinkDate is good for#
- Clustering binaries by build campaign. Sort unassociated PEs on a host by
LinkDateand you frequently see tight clusters: 3-10 binaries all stamped within the same day or hour. That is often a single attacker compiling their full toolkit in one sitting. - Spotting suspiciously old or new builds. A driver compiled in 2014 that first shows up in your Amcache today is a flag for BYOVD. A binary compiled in the future is a flag for clock-skew or sloppy tooling.
- Confirming a build belongs to the expected campaign. "Our internal tool builds always linkdate Mondays at 03:00 UTC. This one is Tuesday at 14:00. Investigate."
What LinkDate is not good for#
- "When did this binary appear on this host?" Attacker-controllable. The attacker can set any
TimeDateStampthey want at link time, sometimes set to0deliberately (reproducible builds) or to a past date (to make the binary look old/established). TrustingLinkDateas a host-presence pivot produces wrong findings. - Cryptographic identity.
LinkDatealone is not unique. Many binaries share the same link timestamp.
InstallDate (on InventoryApplication)#
When the application was installed, in registry FILETIME format. Useful for:
- Cross-checking with
KeyLastWriteTimestampon the file records. If a file'sKeyLastWriteTimestampis significantly older than its parent application'sInstallDate, something is unusual. The file appears to have been on disk before the application existed according to Windows. - Detecting silent installs. Applications installed without user interaction sometimes leave
InstallDatenear 1601-01-01 (the FILETIME epoch) or at unrealistic future dates. Both are flags.
MsiInstallDate (on InventoryApplicationFile)#
The install date of the parent MSI for files that came from an MSI installer. Same FILETIME format as InstallDate. Useful for distinguishing files that arrived via a proper MSI install from files that arrived via copy / drop.
LastModified (when present)#
Some Amcache schema versions expose a per-file LastModified value. Not every hive has it. When present, treat it as the filesystem last-modified time as the appraiser saw it at inventory - not authoritative. The MFT's $STANDARD_INFORMATION is authoritative.
LastWriteTimestamp on legacy Programs#
The legacy Root\Programs schema exposes a per-entry LastWriteTimestamp conceptually identical to KeyLastWriteTimestamp in the modern schema. Same caveats apply.
The standard time-bound pivot#
The investigation pattern most analysts standardise on:
- Identify a suspicious row in
*_UnassociatedFileEntries.csv(typically via "unsigned PE in user-writable path"). - Take its
KeyLastWriteTimestamp. - Define a one-hour window centred on that timestamp.
- Pull from that window:
- All other Amcache rows (cross-key: drivers, devices, shortcuts).
- All Prefetch entries (definitive execution).
- All Security 4688 process-creation events.
- All Sysmon
1(process create),7(image load), and11(file create) events. - All filesystem creates from the MFT and USN journal.
- The resulting timeline is the full picture of what happened around that inventory event.
This is the canonical "what was the attacker doing in this minute?" join, and KeyLastWriteTimestamp is the anchor that makes it possible.
A worked example#
Two Amcache rows for the same path:
FullPath: C:\Users\bob\AppData\Local\Temp\notepad.exe
Row A: KeyLastWriteTimestamp = 2026-03-12 14:23:11 UTC
Hash = aaaaaaaa...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
Row B: KeyLastWriteTimestamp = 2026-04-19 02:14:55 UTC
Hash = bbbbbbbb...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
Reading:
LinkDateis identical. That's theTimeDateStampin the PE header. The attacker reused the same build identity, or used a template that linkstamps every build the same. Not evidence of build time.Hashdiffers. Different content at the path at the twoKeyLastWriteTimestampmoments.KeyLastWriteTimestampdiffers. Amcache saw the path twice, ~5 weeks apart, with different content each time.
Conclusion: a binary at this path was replaced between March 12 and April 19. Pivot on the April 19 timestamp ± 1h for the new binary's drop event. Pivot on March 12 ± 1h for the original drop. Two intrusion events. One path. One Amcache entry to find both.
Further reading#
- Maxim Suhanov on registry key write-time semantics.
- Yogesh Khatri's deep dive on Amcache, including the timestamp gotchas.
Related#
Related posts
- Volatility and Amcache: extracting the hive from memory images
When you only have a RAM dump, Volatility extracts the in-memory copy of Amcache.hve. Hand off to AmcacheParser. The cases where this is the only option.
- RegRipper amcache plugin: what it does and when to use it
RegRipper's amcache plugin produces a plain-text Amcache report. Useful when you're already running RegRipper across other hives or need narrative output. Use AmcacheParser when you need CSV.
- What is LinkDate in Amcache? (glossary)
LinkDate is the PE TimeDateStamp. Attacker-controllable. Use it for build clustering, not for host timelines.
- What is KeyLastWriteTimestamp in Amcache? (glossary)
The registry write time of the Amcache key. Closest thing to 'when the appraiser recorded this'. The single field new analysts most often confuse with LinkDate.