In this section

MFT Record Structure, Allocation, and Sequence Numbers

14 hours · Module 1 · Free
What you already know
Module 0 introduced the MFT as the single most important forensic artifact and showed the record header in a hex dump. This section goes to the binary level: every field, every offset, every flag. You will also learn how NTFS allocates and reuses entries, and why the sequence number is critical for verifying file references.

Scenario

MFTECmd reports a file's "Parent Path" as C:\Windows\System32, but the file is an attacker tool that shouldn't be in a system directory. Is the file actually there, or did the parser resolve the parent directory reference incorrectly? The only way to answer this is to open the raw MFT record, locate the $FILE_NAME attribute, read the parent MFT reference (entry number + sequence number), and verify whether the sequence number matches the current occupant of that entry. If the parent directory was deleted and the MFT entry reused, the parser resolved to the wrong directory.

The 1,024-byte MFT record

MFT RECORD STRUCTURE — 1,024 BYTES RECORD HEADER (offsets 0x00-0x37) 0x00: "FILE" sig (4B) | 0x04: Fixup offset (2B) | 0x06: Fixup count (2B) | 0x08: $LogFile LSN (8B) | 0x10: Sequence # (2B) | 0x12: Hard link count (2B) 0x14: First attr offset (2B) | 0x16: Flags (2B) | 0x18: Used size (4B) | 0x1C: Allocated size (4B) | 0x20: Base record ref (8B) | 0x28: Next attr ID (2B) FIXUP ARRAY (offsets 0x30-0x37 typical) Signature value (2B) + replacement pairs (2B each) — integrity verification across 512-byte sector boundaries ATTRIBUTE 1: $STANDARD_INFORMATION (0x10) Type: 0x10 | Length: variable | Resident: always Created, Modified, Accessed, Entry Modified timestamps File permissions, owner ID, security ID, quota, USN ATTRIBUTE 2: $FILE_NAME (0x30) Type: 0x30 | Length: variable | Resident: always Parent dir MFT ref, filename, namespace flag Own MACE timestamps (NTFS-driver set) ATTRIBUTE 3: $DATA (0x80) Resident: file content in MFT record (<~700 bytes) Non-resident: data run list mapping disk clusters ATTRIBUTE N: ... (variable) Additional attrs: $INDEX, $SECURITY, $OBJECT_ID Chain continues until end marker 0xFFFFFFFF END MARKER: 0xFFFFFFFF | REMAINING BYTES: MFT SLACK (may contain remnants of previous file) Record offset = entry number x 1,024. Entry 38,271 starts at byte 39,189,504. Navigate directly in hex editor — no searching required.

Figure WF1.1 — MFT record structure. The header identifies the record, the fixup array verifies integrity, the attribute chain contains the file's metadata, and slack space may contain remnants of previous files.

Every MFT record is exactly 1,024 bytes. This fixed size means you can calculate the byte offset of any record by multiplying the entry number by 1,024. Entry 38,271 starts at byte 39,189,504. When you need to verify tool output in a hex editor, you calculate the offset and navigate directly.

The record divides into three regions: the record header (first 56 bytes), the fixup array (immediately following), and the attribute area (from the first attribute offset to the end marker at 0xFFFFFFFF). The header contains metadata about the record itself. The attributes contain metadata about the file.

Record header field by field

MFT Record Header — Annotated Hex Dump
Offset   Hex                                        Decoded
0x0000   46 49 4C 45 30 00 03 00  C8 A4 0B 00 00 00 00 00   "FILE" signature | Fixup@0x30 | 3 entries | LSN
0x0010   05 00 01 00 38 00 01 00  A0 01 00 00 00 04 00 00   Seq=5 | Links=1 | 1stAttr@0x38 | Flags=0x01 (in use)
0x0020   00 00 00 00 00 00 00 00  06 00 00 00 00 00 00 00   Base record=0 (this is the base) | NextAttrID=6
── Fixup Array ──
0x0030   A3 02 00 00 00 00 00 00                            Signature=0x02A3 (verify at 0x1FE and 0x3FE)
── First Attribute ──
0x0038   10 00 00 00 60 00 00 00  00 00 00 00 00 00 00 00   Type=$SI (0x10) | Length=96 bytes | Resident
         Next attribute at 0x38 + 0x60 = 0x98

