In this module

MFT Record Structure at the Binary Level

14 hours · Module 1 · Free
Operational Objective
When MFTECmd outputs a CSV with columns for filename, timestamps, size, and parent path, the examiner sees structured data. What the examiner does not see is the 1,024-byte binary record that produced those columns — the record header with its signature and sequence number, the fixup array that ensures data integrity across disk sectors, the attribute chain that links $STANDARD_INFORMATION to $FILE_NAME to $DATA, and the flags that determine whether the record represents an active file, a deleted file, or a directory. Without understanding this binary structure, the examiner cannot verify whether the parser read the record correctly, cannot detect edge cases where the parser makes assumptions that don't hold, and cannot recover data from damaged or partially overwritten records that the parser skips entirely. This subsection teaches the MFT record structure byte by byte — every field, every offset, every flag — so that when you open a hex editor and navigate to offset 0x400 in an MFT extract, you can read the record as fluently as you read the CSV output.
Deliverable: Ability to read a raw MFT record in a hex editor, identify the record header fields (signature, fixup offset, fixup count, sequence number, hard link count, first attribute offset, flags, used size, allocated size), apply the fixup array to validate record integrity, and walk the attribute chain by following attribute type and length fields from the first attribute to the end marker.
Estimated completion: 45 minutes
MFT RECORD STRUCTURE — 1,024 BYTES RECORD HEADER (offsets 0x00–0x37) 0x00: "FILE" signature (4B) | 0x04: Fixup offset (2B) | 0x06: Fixup count (2B) | 0x08: $LogFile LSN (8B) | 0x10: Sequence # (2B) | 0x12: Hard link count (2B) 0x14: First attribute 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) — ensures record integrity 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 directory MFT reference, $FN timestamps (4) Filename (Unicode), namespace (Win32/DOS/POSIX) ATTRIBUTE 3: $DATA (0x80) Type: 0x80 | Resident if file < ~700 bytes Resident: actual file data stored in MFT record Non-resident: data run list (cluster pointers) ADDITIONAL ATTRIBUTES $INDEX_ROOT (0x90) — directory B-tree root $INDEX_ALLOCATION (0xA0) — directory B-tree nodes $BITMAP (0xB0) — index allocation bitmap END MARKER: 0xFFFFFFFF (4 bytes) — signals end of attribute chain Each attribute is self-describing: Type (4B) → Length (4B) → Content. Walk the chain by adding Length to current offset until you hit 0xFFFFFFFF.

Figure WF1.1 — MFT record layout showing the 56-byte header, fixup array, and attribute chain. Each attribute is self-describing with a type code and length, allowing the examiner to walk the chain from the first attribute offset to the end marker. Attributes appear in type-number order but this is convention, not a guarantee — parsers that assume ordering can produce incorrect output.

The 1,024-byte record

Every file and directory on an NTFS volume occupies at least one record in the Master File Table. The record size is fixed at 1,024 bytes on all standard NTFS implementations — this has been consistent since Windows NT 3.1 and remains unchanged through Windows 11 23H2. The size is defined in the NTFS boot sector at offset 0x40 (the "clusters per MFT record" field), and while the NTFS specification technically permits other sizes, no production Windows installation uses anything other than 1,024 bytes.

The fixed size has a critical forensic implication: you can calculate the exact byte offset of any MFT record by multiplying the MFT entry number by 1,024. Entry 0 starts at byte 0 of the MFT. Entry 1 starts at byte 1,024. Entry 38,271 starts at byte 39,189,504. When an examiner needs to locate a specific MFT record in a hex editor — to verify tool output, to examine a record the parser skipped, or to recover data from a damaged record — they calculate the offset and navigate directly to it. No searching required.

The record is divided into three regions: the record header (the first 56 bytes at minimum, typically 0x38 bytes), the fixup array (immediately following the header, size determined by the fixup count field), and the attribute area (from the first attribute offset to the end marker at 0xFFFFFFFF, occupying the remainder of the record). The record header contains metadata about the record itself — its signature, integrity verification data, allocation status, and pointers to the attribute chain. The attributes contain metadata about the file the record represents — its name, timestamps, data content, and security information.

Record header field by field

The record header begins at offset 0x00 of every MFT record. The first four bytes are the ASCII signature "FILE" (hex values 46 49 4C 45). This signature identifies the record as a valid MFT entry. When you scan a raw disk image looking for MFT records, you search for this four-byte signature at 1,024-byte intervals. A record with a corrupted or missing "FILE" signature has been 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 the record is damaged.

