ReFS Reference

Common Metadata Page Header

Every ReFS metadata page – SUPB, CHKP, and MSB+ (B+-tree) – begins with a common 80-byte header. This layout is identical across every version (v3.4 through v3.14 and Insider) and configuration studied. MLog pages use the same "MLog" signature at offset 0x00 but have a different header layout (see MLog).

Field Layout (80 bytes)

OffsetSizeFieldDescription
0x004Signature (ASCII)Page type: "SUPB", "CHKP", "MSB+", or "MLog"
0x044Page header version (u32)Always 0x00000002
0x084Reserved (u32)Always 0
0x0C4Volume signature (u32)XOR of four 32-bit words of the Volume GUID (SUPB+0x50)
0x108Virtual allocator clock (u64)0 for SUPB (immutable); increments for CHKP/MSB+
0x188Tree update clock (u64)Last modification clock for this page’s table
0x208LCN slot 0 – self-block (u64)Primary cluster LCN of this page
0x288LCN slot 1 (u64)MSB+ only: second cluster (self+1)
0x308LCN slot 2 (u64)MSB+ only: third cluster (self+2)
0x388LCN slot 3 (u64)MSB+ only: fourth cluster (self+3)
0x408Table OID – high half (TableIdHigh) (u64)MSB+ only: high 8 bytes of the 16-byte owning-table OID. Always 0 in practice (table OIDs are small ints). 0 for SUPB/CHKP
0x488Table OID – low half (TableIdLow) (u64)MSB+ only: the numeric table OID the driver uses – the well-known TableIds are Object ID Table = 0x02, Block Refcount = 0x05, other system tables 0x01–0x22, user objects >=0x500. 0 for SUPB/CHKP

The two 8-byte halves at 0x40 and 0x48 together form the 16-byte owning-table OID (high+low). The driver reads and compares only the low half at 0x48; the high half at 0x40 is the OID qualifier and is always 0 because table OIDs are small integers.

Page Signatures

SignatureStructureRole
SUPBSuperblockFixed-location volume anchor pointing to checkpoints
CHKPCheckpointAtomic commit point holding the 13 root pointers
MSB+Minstore B+-tree pageA node of any B+-tree – global table or per-object
MLogMetadata logWrite-ahead transaction log (different header layout)

Key Fields Explained

Volume Signature (0x0C)

Enables fast corruption detection: if a page’s volume signature does not match the expected value (derived from SUPB Volume GUID), the page does not belong to this volume.

LCN Quadruple (0x20 - 0x38)

The page’s self-descriptor: four 8-byte values recording the page’s own logical cluster number. The driver confirms that a page read from a given location actually belongs there – a misdirected or stale read is caught when the self-descriptor disagrees with the fetch address.

For SUPB/CHKP, only slot 0 is meaningful. For MSB+ pages, all four slots may be used (a page spans up to 4 clusters on 4 KiB cluster volumes).

Table Identifier (0x40 - 0x48)

MSB+ pages only. The 16-byte owning-table OID spans 0x40-0x4F: the high half (0x40) is TableIdHigh and is always 0 in practice (OIDs are small integers); the low half (0x48) is TableIdLow = the numeric table OID the driver actually reads and compares (FormatPageHeaderInternal writes it from the well-known-object id whose high half is 0). This has direct forensic value: a CoW-discarded page keeps its table identifier, so an OID (read at 0x48) found in a page no longer referenced by the current Object Table flags it as a stale or deleted structure.

Forensic Use

  • Signature scanning for MSB+ pages across a disk image recovers historical file-system states (old CoW-discarded pages)
  • The volume signature provides a quick check to confirm a page belongs to the volume under analysis
  • The table identifier on orphaned MSB+ pages reveals which table they belonged to

Cross-references

  • VBR – provides cluster size and other format parameters
  • Superblock (SUPB) – contains the Volume GUID used to derive the volume signature
  • Checkpoint (CHKP) – uses this header with "CHKP" signature
  • Page References – encode checksums of child pages, chaining into a Merkle tree

Evidence

The four page signatures appear as binary string literals; the full field layout is corroborated in the decompiled driver – FormatPageHeaderInternal writes the OID high/low halves at page+0x40/0x48 – and re-measured on disk across the corpus. The Table OID semantics (high half always 0, low half = numeric table OID with Object ID Table = 0x02 and Block Refcount = 0x05) were confirmed by an all-disk re-measure showing page+0x40 == 0 on every MSB+ page plus SUPB/CHKP. The two halves together form the 16-byte high+low identifier.