Building a program-execution timeline from a SYSTEM hive

4 min read

TL;DR. Build a fused timeline of ShimCache + AmCache + Prefetch + BAM/DAM + Security/Sysmon. Use ShimCache to define the cast (paths), then enrich each row with timestamps from sources that actually record events. Tag every timestamp with its source semantics. Never collapse "file mtime" and "process start" into one column.

A program-execution timeline is the most useful artifact a Windows IR investigator produces. Done well, it tells a chronological story across multiple data sources. Done badly, it overstates evidence and gets challenged by anyone who knows what an mtime is. Here is the workflow I run, with the ShimCache as the spine.

Why ShimCache is a good spine

The cache is rarely the most accurate source for any single field, but it has unique advantages as a timeline anchor:

  • It carries the file path explicitly. Some artifacts only have hashes or partial paths.
  • It captures executables Windows merely examined, so it includes binaries that ran briefly and were deleted (which Prefetch and BAM may miss).
  • It survives many anti-forensic attempts that wipe other artifacts, with important caveats.

Use ShimCache to define the cast of characters in the timeline. Then enrich each row with corroborating artifacts to assign reliable times.

The data sources to fuse

A complete program-execution timeline pulls from at least these five:

SourceWhat it adds to the row
ShimCachePath + file mtime
AmCacheSHA-1, file size, publisher, install timestamp, first-run timestamp
PrefetchProcess-start times (up to last 8), loaded modules
BAM/DAMPer-user "last execution" timestamp on Win10/11
Security / SysmonProcess-creation events with command line, parent, user

For background, see the program-execution artifacts reference. On larger cases, fold in SRUM for network and resource usage, the USN journal for file activity, and LNK files plus jump lists for shell history.

A reproducible workflow

  1. Collect the artifacts. SYSTEM hive with transaction logs, Amcache.hve with its .LOG1 and .LOG2, C:\Windows\Prefetch\*.pf, exported Security event log, Sysmon log if available, NTUSER.DAT per user. The acquisition guide covers the SYSTEM hive specifically.
  2. Parse each to a normalized table. Use the Eric Zimmerman suite (AppCompatCacheParser, AmcacheParser, PECmd) for offline work, or the Shimcache Parser for the ShimCache portion in your browser.
  3. Fuse on (path, optional SHA-1). The join key is the file path, with SHA-1 from AmCache as a secondary signal. Watch for case differences and path normalization (\??\C:\ vs C:\).
  4. Tag each timestamp with its source semantics. Do not merge "AmCache install_date" and "Prefetch run_time" into one column. They answer different questions. Keep them adjacent but distinct.
  5. Render to a tool that handles per-row source attribution. Eric Zimmerman's Timeline Explorer (TLE) and Plaso / log2timeline both do this well. CSV in a spreadsheet works for smaller cases.

What good looks like

A defensible row in a final timeline:

2026-04-12 09:14:33 UTC  C:\Users\alice\AppData\Local\Temp\setup.exe
  ShimCache mtime: 2026-04-12 09:14:30 UTC
  AmCache       : SHA-1 a3b8c9..., signer "Acme Updates", install 2026-04-12 09:14:33
  Prefetch      : last run 2026-04-12 09:15:01 UTC (1 execution)
  Security 4688 : 2026-04-12 09:15:01 UTC, PID 4521, parent PID 1234 (svchost.exe)

Each timestamp is sourced and the row stands up to challenge. The opposite ("ShimCache shows setup.exe ran at 09:14:33") confuses file mtime with execution time and is the kind of claim that gets reports rejected. See proof of execution.

When sources disagree

Conflicts are data.

  • ShimCache mtime ≠ Prefetch first-run. Normal. They measure different things. Note both. Do not pick one.
  • AmCache says executed, ShimCache is empty for that file. Possible reasons: anti-forensic wipe (detection patterns), the entry was evicted from the 1,024-entry cap, the binary ran after the last clean shutdown (still in memory only, pull a RAM dump).
  • Prefetch absent. Server SKUs and SSD-tuned hosts often have Prefetch disabled. Fall back to AmCache plus BAM.
  • EVTX Security 4688 has program name but no command line. Command-line auditing was off. Useful but limited. The EVTX parser covers the audit-policy prerequisites.

Stopping at the right place

A timeline does not have to be complete to be valuable. A focused window ("what ran on host X between 14:00 and 18:00 on 2026-04-11?") built rigorously beats a sprawling one with weak attribution. The malware hunting workflow helps you pick that window.

Further reading

Related articles