Offset 0x04 contains the fixup array offset — a two-byte value indicating where the fixup array begins within the record header, measured from the start of the record. On a standard Windows NTFS implementation, this value is typically 0x30 (48 decimal), meaning the fixup array begins at byte 48 of the record. Offset 0x06 contains the fixup entry count — a two-byte value indicating how many entries are in the fixup array. For a 1,024-byte record with 512-byte sectors, this value is 3 (one signature value plus two replacement values, one per sector boundary).

Offset 0x08 contains the $LogFile sequence number (LSN) — an eight-byte value that links this record to the most recent transaction in the NTFS transaction log ($LogFile). The LSN is updated every time the record is modified. Forensically, the LSN provides a relative ordering of modifications — records with higher LSNs were modified more recently than records with lower LSNs. The absolute time of the modification comes from the timestamps in the record's attributes, but the LSN provides the sequence when timestamps are identical (within the same 100-nanosecond tick) or when timestamps have been manipulated through timestomping.

Offset 0x10 contains the sequence number — a two-byte value that increments every time the MFT record is allocated or deallocated. When a file is created and assigned MFT entry 1,234, the sequence number starts at 1. When that file is deleted, the sequence number increments to 2. When a new file is created and reuses entry 1,234, the sequence number increments to 3. The sequence number provides a forensic indicator of how many times a particular MFT entry has been recycled. An entry with sequence number 1 has only ever held one file. An entry with sequence number 7 has been allocated, freed, and reallocated multiple times. The MFT entry number combined with the sequence number forms a unique file reference — this combination ensures that a reference to "MFT entry 1,234, sequence 3" cannot be confused with the previous file that occupied entry 1,234 at sequence 1.

Offset 0x12 contains the hard link count — a two-byte value indicating how many directory entries point to this MFT record. For a normal file with one name in one directory, this value is 1. For a file with a hard link (a second name in the same or a different directory), this value is 2 or higher. Hard links share the same MFT record and therefore the same $DATA attribute — they are different names for the same data. The hard link count is forensically relevant because it indicates whether a file has additional names that may not be immediately visible in a directory listing.

Offset 0x14 contains the first attribute offset — a two-byte value indicating the byte offset (from the start of the record) where the first attribute begins. This is the entry point to the attribute chain. On a standard record with a fixup array of 3 entries (6 bytes total) beginning at offset 0x30, the first attribute offset is typically 0x38 (56 decimal). The examiner uses this value to locate the first attribute in the record.

Offset 0x16 contains the record flags — a two-byte value where individual bits indicate the record's status. Bit 0 (value 0x01) indicates the record is in use (allocated). Bit 1 (value 0x02) indicates the record is a directory (as opposed to a file). A value of 0x01 means the record is an active file. A value of 0x03 (0x01 | 0x02) means the record is an active directory. A value of 0x00 means the record has been deleted — the entry is available for reuse, but the metadata from the previous file may still be intact. This flag is the first thing to check when examining a specific MFT record: is the record still allocated, or has the file been deleted?

Offset 0x18 contains the used size — a four-byte value indicating how many bytes of the 1,024-byte record are actually used. This value is always less than or equal to 1,024. The difference between the used size and 1,024 is slack space within the MFT record — bytes that are allocated to the record but not currently used by any attribute. MFT slack can contain remnants of previous attributes that were removed or resized, which may contain forensically relevant data from a previous file that occupied the record.

Offset 0x1C contains the allocated size — a four-byte value that for a standard MFT record is always 0x400 (1,024 decimal). Offset 0x20 contains the base record reference — an eight-byte value that points to the base MFT record when this record is an extension record (used when a file has more attributes than fit in a single 1,024-byte record). For the base record itself, this value is 0. Offset 0x28 contains the next attribute ID — a two-byte value used to assign unique IDs to new attributes added to the record.

Compliance Myth: "MFT records are always 1,024 bytes — that's part of the NTFS specification"
The NTFS specification does not mandate 1,024-byte MFT records. The record size is defined in the boot sector and is technically configurable. However, every production Windows installation since NT 3.1 uses 1,024-byte records, and the NTFS driver in modern Windows will not mount a volume with a non-standard MFT record size created by third-party tools. For practical forensic purposes, MFT records are always 1,024 bytes on evidence you will encounter. But for court testimony, state it as "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 that opposing counsel could challenge with the NTFS specification.