The signature at 0x00 (FILE) identifies a valid record. If you scan a raw disk image looking for MFT records, you search for this four-byte sequence at 1,024-byte intervals. A missing or corrupted signature — or the string "BAAD" instead of "FILE" — indicates the record is damaged, either by disk corruption, partial overwrite, or intentional destruction. The signature's presence does not guarantee the record is intact, but its absence confirms damage.

The $LogFile LSN at 0x08 (8 bytes) links this record to the most recent transaction in the NTFS transaction log ($LogFile). The LSN updates every time the record is modified. Records with higher LSNs were modified more recently. When timestamps are identical or manipulated, the LSN provides a relative ordering of modifications.

The sequence number at 0x10 (value 5 in this example) is a 16-bit counter that increments every time the MFT entry is allocated or deallocated. When a file is created and assigned this entry, the sequence starts at 1. When deleted, it increments to 2. When reused for a new file, it increments to 3. A sequence of 5 means this entry has been through multiple allocation cycles. The entry number combined with the sequence number forms a unique file reference — "MFT entry 48,271 sequence 5" cannot be confused with the previous file at "entry 48,271 sequence 3." This distinction matters because parent directory references, USN Journal records, and $LogFile entries all use the full file reference (entry + sequence) to identify files.

The hard link count at 0x12 (2 bytes) indicates how many directory entries point to this record. A value of 1 means one name in one directory. A value of 2 or higher means the file has hard links — multiple names for the same data, each with its own $FILE_NAME attribute.

The first attribute offset at 0x14 (0x38 = 56 decimal) is the entry point to the attribute chain. Navigate to that offset to find the first attribute. The attribute type code (0x10 = $STANDARD_INFORMATION) and length (0x60 = 96 bytes) let you walk to the next attribute by adding the length to the current offset: 0x38 + 0x60 = 0x98.

The flags at 0x16 tell you the record's status: 0x01 = active file, 0x03 = active directory, 0x00 = deleted file, 0x02 = deleted directory. This is the first field to check when examining a specific record. The used size at 0x18 tells you how many bytes of the 1,024-byte record are actually used. The difference between used size and 1,024 is MFT slack — bytes that may contain remnants of previous attributes from an earlier file that occupied this entry.

Anti-Pattern

Assuming MFT records are always 1,024 bytes because "that's the spec"

The NTFS specification does not mandate 1,024-byte records. The record size is defined in the boot sector and is technically configurable. Every production Windows installation since NT 3.1 uses 1,024 bytes, and the current NTFS driver won't mount volumes with non-standard sizes. For court testimony, state "the MFT record size for this volume is 1,024 bytes as defined in the boot sector" rather than "MFT records are always 1,024 bytes." The former is a verifiable fact about the specific evidence; the latter is an assumption opposing counsel can challenge.

The fixup array — integrity verification

The fixup array detects sector-level corruption. NTFS writes a signature value to the last two bytes of each 512-byte sector within the record, then stores the original values in the fixup array. On read, NTFS verifies the signature and restores the original bytes. For a 1,024-byte record spanning two sectors, the fixup array has three entries: one signature plus two replacement values.

When working with raw MFT data, the fixup matters. If you extract using a tool that applies fixup corrections (MFTECmd does this automatically), the output has original bytes restored. If you extract using a raw disk tool or hex editor, the fixup values are still at the sector boundaries (offsets 0x1FE-0x1FF and 0x3FE-0x3FF), and you must apply the correction manually before interpreting data at those offsets. Failing to apply fixup correction when an attribute header or timestamp spans a sector boundary produces garbage values.

