Windows artifacts · Lesson 3 of 9
Program execution: Prefetch, Amcache, Shimcache and BAM
10 min read
"Did this program run, when, and as which user?" is one of the most common questions in a Windows case. No single artifact answers all three parts. This lesson covers the main execution artifacts on Windows 10 and 11: where each one is in a triage collection, which timestamps it holds, and what it proves and does not prove. The method is to state a run time only from an artifact that records execution, and to corroborate it with the others.
Prefetch
The prefetcher speeds up program start by recording what an executable loads. Each executable gets a file C:\Windows\Prefetch\<EXENAME>-<HASH>.pf, for example XFER.EXE-1A2B3C4D.pf. The 8-hex-digit hash is computed from the full path of the executable, and for hosting processes such as svchost.exe, rundll32.exe and dllhost.exe also from the command line. For other executables, the same name with different hashes therefore means the program ran from different paths, which often matters: SVCHOST.EXE outside System32 is suspicious.
Format
On Windows 10 and 11 the .pf files are compressed. They begin with the signature MAM followed by a byte whose low nibble 4 means XPRESS Huffman (usually 0x04), then the uncompressed size, so a hex editor shows nothing readable until a tool decompresses them. After decompression the header starts with the format version at offset 0 (30, that is 0x1E, on Windows 10 and 11; some Windows 11 builds use 31, so expect "version 30 or later"), the signature SCCA at offset 4, the executable name in UTF-16 at offset 0x10 and the path hash at offset 0x4C. Parsed, a file gives:
- the run count;
- up to 8 last run times (FILETIME, UTC), the most recent first;
- the files and directories referenced during roughly the first ten seconds of execution, often including DLLs, data files and the program's own full path;
- volume information: device path, volume serial number and volume creation time.
The .pf file is written about ten seconds after the program starts. Its own file system timestamps are therefore useful: creation time ≈ first run (the first run is about 10 seconds earlier) and modification time ≈ last run. This matters when the run count is above 8 and the oldest run times have rolled off.
Settings and limits
Prefetch is controlled by EnablePrefetcher under SYSTEM\ControlSet001\Control\Session Manager\Memory Management\PrefetchParameters (0 disabled, 1 application launch, 2 boot only, 3 both). Client Windows enables it by default; Windows Server usually has application prefetching disabled. Since Windows 8 the folder holds up to 1,024 .pf files, and older ones are discarded. In an offline hive there is no CurrentControlSet; read SYSTEM\Select\Current to choose the right ControlSet00x (Lesson 2.1).
Proves: the executable at that path was launched, how often, and when. Does not prove: which user ran it, whether it finished its task, or that it never ran before (a deleted or evicted .pf erases history). PECmd is an example parser.
Amcache.hve
C:\Windows\AppCompat\Programs\Amcache.hve is a registry-format hive with its own transaction logs, Amcache.hve.LOG1 and .LOG2; collect all three and replay the logs before parsing. On current Windows 10 and 11 builds, files are listed under Root\InventoryApplicationFile, one subkey per file, with values such as:
| Value | Meaning |
|---|---|
LowerCaseLongPath | Full path in lower case |
Name, Publisher, Version | From the PE version resource (may be empty) |
Size | File size in bytes |
LinkDate | PE header compile time (set by the linker, can be forged) |
FileId | 0000 followed by the SHA-1 of the file |
ProgramId | Links to an installed program in Root\InventoryApplication |
The SHA-1 covers the whole file only up to 31,457,280 bytes (30 MiB); for a larger file it covers the first 31,457,280 bytes, so hashing the full file will not match. Root\InventoryApplication lists installed programs with name, publisher, version and install information. Older builds used Root\File instead.
The important caveat: on Windows 10 and 11, Amcache is filled by inventory tasks that scan installed programs and files, so an entry shows that the file was present and inventoried, not necessarily that it ran. The LastWrite time of an entry's key is when Windows wrote the entry, not a run time. Treat Amcache as strong supporting evidence, and use its SHA-1 to identify the exact binary, even after the file is deleted. AmcacheParser is an example tool.
Shimcache (AppCompatCache)
The Application Compatibility cache is stored in SYSTEM\ControlSet001\Control\Session Manager\AppCompatCache, value AppCompatCache, as one binary blob. On Windows 10 and 11 each entry begins with the signature 10ts and holds the file path and the file's last modified time from $STANDARD_INFORMATION. That time is not an execution time, and on Windows 10 and 11 there is no reliable flag showing that the file ran. Entries are ordered most recent first, so position can help order events, and the cache holds up to 1,024 entries.
The cache lives in memory and is written to the hive at shutdown or reboot. A triage collected from a running system therefore holds the cache as it was at the last shutdown: recent programs may be missing (memory analysis in Module 5 can recover them). Proves: a file existed at that path with that modified time. Does not prove: execution or a run time. AppCompatCacheParser is an example tool.
BAM and DAM
The Background Activity Moderator, a service from Windows 10 version 1709, keeps a per-user list in the SYSTEM hive:
SYSTEM\ControlSet001\Services\bam\State\UserSettings\<SID>(later Windows 10 builds and Windows 11);SYSTEM\ControlSet001\Services\bam\UserSettings\<SID>on older Windows 10 builds.
Each value is named by the full device path, such as \Device\HarddiskVolume3\Users\ana\Downloads\xfer.exe, and the first 8 bytes of the data are a FILETIME (UTC) of the program's last execution. Map the volume to a drive letter with the other artifacts; the Windows volume is usually C:. Because the key is per SID, BAM, like UserAssist below, ties a run to a user account (Lesson 2.2 resolves SIDs). Entries are cleaned up: entries older than about a week, and entries for deleted executables, can disappear at startup, so absence proves little. The time may differ by seconds or more from the Prefetch run time. The Desktop Activity Moderator (Services\dam\...) uses the same layout and appears mainly on devices with modern standby.
UserAssist
NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count records programs the user launched through Explorer: Start menu, desktop, double-click. {CEBFF5CD-ACE2-4F4F-9178-9926F41749EA} holds executables and {F4E57C4B-2036-45F0-A9AB-443BCFE33D9F} holds shortcuts. Value names are ROT13-encoded: P:\Hfref\nan\Qbjaybnqf\ksre.rkr decodes to C:\Users\ana\Downloads\xfer.exe. Known folders appear as GUIDs, for example {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7} for System32. The 72-byte data holds the run count (offset 4), focus count (offset 8), focus time in milliseconds (offset 12) and the last run FILETIME (offset 60). It proves a GUI launch by that user, but programs started from a command line, a script or a service do not appear.
Program Compatibility Assistant logs (Windows 11)
Windows 11 22H2 and later write plain-text files in C:\Windows\appcompat\pca\. PcaAppLaunchDic.txt holds one line per executable: full path, |, and a last-launch time in UTC, such as C:\Users\ana\Downloads\xfer.exe|2026-03-14 10:42:17.130. Public research shows these lines track programs launched through Explorer, but the format is undocumented and not every process appears. Treat a line as execution evidence to corroborate, and its absence as meaningless.
Comparison
| Artifact | Location | Timestamp means | Proves execution? |
|---|---|---|---|
| Prefetch | C:\Windows\Prefetch\*.pf | Up to 8 last runs; .pf created ≈ first run, modified ≈ last run | Yes (no user) |
| Amcache | C:\Windows\AppCompat\Programs\Amcache.hve | Key LastWrite = entry written; LinkDate = compile time | No, supports it; gives SHA-1 |
| Shimcache | SYSTEM ...\Session Manager\AppCompatCache | File's $SI last modified time | No, presence only |
| BAM | SYSTEM ...\Services\bam\State\UserSettings\<SID> | Last execution | Yes, per user |
| UserAssist | NTUSER.DAT ...\Explorer\UserAssist\{GUID}\Count | Last GUI launch | Yes, GUI launches by that user |
| PCA | C:\Windows\appcompat\pca\PcaAppLaunchDic.txt | Last launch (UTC text) | Supports; corroborate |
Worked example: when did xfer.exe run?
The triage collection of a Windows 11 laptop contains C:\Windows\Prefetch\XFER.EXE-1A2B3C4D.pf (the hash value here is illustrative).
Prefetch. PECmd reports version 30, run count 3, and the referenced path \VOLUME{…}\USERS\ANA\DOWNLOADS\XFER.EXE. The newest run time is FILETIME 0x01DCB39F3A299D50 = 134,179,585,371,250,000. Dividing by 10,000,000 gives 13,417,958,537.125 s since 1601-01-01; subtracting 11,644,473,600 s (1601 to 1970) gives Unix time 1,773,484,937.125, that is 2026-03-14T10:42:17.125Z. The other run times are 2026-03-14T10:05:33Z and 2026-03-13T16:20:02Z. The .pf file was created at 2026-03-13T16:20:12Z (10 s after the first run) and modified at 2026-03-14T10:42:27Z, both consistent.
BAM. Under bam\State\UserSettings\S-1-5-21-…-1001, the value \Device\HarddiskVolume3\Users\ana\Downloads\xfer.exe starts with 50 AB 50 41 9F B3 DC 01. Read little-endian, that is 0x01DCB39F4150AB50 = 134,179,585,491,250,000, which is 2026-03-14T10:42:29.125Z: 12 seconds after the Prefetch last run, and tied to RID 1001, the account ana.
Amcache. An InventoryApplicationFile entry has LowerCaseLongPath c:\users\ana\downloads\xfer.exe, Size 1,482,752 (below 31,457,280, so the SHA-1 covers the whole file), empty Publisher and FileId 00003f2a9c1e7b0d4e85a6c2f19b0e7d3a5c48b1f6e2. Removing 0000 leaves the 40-hex-digit SHA-1 3f2a9c1e7b0d4e85a6c2f19b0e7d3a5c48b1f6e2, which you can match against a copy on the USB drive image or a malware database.
The trap. Shimcache lists C:\Users\ana\Downloads\xfer.exe with time 2026-03-13T16:18:40Z. That is the file's last modified time, most likely when the download was written, and it matches the $SI modified time in the $MFT. It is not a run time: the answer to "when was xfer.exe first executed?" is 2026-03-13T16:20:02Z from Prefetch, not 16:18:40Z.
Exam focus: Expect to report a first or last run time from Prefetch in UTC, a SHA-1 from AmcacheFileId(without the0000prefix), or the SID that BAM ties to a program. Questions are likely to test which timestamps mean execution: Shimcache times are file modification times and Amcache entries show presence. Two .pf files with the same name and different hashes mean two paths, unless the program is a hosting process such as svchost.exe.
Key points
- Prefetch (
EXENAME-HASH.pf, MAM-compressed, version 30 or later) gives run count, up to 8 run times, referenced files and volume data; the hash depends on the path. - The .pf file's creation time is about 10 seconds after the first run and its modification time about 10 seconds after the last run.
- Amcache
InventoryApplicationFilegives path, size, LinkDate and SHA-1 (FileIdminus0000, first 31,457,280 bytes), but shows presence, not execution. - Shimcache records path and $SI modified time, is written at shutdown, and has no reliable execution flag on Windows 10 and 11.
- BAM gives a last-execution FILETIME per user SID; UserAssist gives ROT13-encoded GUI launches per user; PCA logs on Windows 11 22H2+ add a text record to corroborate.