The fixup array — integrity verification

The fixup array is an NTFS mechanism for detecting sector-level corruption. The concept: NTFS writes a signature value to the last two bytes of each 512-byte sector within the record, then stores the original values of those bytes in the fixup array. When reading the record back, NTFS verifies that the signature value is present at each sector boundary. If the signature matches, the original bytes are restored. If the signature doesn't match, the sector has been corrupted or overwritten outside of NTFS control.

For a 1,024-byte MFT record with 512-byte sectors, the record spans two sectors. The fixup array contains three entries: the signature value (2 bytes) and two replacement pairs (2 bytes each, one for each sector). The array occupies 6 bytes total. The fixup array is located at the offset specified in the header (typically 0x30) and its size is determined by the fixup count field (typically 3 entries).

When NTFS writes the MFT record to disk, it copies the last two bytes of sector 1 (bytes at offset 0x1FE–0x1FF) and the last two bytes of sector 2 (bytes at offset 0x3FE–0x3FF) into the fixup array. It then overwrites those locations with the signature value. When NTFS reads the record from disk, it verifies the signature value at offsets 0x1FE and 0x3FE, then restores the original bytes from the fixup array.

For the forensic examiner working with raw MFT data, the fixup array is critical. If you extract MFT records using a tool that applies fixup corrections (MFTECmd does this automatically), the output already has the original bytes restored. If you extract MFT records using a raw disk tool or hex editor, the fixup values are still in place at the sector boundaries, and you must apply the fixup correction manually before interpreting the data at those offsets. Failing to apply the fixup correction means the bytes at offsets 0x1FE–0x1FF and 0x3FE–0x3FF contain the signature value, not the actual attribute data. If an attribute header or timestamp happens to span a sector boundary, reading the raw data without fixup correction produces garbage values.

The fixup array also serves as a corruption detector. If you open a raw MFT record in a hex editor and the values at offsets 0x1FE and 0x3FE do not match the signature value at the beginning of the fixup array, the record has been modified outside of NTFS — by disk corruption, by a forensic tool that wrote to the evidence (a catastrophic chain of custody violation), or by intentional anti-forensic manipulation. This mismatch is itself a forensic finding.

Walking the attribute chain

Every MFT record contains a chain of attributes that describe the file the record represents. The chain begins at the first attribute offset (read from the record header at offset 0x14) and continues until the end marker 0xFFFFFFFF is encountered. Each attribute is self-describing: it begins with a common header that specifies the attribute type (4 bytes) and the total length of the attribute including the header (4 bytes). To walk the chain, the examiner reads the type and length of the current attribute, then advances the offset by the length to reach the next attribute.

The attribute header has a fixed structure regardless of attribute type. Offset 0x00 (relative to the attribute start) contains the attribute type code — a four-byte value that identifies what kind of attribute this is. The forensically relevant type codes are 0x10 ($STANDARD_INFORMATION), 0x30 ($FILE_NAME), 0x40 ($OBJECT_ID), 0x50 ($SECURITY_DESCRIPTOR), 0x60 ($VOLUME_NAME), 0x70 ($VOLUME_INFORMATION), 0x80 ($DATA), 0x90 ($INDEX_ROOT), 0xA0 ($INDEX_ALLOCATION), and 0xB0 ($BITMAP). Offset 0x04 contains the attribute length in bytes — a four-byte value that includes the header. Offset 0x08 contains the non-resident flag — a one-byte value where 0 means the attribute data is stored within the MFT record (resident) and 1 means the data is stored in clusters on disk (non-resident).

For resident attributes, the data immediately follows the attribute header within the MFT record. For non-resident attributes, the header contains a data run list — a compact encoding of the cluster numbers and lengths where the data is stored on disk. The distinction between resident and non-resident is critical for forensic recovery: resident data exists entirely within the MFT record and can be recovered even if the file is deleted (as long as the MFT entry has not been reallocated). Non-resident data depends on the clusters not having been overwritten.

The attribute chain typically appears in type-number order (0x10 first, then 0x30, then 0x80, and so on), but this is convention, not a guarantee enforced by NTFS. A parser that assumes attributes appear in order and stops searching after finding the expected type will miss attributes that appear out of order — which can occur after disk repair operations, certain backup-restore sequences, or when NTFS reorganizes the record internally. The correct approach is to walk the entire chain from start to end marker, examining every attribute regardless of type code.

