What changed in Windows Prefetch v30 and v31
The first four bytes inside the decompressed SCCA payload are the version number. It is the most useful single field in a Prefetch file. Get it right and you know which header layout to apply, how many last-run slots to read, and which Windows family wrote the file:
| Version | Windows | Compression | Last-run slots |
|---|---|---|---|
| 17 | XP, Vista, 7 | None | 1 |
| 23 | Windows 8 | Xpress Huff. | 1 |
| 26 | Windows 8.1 | Xpress Huff. | 8 |
| 30 | Windows 10 | Xpress Huff. | 8 |
| 31 | Windows 11 | Xpress Huff. | 8 |
Get it wrong and the parser hands you garbage with no error, which is the more common failure mode.
The v26 jump: eight run times
The single most consequential change in the format history landed with Windows 8.1 (v26). The header gained room for eight last-run FILETIME values instead of one. Before 8.1, a .pf told you the binary ran most recently at time T. From 8.1 onward you get a rolling window of the eight most recent executions, each as a Windows FILETIME (u64, 100-nanosecond ticks since 1601-01-01 UTC).
For DFIR this is the difference between "the program ran at some point before yesterday" and "the program ran eight times in the last three days at these specific moments." Pair the eight timestamps with Sysmon EID 1 or Security 4688 and you have a defensible execution timeline at the second level.
Note the cap: eight, not "at least eight." If a binary runs a hundred times, you get the eight most recent. The other 92 are folded into the run counter and otherwise lost. The "last run was nine hours ago" reading from one collection plus "last run was three minutes ago" from a later collection on the same host tells you executions kept happening; the eight-slot history does not let you reconstruct the full sequence.
v30: Windows 10
v30 reshuffles offsets in the file information section and tightens the volume information records, but the externally visible fields are the same as v26: executable name, hash, run count, eight last-run times, volume info (path, serial, creation time), and the file-metric list of every DLL and resource the binary touched in its first ten seconds of monitored execution.
Most parsers do not need radically different code paths inside the payload past reading the version number. The fields are the same width and meaning; only their positions move. PECmd handles v30 cleanly; so does libscca and pyscca.
Worth knowing on Win10 1709+: Windows began expiring .pf entries more aggressively during maintenance. If a binary's eight last-run slots only show three populated FILETIME values, that does not mean the binary ran three times. It means at least three. The run counter is the authoritative count.
v31: Windows 11
v31 is incremental over v30. A few padding tweaks, additional bits in the prefetch flags field. Practically, a parser that reads v30 correctly will read v31 with at most a small offset adjustment in the header. If your toolchain claims "Windows 10 support" but errors on v31, the cause is almost always an over-strict version check (version == 30) rather than a real layout incompatibility.
On Win11 22H2 and newer, Prefetch on SSDs is opportunistically disabled by parts of the OS. Forensically this is a coverage problem, not a v31 layout problem — the files you do get are valid v31, there are just fewer of them than the registry would suggest.
What this means for triage
When the parser shows Ver. 31 you can rely on the eight-deep last-run history, the run counter, and the file-metric list. When it shows Ver. 17, you get a single last-run timestamp and the binary was launched on an XP, Vista, or Win7 host. Finding a v17 on a Windows 10 or 11 image is a strong signal that the .pf was carried in from elsewhere — there is no realistic scenario where a modern Windows host writes v17 natively.
Mixed versions in a single Prefetch folder are normal on a host that has been upgraded across major versions; a Windows 10 image with v23 entries left over from a long-ago Windows 8 install is not unheard of. A Windows 11 image with v17 is. The version field is one of the first triage signals worth scanning across the entire folder.
Further reading
- Joachim Metz, libscca format documentation — has the per-version field tables.
- Eric Zimmerman, PECmd — handles every version above correctly out of the box.