<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: analyzing-prefetch-files
description: >-
  Windows Prefetch file forensic analysis for application execution evidence
  including run count, last execution timestamps, loaded DLLs/files, volume
  information, and hash-based file identification using PECmd, winprefetchview,
  and manual binary parsing of MAM/SCCA compressed Prefetch format.
domain: cybersecurity
subdomain: digital-forensics
tags:
  - prefetch
  - application-execution
  - pecmd
  - windows-forensics
  - program-execution
  - mam-compression
version: "1.0"
author: defconxt
license: AGPL-3.0
compatibility: Designed for Claude Code, GitHub Copilot, OpenAI Codex, Cursor, Gemini CLI, and any agentskills.io-compatible agent.
metadata:
  mitre-attack: ["T1059", "T1204"]
  nist-csf: ["RS.AN-3"]
  frameworks: ["NIST SP 800-86"]
---

# Analyzing Prefetch Files

## Overview

Windows Prefetch files (`.pf`) are created in `C:\Windows\Prefetch\` when
applications execute. They contain execution timestamps (up to 8 last runs
on Win8+), run count, loaded files and directories, and volume device paths.
Prefetch analysis provides critical evidence of program execution even after
the executable has been deleted.

## Prerequisites

- PECmd (Eric Zimmerman) for automated parsing
- WinPrefetchView (NirSoft) for GUI analysis
- Python 3.10+ for manual parsing
- Access to `C:\Windows\Prefetch\` from forensic image

```bash
# Extract Prefetch directory from mounted image
cp -r /mnt/evidence/Windows/Prefetch/ ./prefetch_files/
```

## Key Concepts

### Prefetch File Naming Convention

```
Format: <EXECUTABLE_NAME>-<HASH>.pf
Example: CMD.EXE-89305D47.pf

The hash is based on:
  - Executable path (case-insensitive)
  - Command-line arguments (for hosting executables like svchost, dllhost, mmc)

Multiple Prefetch files for same executable = different paths or arguments:
  SVCHOST.EXE-A1B2C3D4.pf  (svchost -k netsvcs)
  SVCHOST.EXE-E5F6A7B8.pf  (svchost -k LocalService)
```

### Prefetch Versions

| Windows Version | Prefetch Version | Compression | Max Files | Timestamps |
|----------------|-----------------|-------------|-----------|------------|
| XP/2003 | 17 | None | 128 | 1 last run |
| Vista/7 | 23 | None | 128 | 1 last run |
| 8/8.1 | 26 | MAM (Xpress) | 1024 | 8 last runs |
| 10/11 | 30 | MAM (Xpress Huffman) | 1024 | 8 last runs |

### Forensic Value

```
Evidence of execution:
├── Prefetch file exists → program was executed
├── Run count → how many times
├── Last run timestamps → when (up to 8 most recent)
├── Loaded files list → what DLLs/data files were accessed
├── Volume device path → which drive it ran from
└── File references → can reveal data access patterns
```

## Workflow

### Step 1: Parse with PECmd

```bash
# Parse single Prefetch file
PECmd.exe -f "CMD.EXE-89305D47.pf"

# Parse entire Prefetch directory to CSV
PECmd.exe -d C:\Windows\Prefetch --csv . --csvf prefetch_output.csv

# Parse with timeline output
PECmd.exe -d C:\Windows\Prefetch --csv . --csvf pf.csv -q

# Key CSV columns:
# SourceFilename, ExecutableName, RunCount,
# LastRun (×8 for Win8+), FilesLoaded, Directories
```

### Step 2: Python Prefetch Parser

```python
import struct
from datetime import datetime, timedelta, timezone
from pathlib import Path

WINDOWS_EPOCH = datetime(1601, 1, 1, tzinfo=timezone.utc)

