Methodology

How USN Parser turns a $J blob into structured records — the algorithms, the validation steps, the known limitations.

This page documents what USN Parser does to your input, why we trust the output, and where the limits are. It is meant to support a forensic chain of custody — if you cite USN Parser in a report, this is the page to reference.

Inputs

  • $UsnJrnl:$J: required. A sparse alternate data stream extracted from the volume root \$Extend\$UsnJrnl. Must be the $J stream specifically — $Max only carries journal sizing.
  • $MFT: optional. The Master File Table from the same volume. Used solely to resolve parent-directory references to full paths.

Both files are read in-memory and passed to the WebAssembly parser. The browser hands the byte buffer to the worker via postMessage with an explicit transfer list, which is faster and prevents accidental copies that linger in memory.

Parsing algorithm

We compile usnrs (Airbus CERT, Apache-2.0) to wasm32-unknown-unknown. It implements the documented USN_RECORD_V2 structure described in the Microsoft NTFS reference.

The reader:

  1. Skips the leading sparse-zero region until the first non-zero byte (the start of the first record).
  2. Walks forward, reading the 4-byte RecordLength at each offset to step to the next record.
  3. Stops at the first 4 zero bytes (end of valid records).
  4. For each record, validates the major/minor version is 2.0 and decodes the fixed-size header plus the variable-length filename.

When an $MFT is supplied, we resolve full paths by walking the parent reference chain. We only commit a full path when the resolved leaf name matches the journal's filename — preventing a stale MFT entry from producing a wrong-confidence path.

Output

Each record exposes:

  • usn (u64): position in the journal
  • timestampMs (i64): Windows FILETIME converted to Unix milliseconds, UTC
  • filename (UTF-16 decoded)
  • fullPath (string or null): only when $MFT was supplied and matched
  • reasons (string[]): the Reason bitmask expanded to readable names
  • attributes (string[]): NTFS attributes flagged on the file
  • mftEntry, mftSequence, parentMftEntry, parentMftSequence

The output stays in browser memory until you close the tab.

Limitations

  • No USN_RECORD_V3 support yet. V3 (variable-length file references, introduced with ReFS) is not produced on standard NTFS volumes, so this rarely matters in practice.
  • Ring-buffer wrap is invisible: we do not know what was overwritten before the oldest record. Cross-check with $LogFile and Volume Shadow Copies if you need older history.
  • No timestamp validation: we trust the FILETIME in the record. To detect timestomping, the SI vs FN comparison post describes the standard cross-check against $MFT.

Chain of custody

If you need a reference for a report: USN Parser version is identifiable from the deployed commit hash at the bottom of the GitHub repository. The wasm artefact is reproducible from source via wasm-pack build --release; the hash of the .wasm is stable per source revision.