在磁盘上写作 $MFT 的 Master File Table(主文件表),是 NTFS 用来追踪卷上每个文件和目录的索引。它是每个 NTFS 分区上第一个用户可见的文件,而卷上的其他每一个文件 —— 包括这张表本身 —— 都在其中至少拥有一条记录。读取 $MFT 正是取证工具回答以下问题的方式:Windows 已不再承认存在的文件,究竟在何时被创建、叫什么名字、内容是什么、最后由谁触碰过。
本指南是一份完整参考。涵盖了这张表是什么、记录的布局方式、一条记录能承载哪些属性、表头那一小组保留的系统文件、「Windows cannot recover the master file table」到底意味着什么,以及如何使用本站的解析器自己读取 $MFT。
什么是 Master File Table?
Master File Table 是一个名为 $MFT 的单一文件,位于每个 NTFS 卷起始附近的固定位置。NTFS —— New Technology File System —— 在 1993 年随 Windows NT 3.1 一同发布,取代 FAT 成为 Windows 的默认文件系统。与维护一张小型分配表、将文件名存放在目录条目里的 FAT 不同,NTFS 几乎把每个文件的全部元数据都塞进同一张结构化的表里:$MFT。
表中的每一行都是一条 记录,大小正好是 1024 字节。每条记录描述一个文件或一个目录。记录里保存文件的名称、时间戳、DOS 风格的标志位、其数据所在的磁盘簇列表、安全描述符,以及若干其他属性 —— 全部以一小袋带类型字段的形式编码。
这一设计带来两个重大影响:
- 所有元数据集中在一处。 一次对
$MFT的查找就足以枚举卷上的每个文件。取证和恢复工具都依赖这一点;杀毒扫描器与索引服务同样如此。 - 被删除的文件留下完好的元数据。 当 NTFS 删除一个文件时,只会清掉记录头里的一个比特位,并把文件的簇标记为空闲。记录的其余部分 —— 名称、时间戳,通常还包括数据 run —— 在该记录槽被重新使用之前都会保留原样。
缩写 MFT 代表 Master File Table。你会看到它被写作 MFT、$MFT 或 the MFT,指的都是同一种磁盘结构。
$MFT 在磁盘上的布局
当 NTFS 格式化一个卷时,会在分区开头附近预留一块称为 MFT zone 的区域。卷偏移 0 处的引导扇区包含一个指针(MftStartLcn 字段),指向 $MFT 的第一个簇。表的前 16 条记录被保留给 NTFS 的元数据文件(见下文);记录 0 是表自身的条目,回指其自身的簇。
每当需要更多记录时,$MFT 就会通过扩展到自己的预留区中而增长。如果在该预留区被耗尽之前卷就满了,Windows 会缩小这块区域以腾出空间给用户数据,这就是为什么在老旧的文件系统上,严重碎片化的 $MFT 是常见症状。
前几条记录的备份保存在另一个文件 $MFTMirr 中,通常被放置在卷的中部。如果 $MFT 本身被损坏,NTFS 会使用 $MFTMirr 来引导恢复 —— 这正是下文所述「Windows cannot recover the master file table」错误背后的机制。
FILE 记录的结构剖析
每条 MFT 记录都以四字节的 ASCII 签名 FILE 开头。(损坏的记录会改为使用 BAAD —— 这是 chkdsk 刻意写下的「墓碑」。)签名之后是一个固定的头部,再后面是一段长度可变的属性流。
记录头部包含:
- 签名 —— 有效记录为
FILE,chkdsk无法修复的记录为BAAD。 - 更新序列号(USN)与 fixup 数组 —— 一个微型校验技巧,让 NTFS 能够检测撕裂写入。记录中每个 512 字节块的最后两字节会被替换为 USN;原始字节则被保存在 fixup 数组中。读取时,NTFS 验证 USN 并将原始字节还原。
- 日志序列号 —— 指向
$LogFile,用于崩溃恢复。 - 序列号 —— 每次该记录被重新使用时递增。与记录号组合后构成一个 64 位的 file reference,唯一标识某个文件的某次具体「化身」。
- 硬链接计数 —— 指向该记录的
$FILE_NAME属性数量。 - 标志位 —— 其中最重要的是 bit 0,即
IN_USE。该位被清零表示已删除。 - 基础文件记录引用 —— 对于属于表中其他位置的某条基础记录的扩展记录,此字段非零。
头部之后就是各个属性。每个属性都有自己的简短头部(类型、长度、resident/non-resident 标志、名称(如有)),后面跟着数据。属性没有固定顺序,但按惯例 $STANDARD_INFORMATION 位于最前,$DATA 位于最后。
当一条记录的空间不够用时 —— 碎片过多、ADS 过多、文件名异常长 —— 就会长出一个 $ATTRIBUTE_LIST 属性,指向表中其他位置的一条或多条 扩展记录。解析器必须沿着这条链跟踪下去,才能拼装出完整的文件。
$MFT 中存储的文件属性
这是关键词 「what file attributes are stored in the master file table」 背后最常见的搜索。下面是 NTFS 属性类型的完整列表,附带十六进制代码:
| Type | Hex | 用途 |
|------|-----|------|
| $STANDARD_INFORMATION | 0x10 | 四个时间戳(创建、修改、访问、MFT 修改)、DOS 标志、属主 ID、安全 ID、USN。 |
| $ATTRIBUTE_LIST | 0x20 | 当文件属性超出单条记录时,指向扩展记录的指针。 |
| $FILE_NAME | 0x30 | 文件名、父目录引用、已分配大小与真实大小,以及第二组四个时间戳。一个文件可以有多个 —— 每条硬链接一个,8.3 短名一个。 |
| $OBJECT_ID | 0x40 | 128 位对象标识符,由 Distributed Link Tracking 服务使用。 |
| $SECURITY_DESCRIPTOR | 0x50 | 旧式的逐文件 ACL。现代 NTFS 将 ACL 集中存放在 $Secure 中,通过 $STANDARD_INFORMATION 里的 ID 引用。 |
| $VOLUME_NAME | 0x60 | 仅出现在记录 3($Volume)。保存卷标。 |
| $VOLUME_INFORMATION | 0x70 | NTFS 版本号,dirty 标志。 |
| $DATA | 0x80 | 文件内容。对于极小的文件为常驻;否则为非常驻(一组簇运行)。一个文件可以携带多个 $DATA 属性 —— 未命名的那个是主数据流,命名的则是 备用数据流。 |
| $INDEX_ROOT | 0x90 | B+ 树的根。被目录($I30)、reparse point 索引以及其他索引结构使用。 |
| $INDEX_ALLOCATION | 0xA0 | 大型索引的非常驻延续部分。 |
| $BITMAP | 0xB0 | $MFT 自身或大型目录的分配位图。 |
| $REPARSE_POINT | 0xC0 | 符号链接、junction、挂载点、OneDrive 占位符。 |
| $EA_INFORMATION / $EA | 0xD0 / 0xE0 | 源自 OS/2 时代的扩展属性。在现代 Windows 上罕见。 |
| $LOGGED_UTILITY_STREAM | 0x100 | EFS 加密元数据($EFS)、TxF 事务数据。 |
一条记录至少始终携带 $STANDARD_INFORMATION、一个 $FILE_NAME 和一个 $DATA。其余都是可选的,由具体功能决定。
常驻数据 vs 非常驻数据
在真实卷上,大多数 $DATA 属性都是 非常驻 的:属性头中携带一份紧凑的 cluster runs 列表(起始 LCN 加长度,反复出现),而文件的字节位于磁盘上的别处。属性头本身很小。
如果文件足够小 —— 通常在扣除其他属性后小于约 700 字节 —— NTFS 就会把字节内联存放在记录中。这就是 常驻数据,也是取证工作中最有用的物件之一:几周前被删除的一个小文本文件,其内容仍可能逐字节地保存在某条已释放的 $MFT 记录中。深入阅读见 resident-data。
前十六条记录里的 NTFS 元数据文件
$MFT 的前 16 条记录被保留给 NTFS 自身的簿记文件。它们以 $ 开头,以免与用户文件名冲突。值得了解的几个:
| 记录号 | 文件 | 含义 |
|--------|------|------|
| 0 | $MFT | 表自身。 |
| 1 | $MFTMirr | $MFT 前几条记录的备份。 |
| 2 | $LogFile | 用于崩溃后撤销或重放未完成操作的事务日志。 |
| 3 | $Volume | 卷标和 dirty 标志。 |
| 4 | $AttrDef | 有效属性类型的 schema。 |
| 5 | . | 根目录。 |
| 6 | $Bitmap | 卷上每个簇一比特;追踪分配情况。 |
| 7 | $Boot | 引导扇区的副本。 |
| 8 | $BadClus | 稀疏文件,其 run 指向文件系统标记为坏簇的每个簇。 |
| 9 | $Secure | 安全描述符的集中存储。 |
| 10 | $UpCase | 用于大小写不敏感名称比较的 Unicode 大写映射表。 |
| 11 | $Extend | 一个目录,包含较新的系统文件:$ObjId、$Quota、$Reparse、$UsnJrnl、$RmMetadata。 |
变更日志 $UsnJrnl(位于 $Extend 下)在取证中尤为有用 —— 它记录了卷上的每一次元数据变更,可与 $MFT 互补,用于时间线重建。参见 usn-journal。
当 $MFT 出问题时:损坏与「Windows cannot recover the master file table」
错误信息 「Windows cannot recover master file table. CHKDSK aborted」 出现在 chkdsk 既无法读取 $MFT、也无法回退到 $MFTMirr 的时候。当你看到这条消息时,NTFS 已经尝试过自己的内置自修复并失败了。
常见根因:
- 物理介质故障。 MFT zone 内的坏扇区会让读取返回乱码。SMART 数据通常能佐证。
- 元数据密集型操作期间的突然断电。 事务日志一般能回滚这类问题,但已损坏的
$LogFile会让回滚失效。 - 驱动或筛选器层的损坏。 行为异常的磁盘加密栈、文件系统微筛选器或有 bug 的存储驱动可能写出不一致的记录。
- 恶意覆写。 擦除器和一些勒索软件家族会故意在
$MFT上涂抹,以增加恢复难度。
从取证角度合理的应对方式是:
- 立即停止对该卷的所有写入。 之后每一次写入都会降低恢复成功率。
- 对磁盘做镜像,用 FTK Imager、
dd或ddrescue写入一个已知良好的目标。校验哈希。 - 在镜像上工作,而不是在原盘上。试试
testdisk、R-Studio,或通过直接对卷做签名扫描寻找FILE记录的手工解析 —— 即便磁盘上指向$MFT的指针已不复存在,记录本身通常仍然可被识别。 - 只有当目标是让卷重新上线、而非恢复数据时,才在镜像上运行
chkdsk /f。
在可写卷上运行 chkdsk /b 可以清除坏簇标记,但它也可能丢弃它无法理解的记录。仅在你已经取得镜像、并且认定可用性优先于取证保真度之后,才在原盘上运行它。
如何读取 $MFT
你有三种现实的选项:
- MFTECmd(Eric Zimmerman 出品) —— Windows 下的 CLI,输出大多数时间线工具所期望的 bodyfile 风格 CSV。事实上的事件响应人员标准工具。
omerbenamram/mft—— 一个 Rust crate 与 CLI。本站使用的同一款解析器,适合脚本化分析或嵌入到更大的流水线中。- 本站的浏览器解析器 —— 把
$MFT拖到主页上,它会在你的浏览器里运行同一个编译为 WebAssembly 的 Rust 解析器,完全本地处理。不会上传任何内容。适合无需安装即可快速阅读的场景,或者政策禁止把证据发送到云端服务时。
如果你想看三者的具体优缺点对比,见 mft-parser-tools。基于已解析 $MFT 的实用工作流,见 build-mft-timeline、deleted-files 和 extracting-mft。
常见问题
MFT 是什么的缩写?
MFT 是 Master File Table 的缩写。在磁盘上也写作 $MFT,因为在 NTFS 中,美元符号是元数据文件名的前缀。
Master File Table 是干什么用的?
它是 NTFS 用来定位卷上每个文件和目录的索引。每个条目存储该文件的名称、时间戳、安全信息、属性以及其数据在磁盘上的位置。
Master File Table 中存储了哪些文件属性?
每条记录至少携带 $STANDARD_INFORMATION(时间戳、DOS 标志)、$FILE_NAME(名称及第二组时间戳)与 $DATA(文件内容或指向其的指针)。根据文件不同,记录还可能携带 $ATTRIBUTE_LIST、$OBJECT_ID、$SECURITY_DESCRIPTOR、$INDEX_ROOT、$INDEX_ALLOCATION、$BITMAP、$REPARSE_POINT、$EA 与 $LOGGED_UTILITY_STREAM。完整参考见上方的属性表。
Master File Table 有多大?
每条记录 1024 字节。默认情况下,该表为自己保留约 12.5% 的卷空间(即 MFT zone),但只会实际占用所需的空间。一个有百万级文件的卷,$MFT 大约为 1 GB。
$MFT 和 $MFTMirr 是一回事吗?
不是。$MFTMirr 是 $MFT 前几条记录的部分备份,被放置在磁盘的别处,以便在主表头部损坏时让 NTFS 能够引导恢复。
如何修复损坏的 Master File Table?
先对磁盘做镜像。然后要么对镜像运行 chkdsk /f(速度快,可能丢弃部分记录),要么使用能够扫描 FILE 签名并从原始簇重建表的恢复工具(速度慢,但保留更多证据)。在做镜像之前,切勿对原始卷运行 chkdsk。
我能在 Linux 或 macOS 上读取 $MFT 吗?
可以。$MFT 只是一个普通文件。任何接受原始 $MFT dump 的解析器都能在任意操作系统上工作 —— omerbenamram/mft、analyzeMFT、本站的浏览器工具皆可。你只在需要从已挂载的活动卷中 提取 文件时才需要 Windows。