def filetime_to_dt(ft: int) -> str:
    if ft <= 0:
        return ""
    return (WINDOWS_EPOCH + timedelta(microseconds=ft // 10)).isoformat()

def parse_prefetch_header(data: bytes) -> dict:
    """Parse Prefetch file header (after decompression for Win8+)."""
    if len(data) < 84:
        return {"error": "File too small"}
    version = struct.unpack_from("<I", data, 0)[0]
    signature = data[4:8]
    if signature != b"SCCA":
        return {"error": "Invalid signature (not SCCA)"}
    file_size = struct.unpack_from("<I", data, 12)[0]
    exe_name = data[16:76].decode("utf-16-le").rstrip("\x00")
    hash_val = struct.unpack_from("<I", data, 76)[0]
    return {
        "version": version,
        "executable": exe_name,
        "prefetch_hash": f"{hash_val:08X}",
        "file_size": file_size,
    }

def parse_v30_timestamps(data: bytes) -> list[str]:
    """Extract up to 8 execution timestamps from Version 30 Prefetch."""
    timestamps = []
    offset = 128  # Typical offset for v30 last run times
    for i in range(8):
        ft = struct.unpack_from("<Q", data, offset + (i * 8))[0]
        ts = filetime_to_dt(ft)
        if ts:
            timestamps.append(ts)
    return timestamps
```

### Step 3: Decompress MAM-Compressed Prefetch (Win10/11)

```python
import ctypes
import ctypes.wintypes

def decompress_mam(compressed_data: bytes) -> bytes:
    """Decompress MAM (Xpress Huffman) compressed Prefetch files."""
    # Signature check: MAM\x04
    if compressed_data[:3] != b"MAM":
        return compressed_data  # Not compressed
    decompressed_size = struct.unpack_from("<I", compressed_data, 4)[0]
    # Use Windows RtlDecompressBufferEx or external library
    # For cross-platform: use python-lzxpress
    try:
        import lzxpress
        return lzxpress.decompress(compressed_data[8:], decompressed_size)
    except ImportError:
        return compressed_data  # Fallback: return raw
```

### Step 4: Correlate with Execution Timeline

```bash
# Key Prefetch files for incident response:
# POWERSHELL.EXE-*.pf     — PowerShell execution
# CMD.EXE-*.pf            — Command prompt usage
# PSEXEC.EXE-*.pf         — Remote execution tool
# WMIC.EXE-*.pf           — WMI command-line
# NET.EXE-*.pf            — Network commands
# CERTUTIL.EXE-*.pf       — Often used for download/decode
# RUNDLL32.EXE-*.pf       — DLL execution
# MSHTA.EXE-*.pf          — HTML Application host
# REGSVR32.EXE-*.pf       — COM object registration
# SCHTASKS.EXE-*.pf       — Scheduled task creation
```

## Detection

```yaml
title: Prefetch Files Detection
id: a4d7de33-0bd2-465e-a7ac-94e913a05830
status: experimental
description: Detects suspicious activity related to analyzing prefetch files techniques in digital forensics context
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    CommandLine: "*analyzing*prefetch*"
  condition: selection
level: medium
tags:
  - attack.t1059
  - attack.t1204
  - attack.collection
falsepositives:
  - Forensic investigation tools used by authorized incident response team
```

## Verification

- [ ] Prefetch directory extracted and preserved
- [ ] All .pf files parsed with execution timestamps and run counts
- [ ] Suspicious executables identified (LOLBins, unknown programs)
- [ ] Loaded file references analyzed for data access patterns
- [ ] Execution timeline correlated with other artifact sources
- [ ] Deleted executables identified via Prefetch (program ran but binary gone)

## References

- [PECmd — Eric Zimmerman](https://ericzimmerman.github.io/)
- [WinPrefetchView — NirSoft](https://www.nirsoft.net/utils/win_prefetch_view.html)
- [Prefetch File Format — libyal](https://github.com/libyal/libscca)
- [SANS Prefetch Forensics](https://www.sans.org/blog/digital-forensics-prefetch-artifacts/)