Decision point

You are examining an MFT record for a file that is central to your investigation. MFTECmd reports the filename, timestamps, and file size, but the "Parent Path" column shows an unexpected directory — the file appears to be in a system directory where you wouldn't expect to find it. You need to determine whether the file was actually in that directory or whether the parser made an error.

Your options: (A) Accept the MFTECmd output and note the unusual directory in your report. (B) Open the raw MFT record in a hex editor, locate the $FILE_NAME attribute, and manually verify the parent directory reference by checking the MFT entry and sequence number it points to. (C) Re-run MFTECmd with different options to see if the output changes.

The correct approach is B. MFTECmd resolves parent directory references by looking up the MFT entry number stored in the $FILE_NAME attribute. If the parent directory's MFT entry has been reallocated to a different directory since the file was created — which happens when directories are deleted and the MFT entry is reused — the parser resolves to the current directory name, not the original directory name. By examining the raw $FILE_NAME attribute, you can read the parent MFT reference (entry number + sequence number) and verify whether the sequence number matches the current occupant of that MFT entry. If the sequence numbers don't match, the parent directory has been reallocated, and the parser's path resolution is incorrect. This is a real edge case that occurs in investigations involving deleted directory structures.

Practical hex reading — walking a real record

To make this concrete, consider an MFT record starting at offset 0x00 in a raw MFT extract. The first 8 bytes read: 46 49 4C 45 30 00 03 00. Breaking this down: bytes 0x00–0x03 are 46 49 4C 45 which is "FILE" in ASCII — the record signature is valid. Bytes 0x04–0x05 are 30 00 which is 0x0030 (48 decimal) in little-endian — the fixup array starts at byte 48 of the record. Bytes 0x06–0x07 are 03 00 which is 0x0003 (3 decimal) — the fixup array has 3 entries (1 signature + 2 sector replacements).

Continuing: bytes 0x10–0x11 read 05 00 — the sequence number is 5, meaning this MFT entry has been allocated and deallocated multiple times and is currently on its fifth use. Bytes 0x12–0x13 read 01 00 — the hard link count is 1, meaning one directory entry points to this file. Bytes 0x14–0x15 read 38 00 — the first attribute starts at offset 0x38 (56 decimal). Bytes 0x16–0x17 read 01 00 — the flags indicate the record is in use (0x01) and is a file (not a directory, because bit 1 is not set).

Navigating to offset 0x38, you reach the first attribute. The first four bytes read 10 00 00 00 — attribute type 0x00000010, which is $STANDARD_INFORMATION. The next four bytes read 60 00 00 00 — the attribute is 0x60 (96) bytes long including the header. To find the next attribute, add 0x60 to the current offset: 0x38 + 0x60 = 0x98. At offset 0x98, the first four bytes read 30 00 00 00 — attribute type 0x00000030, which is $FILE_NAME. The length field shows this attribute is 0x68 (104) bytes. The next attribute is at 0x98 + 0x68 = 0x100. This process continues until you encounter FF FF FF FF — the end marker.

This is the fundamental skill of MFT analysis. 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.

Try it: Walk an MFT record header

Open HxD (free hex editor) and load any raw MFT file extracted with KAPE or FTK Imager. Navigate to offset 0x000 (the first MFT record — the $MFT file itself).

1. Confirm the signature at offset 0x00 reads 46 49 4C 45 ("FILE"). 2. Read the fixup offset at 0x04 (two bytes, little-endian). It should read 30 00 = 0x0030. 3. Read the fixup count at 0x06 (two bytes, little-endian). It should read 03 00 = 3. 4. Read the sequence number at 0x10 (two bytes). For the $MFT file itself, this is typically 1. 5. Read the flags at 0x16 (two bytes). For the $MFT file, this should be 01 00 (in use, file). 6. Read the first attribute offset at 0x14 (two bytes). Navigate to that offset. 7. Read the attribute type at that offset (four bytes). It should be 10 00 00 00 ($STANDARD_INFORMATION). 8. Read the attribute length (next four bytes). Add the length to your current offset to find the next attribute. 9. Continue until you reach FF FF FF FF — the end marker.

Count how many attributes the $MFT file's first record contains. Compare with MFTECmd's output for MFT entry 0. Every attribute type you found in hex should correspond to a column or detail in the parser's output.

Flags and allocation status