A fixup mismatch (values at sector boundaries don't match the signature) is itself a forensic finding: the record was modified outside of NTFS, by disk corruption, a tool that wrote to the evidence, or intentional anti-forensic manipulation.

Walking the attribute chain

Every MFT record contains a chain of attributes beginning at the first attribute offset and continuing until the end marker 0xFFFFFFFF. Each attribute is self-describing: a common header specifies the type (4 bytes) and total length (4 bytes). To walk the chain, read the type and length of the current attribute, then advance the offset by the length to reach the next attribute.

Attribute Chain Walk
Offset   Type         Length   Next offset        Attribute
0x0038   10 00 00 00  60 00    0x38 + 0x60 = 0x98  $STANDARD_INFORMATION  ◄ Timestamps, permissions
0x0098   30 00 00 00  68 00    0x98 + 0x68 = 0x100  $FILE_NAME (long)       ◄ Filename, parent ref, $FN timestamps
0x0100   30 00 00 00  60 00    0x100 + 0x60 = 0x160 $FILE_NAME (8.3)       ◄ Short name (if exists)
0x0160   80 00 00 00  48 00    0x160 + 0x48 = 0x1A8 $DATA                 ◄ File content or data runs
0x01A8   FF FF FF FF                                   END MARKER              ◄ Stop walking

The attribute header also contains the non-resident flag at offset 0x08: 0 means the data is stored within the MFT record (resident), 1 means the data is on disk clusters (non-resident). Resident data can be recovered even from deleted files as long as the MFT entry hasn't been reallocated. Non-resident data depends on the clusters not having been overwritten.

The forensically relevant attribute type codes are: 0x10 ($STANDARD_INFORMATION — timestamps, permissions, USN), 0x30 ($FILE_NAME — filename, parent reference, second timestamp set), 0x40 ($OBJECT_ID — unique file identifier), 0x50 ($SECURITY_DESCRIPTOR — ACLs, ownership), 0x80 ($DATA — file content or cluster pointers), 0x90 ($INDEX_ROOT — directory B-tree root), 0xA0 ($INDEX_ALLOCATION — directory B-tree nodes), and 0xB0 ($BITMAP — cluster allocation tracking for indexes).

The chain typically appears in type-number order (0x10, then 0x30, then 0x80), but this is convention, not a guarantee enforced by NTFS. After disk repair, backup-restore, or internal reorganization, attributes can appear out of order. A parser that assumes ordering and stops searching after the expected type will miss out-of-order attributes. The correct approach is to walk the entire chain from start to end marker, examining every attribute regardless of type code. This is also how you find Alternate Data Streams — additional $DATA attributes (type 0x80) with names, which appear as separate entries in the chain after the primary unnamed $DATA attribute.

Flags and allocation status

The flags at offset 0x16 are the fastest way to determine a record's forensic status:

0x00 — deleted file. The entry is available for reuse, but the metadata from the deleted file persists in the record. The timestamps, filename, and file content (if resident) can all be recoverable. This is the most common state for forensically interesting deleted files.

0x01 — active file. All attributes are current and reflect the file's present state.

0x02 — deleted directory. The directory's name and timestamps can be recovered, but the directory's contents (tracked in $INDEX_ROOT and $INDEX_ALLOCATION attributes) may be partially overwritten by B-tree reorganization.

0x03 — active directory.

When examining deleted records (flags 0x00 or 0x02), the key forensic question is whether the record has been partially overwritten by a subsequent allocation. Check the attribute chain: if attributes parse correctly (valid type codes, length fields that don't point past the record boundary) and the end marker (0xFFFFFFFF) is intact, the record is fully recoverable. If the chain is broken, the record was partially overwritten. Only the intact portion before the break can be trusted. MFTECmd flags these partial records in its output, but for critical evidence, verify the chain integrity in hex.

Investigation Principle

Once you can walk the attribute chain in hex, you can verify any parser's output, recover data from records the parser skipped, and detect anomalies that automated tools miss. This is the fundamental skill of MFT analysis. The record header, the fixup array, and the attribute chain are the same structure on every NTFS volume from Windows NT 3.1 through Windows 11.

MFT entry numbers and reserved entries

Entries 0-23 are reserved for NTFS metadata files. Entry 0 is the $MFT itself — the file that contains the Master File Table. Entry 1 is $MFTMirr — a backup copy of the first four MFT entries stored in a different location on the volume. If the primary MFT is damaged, NTFS uses $MFTMirr to recover the critical first entries. Entry 2 is $LogFile — the NTFS transaction log that records metadata changes for crash recovery and forensic analysis. Entry 3 is $Volume — volume metadata including the volume label and NTFS version.

Entry 5 is the root directory ("C:\" itself). Its $INDEX_ROOT and $INDEX_ALLOCATION attributes define the top-level directory structure. Entry 6 is $Bitmap — tracks which clusters on the volume are allocated versus free. This is critical for determining whether a deleted file's data clusters have been overwritten. Entries 4 and 7-15 contain other NTFS metadata ($AttrDef, $Boot, $BadClus, $Secure, $UpCase, $Extend). Entries 16-23 are reserved but typically unused on modern Windows.

Entry 24 is the first entry available for user files and directories. When a new file is created, NTFS scans from the beginning of the MFT for a free entry. Free entries from deleted files are reused before the MFT expands. On a volume with significant file churn over time, the MFT contains thousands of deleted file records interspersed with active records, each a potential forensic artifact. The forensic examiner should know these reserved entries by number because they appear constantly in cross-references — a parent directory reference pointing to entry 5 means the file is in the root directory, and an $ATTRIBUTE_LIST referencing entry 0 means the attribute belongs to the $MFT file itself.

MFT Record Header Field Reference

0x00 (4B): Signature "FILE" — identifies valid record. Absent = damaged.

0x04 (2B): Fixup array offset — typically 0x30.

0x08 (8B): $LogFile LSN — links to transaction log. Higher = more recent modification.

0x10 (2B): Sequence number — increments on each alloc/dealloc. Reuse counter.

0x14 (2B): First attribute offset — entry point to attribute chain. Typically 0x38.

0x16 (2B): Flags — 0x01=file, 0x02=directory, 0x00=deleted file, 0x03=active directory.

0x18 (4B): Used size — bytes used in this record. 1024 minus used size = MFT slack.

Scenario

A $FILE_NAME attribute references parent directory MFT entry 500, sequence 3. You look up entry 500 and find it currently has sequence 5 and contains a completely different directory. The parent directory that your file belonged to was deleted and the MFT entry was reused twice since then. MFTECmd resolved the path using the current directory name at entry 500 — not the original directory. The parser's "ParentPath" output is wrong. You can only detect this by checking the sequence number.

The allocation cycle

When a new file is created, NTFS scans the MFT for a free entry — one with the in-use flag cleared (flags = 0x00). NTFS begins scanning from the beginning of the MFT and uses the first free entry it finds. This allocation strategy means recently freed entries near the beginning are reallocated quickly, while entries deeper in the MFT may remain free for longer.

When NTFS allocates a free entry, it increments the sequence number, sets the in-use flag, and populates the record with the new file's attributes ($SI, $FN, $DATA), overwriting whatever the previous file left. From this point, the MFT entry belongs to the new file entirely. However, "overwriting" means the new attributes are written to the record — if the new file uses less space than the previous file (fewer attributes, shorter filename, no ADS), the unused portion of the record retains bytes from the previous file as MFT slack.

Recent research from Sygnia (April 2025) demonstrated an important behavioral difference between Windows versions for MFT slack. On older Windows systems (pre-Windows 10), when a resident file grows and transitions to non-resident storage, the old resident data persists in the MFT record slack after the $DATA attribute is converted to a non-resident data run list. On Windows 10 and later, NTFS zeros the slack area during this transition, eliminating the residual content. This means MFT slack analysis is more productive on older evidence but less reliable on modern systems for recovering data that was once resident.

When a file is deleted, NTFS clears the in-use flag and increments the sequence number. The record's attributes are not zeroed. The previous file's timestamps, filename, and resident data remain intact in the record. NTFS also updates the volume bitmap to free the file's clusters (for non-resident data) and removes the file's entry from the parent directory's index.

The forensic window between deletion and reallocation depends on file creation activity. On a busy system with constant temp file creation, the window may be minutes. On a stable workstation or file server with infrequent file creation, freed entries near the end of the MFT can remain unallocated for weeks or months. During this window, the deleted file's metadata is fully recoverable.

MFTECmd Output — Sequence Number Analysis
Entry   Seq  InUse  FileName                    ParentPath
48271   5    True   quarterly_report.docx       .\Users\d.chen\Documents       ◄ Current file (seq 5)
48271   3    False  svchost_update.exe          .\Windows\Temp                 ◄ Previous occupant (seq 3, deleted)
48271   1    False  tmpDB4F.tmp                 .\Users\d.chen\AppData\Local   ◄ Original occupant (seq 1, deleted)

MFT entry 48,271 has been used three times. The current file (sequence 5, in use) is a Word document. The previous occupant (sequence 3, freed) was the attacker tool svchost_update.exe. The original occupant (sequence 1) was a temporary file. The sequence number history reconstructs who used this MFT slot and when.

Anti-Pattern

Referencing files by MFT entry number alone

MFT entry numbers are reusable slots, not permanent identifiers. Entry 5,000 might be a Word document today and a malware executable next week. Always include the sequence number: "MFT entry 5,000 (sequence 3)" is unambiguous. "MFT entry 5,000" is ambiguous. Every file reference in your forensic report must include both the entry number and the sequence number.

Sequence number forensics

The sequence number provides three forensic uses.

Reuse frequency. A high sequence number (for example, 47) means the entry has been allocated and freed many times. High-reuse entries are typically near the beginning of the MFT, in a region that sees frequent file creation and deletion (temporary files, cache files, browser data). A low sequence number (1 or 2) means the entry has been used once or twice — either recently allocated for the first time as the MFT grew, or in a region that doesn't experience frequent churn.

The sequence number is a 16-bit unsigned integer with a range of 1-65,535 (NTFS skips 0 when incrementing). In practice, even heavily churned entries rarely exceed sequence numbers in the hundreds. An entry with a sequence number above 1,000 indicates an unusually high level of file creation and deletion at that MFT slot — possibly a temp directory, a browser cache location, or a directory used by an application that creates and destroys files frequently. This can help characterize the volume's usage pattern.

Stale reference detection. When an artifact references an MFT entry by entry number and sequence number — a parent directory reference in $FILE_NAME, a $LogFile transaction entry, a USN Journal record, or a $REPARSE_POINT target — you verify whether the reference is current by comparing the referenced sequence number against the current sequence of that MFT entry. If they match, the reference points to the file currently occupying the entry. If the referenced sequence is lower, the file has been deleted and the entry reused — the reference is stale.

This is how you detect parent path resolution errors in MFTECmd. The parser resolves parent directory references by looking up the MFT entry number in $FILE_NAME. If the parent directory's entry has been reallocated to a different directory since the file was created, MFTECmd resolves to the current directory name, not the original. The CyberCX research team documented this issue: when parent entries are reused, USN Journal tools mark the parent path as "UNKNOWN" because the sequence numbers don't match, but MFT parsers that only check the entry number without validating the sequence may silently resolve to the wrong path. Always verify sequence numbers on parent references for files that are central to your investigation.

Previous occupant evidence. When examining a freed MFT entry (flags 0x00), the attributes in the record belong to the file that most recently occupied the entry. On a reallocated entry (flags 0x01), the current file's attributes are present, but fragments of the previous file may persist in MFT slack — the unused bytes between the end marker (0xFFFFFFFF) and the end of the 1,024-byte record. MFT slack can contain remnants of previous attributes that were removed or resized, potentially including filenames and timestamps from earlier occupants.

MFT growth and the $MFT zone

The MFT itself is a file (MFT entry 0) stored on the volume. When all existing entries are in use and a new file is created, NTFS extends the MFT by allocating additional clusters and adding new entries. NTFS reserves approximately 12.5% of the volume for MFT growth — this is the MFT zone. The reserved space is not exclusively locked; regular files can use it when the rest of the volume is full. But under normal conditions, the zone provides room for the MFT to grow without fragmentation.

The MFT rarely shrinks. Once entries are added (even for files later deleted), the MFT retains them as freed entries. This is beneficial for forensics — the MFT preserves freed entries rather than destroying them. On a workstation in use for three years, the MFT may contain 400,000+ entries with 20,000-50,000 freed entries. Each freed entry is a potential artifact. MFTECmd's output includes all freed entries marked "not in use," and filtering for these is a standard first step in deleted file recovery.

The MFT can become fragmented over time as it grows beyond its initial zone allocation. A fragmented MFT is still fully functional. The MFT's own $DATA attribute contains data runs mapping its clusters, just like any other non-resident file. KAPE and FTK Imager handle MFT fragmentation transparently during extraction.

Recent research from Sygnia (April 2025) demonstrated an important behavioral difference between Windows versions for MFT slack space. On older Windows systems (pre-Windows 10), when a resident file grows and transitions to non-resident storage, the old resident data persists in the MFT record's slack area. On Windows 10 and later, NTFS zeros the slack area during this transition, eliminating residual content. This means MFT slack analysis is more productive on older evidence but less reliable on modern systems for recovering data that was once resident and then grew beyond the threshold.

Investigation Principle

To verify any file reference in the MFT, check three things: the entry number points to a valid MFT record, the sequence number matches the expected value, and the record flags confirm the expected allocation state. A mismatched sequence number means the referenced file is gone and the entry has been reused. This check catches parent path resolution errors and stale cross-references from the USN Journal and $LogFile.

Next
Section 1.2 examines the two timestamp attributes in detail: $STANDARD_INFORMATION (the user-modifiable timestamps) and $FILE_NAME (the kernel-controlled timestamps that form the forensic baseline for timestomping detection).
Unlock the Full Course See Full Course Agenda