The record flags at offset 0x16 are the fastest way to determine a record's forensic status. The two bits that matter are bit 0 (in-use) and bit 1 (directory). The four possible combinations are:

0x00 — the record is not in use and represents a file. This is a deleted file. The MFT entry is available for reuse, but the metadata from the deleted file may still be intact. The timestamps, filename, and potentially the data content (if resident) can be recovered from this record.

0x01 — the record is in use and represents a file. This is an active file. All attributes are current and reflect the file's present state.

0x02 — the record is not in use and represents a directory. This is a deleted directory. The directory's name and timestamps can be recovered, but the directory's contents (which were tracked in $INDEX_ROOT and $INDEX_ALLOCATION attributes) may have been partially overwritten.

0x03 — the record is in use and represents a directory. This is an 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. The record's used size field (offset 0x18) and the actual content of the attribute area provide the answer. If the attributes parse correctly and the end marker is intact, the record is recoverable. If the attribute chain is broken (an attribute length field points past the end of the record, or the type codes are invalid), the record has been partially overwritten and only the intact portions can be trusted.

You are examining a raw MFT record. The header shows a sequence number of 12, flags of 0x00, and a used size of 456 bytes. MFTECmd did not include this record in its output. What is the forensic significance of this record?
The record is corrupted and cannot be analyzed — the sequence number of 12 indicates excessive reuse that has degraded the data.
The record is a deleted file (flags 0x00) that has been allocated and freed multiple times (sequence 12). The 456 bytes of used content may contain recoverable metadata from the last file that occupied this entry — including filename, timestamps, and potentially resident file data. MFTECmd likely skipped it because it's marked as free, but the metadata is forensically valuable and should be examined manually.
The record belongs to the MFT itself (entry 12) and should not be analyzed as a normal file record.
The record has been wiped by a secure deletion tool — the flags of 0x00 and high sequence number indicate intentional evidence destruction.

MFT entry numbers and the reserved entries

The MFT is an array of records indexed by entry number. Entry 0 is the $MFT file itself — the file that contains the Master File Table. Entry 1 is $MFTMirr — a backup of the first four MFT entries stored in a different location on the volume. Entry 2 is $LogFile — the NTFS transaction log. Entry 3 is $Volume — volume metadata. Entries 4 through 15 are reserved for other NTFS metadata files ($AttrDef, the root directory, $Bitmap, $Boot, $BadClus, $Secure, $UpCase, $Extend). Entries 16 through 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 the MFT from the beginning looking for a free entry (one with the in-use flag cleared). When it finds a free entry, it increments the sequence number and allocates the entry for the new file. This means the MFT grows as more files are created, but entries freed by deleted files are reused before the MFT expands. On a volume that has undergone significant file creation and deletion over time, the MFT may contain thousands of deleted file records interspersed with active records — each one a potential forensic artifact.

Understanding the reserved entries matters because MFT entry 5 is the root directory (the "C:\" directory itself), and its $INDEX_ROOT and $INDEX_ALLOCATION attributes define the top-level directory structure. MFT entry 2 ($LogFile) contains transaction records that can be used to recover operations that have been lost from the MFT proper. MFT entry 6 ($Bitmap) tracks which clusters on the volume are allocated — critical for identifying whether a deleted file's data clusters have been overwritten.

You've built the foundations of artifact-level forensic analysis.

WF0 gave you the taxonomy, NTFS architecture, and the five-step methodology. WF1 took you inside the MFT at the binary level — every attribute, every timestamp, every edge case. From here, every artifact category gets the same raw-first treatment.

  • WF2–WF10: every major Windows artifact decoded at binary level — USN Journal, Prefetch, Amcache, Shimcache, ShellBags, LNK, Jump Lists, SRUM, Event Logs, and the Registry hives
  • INC-NE-2026-0915 (WF13) — Insider data exfiltration capstone. Work the complete investigation from USB history to OneDrive exfiltration evidence
  • INC-NE-2026-1022 (WF14) — Ransomware capstone. Three-host triage (FIN01 → IT03 → FS01) across the 72-hour attack chain
  • The lab pack — 25+ realistic evidence files in 10 formats, simulated KAPE triage pre-populated, both capstones deployable to your own VM
  • Anti-forensic detection methodology — defeat timestomping, log clearing, and Prefetch deletion with cross-artifact correlation
Unlock with Specialist — £25/mo See Full Syllabus

Cancel anytime