Master File Table はディスク上では $MFT と書かれ、NTFS がボリューム上のすべてのファイルとディレクトリを追跡するためのインデックスです。すべての NTFS パーティションで最初のユーザー可視ファイルであり、ボリューム上の他のすべてのファイル — テーブル自身も含めて — はこの中に少なくとも 1 つのエントリを持っています。$MFT を読むことは、Windows がもう存在を認めないファイルについて、フォレンジック ツールが答えを出す手段になります。いつ作成されたか、どんな名前だったか、何を含んでいたか、そして最後に誰が触れたか。
この記事は包括的なリファレンスです。テーブルとは何か、レコードはどう配置されるか、レコードが持ち得る属性、テーブル先頭の予約済みシステム ファイル群、「Windows がマスター ファイル テーブルを回復できない」とは実際何を意味するか、そして本サイトのパーサーで $MFT を自分で読む方法までカバーします。
マスター ファイル テーブルとは何か
マスター ファイル テーブルは $MFT という単一のファイルで、すべての NTFS ボリュームの先頭近くの固定位置に置かれます。NTFS — New Technology File System — は 1993 年の Windows NT 3.1 で導入され、Windows の既定のファイル システムとして FAT を置き換えました。FAT は小さな割り当てテーブルを保持し、ファイル名はディレクトリ エントリ内に格納していたのに対し、NTFS はほぼすべてのファイルのほぼすべてのメタデータを 1 つの構造化テーブル $MFT に集約します。
このテーブルの各行は レコード で、長さは正確に 1,024 バイトです。各レコードは 1 つのファイルまたは 1 つのディレクトリを記述します。レコードはファイル名、タイムスタンプ、DOS スタイルのフラグ、データが格納されているディスク クラスタの一覧、セキュリティ ディスクリプタ、その他いくつかの属性を保持し、それらは小さな型付きフィールドの集合としてエンコードされます。
この設計には 2 つの大きな帰結があります。
- すべてのメタデータが 1 箇所にまとまっている。
$MFTを 1 度シークするだけでボリューム上のすべてのファイルを列挙できます。フォレンジックや復元のツールはこれに依存していますし、ウイルス対策スキャナやインデックス作成サービスもそうです。 - 削除されたファイルはメタデータをそのまま残す。 NTFS はファイルを削除する際、レコード ヘッダーの 1 ビットをクリアし、ファイルのクラスタを空きとしてマークするだけです。レコードの残り — 名前、タイムスタンプ、しばしばデータ ラン — は、そのレコード スロットが再利用されるまで残ります。
頭字語 MFT は Master File Table の略です。 MFT、$MFT、または the MFT と表記されますが、いずれも同じディスク上の構造を指します。
$MFT のディスク上の配置
NTFS がボリュームをフォーマットするとき、パーティションの先頭近くに MFT zone と呼ばれる領域を予約します。ボリュームのオフセット 0 にあるブート セクタには、$MFT の最初のクラスタを指すポインタ(MftStartLcn フィールド)が含まれます。テーブルの最初の 16 レコードは NTFS のメタデータ ファイル(後述)用に予約されており、レコード 0 はテーブル自身のエントリで、自分自身のクラスタを指し返します。
$MFT はより多くのレコードが必要になるたびに、予約ゾーンに拡張して成長します。ゾーンが尽きる前にボリュームが満杯になると、Windows はユーザー データのためにゾーンを縮小します。これが、長く使われたファイル システムで激しく断片化した $MFT が一般的な症状である理由です。
最初のいくつかのレコードのバックアップは、通常ボリュームの中央付近に置かれる第 2 のファイル $MFTMirr に存在します。$MFT 自体が破損した場合、NTFS は $MFTMirr を使って回復をブートストラップします — これが後述する 「Windows がマスター ファイル テーブルを回復できません」 エラーの背後にある仕組みです。
FILE レコードの解剖
すべての MFT レコードは 4 バイトの ASCII シグネチャ FILE で始まります。(破損したレコードでは代わりに BAAD が使われます — これは chkdsk が意図的に書き込む墓標です。) シグネチャの後には固定ヘッダーが続き、その後に可変長の属性ストリームが並びます。
レコード ヘッダーには次のものが含まれます。
- シグネチャ — 有効なレコードでは
FILE、chkdskが修復できなかったレコードではBAAD。 - 更新シーケンス番号 (USN) とフィックスアップ配列 — NTFS が書き込み途中破損(torn write)を検出するための小さなチェックサム機構。レコード内の各 512 バイト ブロックの末尾 2 バイトは USN で置き換えられ、元の値はフィックスアップ配列に保存されます。読み出し時、NTFS は USN を検証し元のバイトを復元します。
- ログ シーケンス番号 — クラッシュ リカバリのための
$LogFileへのポインタ。 - シーケンス番号 — レコードが再利用されるたびに加算されます。レコード番号と組み合わせて、特定のファイルの 1 つの化身を一意に識別する 64 ビットの ファイル参照 を形成します。
- ハード リンク カウント — このレコードを指す
$FILE_NAME属性の数。 - フラグ — 最も重要なのはビット 0、
IN_USE。クリアされていれば削除済みを意味します。 - 基底ファイル レコード参照 — テーブル内の他の場所にある基底レコードに属する拡張レコードでは非ゼロになります。
ヘッダーの後には属性が続きます。各属性は独自の短いヘッダー(型、長さ、常駐/非常駐フラグ、必要なら名前)を持ち、その後にデータが続きます。固定の順序はありませんが、慣習として $STANDARD_INFORMATION が先頭、$DATA が末尾に置かれます。
スペースを使い切ったレコード — フラグメントが多すぎる、ADS が多すぎる、異常に長い名前 — には $ATTRIBUTE_LIST 属性が追加され、テーブル内の他の場所にある 1 つ以上の 拡張レコード を指します。パーサーは完全なファイルを組み立てるためにこの連鎖を辿らなければなりません。
$MFT に格納されるファイル属性
これは 「マスター ファイル テーブルに格納されるファイル属性は何か」 というキーワードの背後にある最も一般的な検索です。NTFS の属性型の完全な一覧を、16 進コードと共に示します。
| 型 | Hex | 役割 |
|------|-----|---------|
| $STANDARD_INFORMATION | 0x10 | 4 つのタイムスタンプ(作成、更新、アクセス、MFT 更新)、DOS フラグ、オーナー ID、セキュリティ ID、USN。 |
| $ATTRIBUTE_LIST | 0x20 | ファイルの属性が 1 レコードに収まらないときに拡張レコードを指すポインタ。 |
| $FILE_NAME | 0x30 | ファイル名、親ディレクトリ参照、割り当てサイズと実サイズ、そして 4 つのタイムスタンプの 2 組目。ハード リンクごとに 1 つ、8.3 形式の短い名前用に 1 つなど、複数持つこともあります。 |
| $OBJECT_ID | 0x40 | Distributed Link Tracking サービスで使われる 128 ビットのオブジェクト識別子。 |
| $SECURITY_DESCRIPTOR | 0x50 | 旧来のファイルごとの ACL。現代の NTFS は ACL を $Secure に集中保管し、$STANDARD_INFORMATION から ID で参照します。 |
| $VOLUME_NAME | 0x60 | レコード 3 ($Volume) にのみ存在。ボリューム ラベルを保持します。 |
| $VOLUME_INFORMATION | 0x70 | NTFS バージョン、dirty フラグ。 |
| $DATA | 0x80 | ファイルの内容。とても小さなファイルでは常駐、それ以外では非常駐(クラスタ ランのリスト)。1 つのファイルが複数の $DATA を持つことがあります — 名前なしのものがメイン ストリーム、名前付きが 代替データ ストリーム です。 |
| $INDEX_ROOT | 0x90 | B+ ツリーのルート。ディレクトリ ($I30)、reparse-point インデックス、その他のインデックス構造で使われます。 |
| $INDEX_ALLOCATION | 0xA0 | 大きなインデックスの非常駐な続き。 |
| $BITMAP | 0xB0 | $MFT 自身や大きなディレクトリ用の割り当てビットマップ。 |
| $REPARSE_POINT | 0xC0 | シンボリック リンク、ジャンクション、マウント ポイント、OneDrive プレースホルダ。 |
| $EA_INFORMATION / $EA | 0xD0 / 0xE0 | OS/2 時代の拡張属性。現代の Windows ではまれ。 |
| $LOGGED_UTILITY_STREAM | 0x100 | EFS 暗号化のメタデータ ($EFS)、TxF トランザクション データ。 |
レコードは少なくとも $STANDARD_INFORMATION、1 つの $FILE_NAME、1 つの $DATA を必ず持ちます。それ以外はすべて任意で、機能に応じて付与されます。
常駐データ対非常駐データ
実ボリューム上のほとんどの $DATA 属性は 非常駐 です。属性ヘッダーにはコンパクトな クラスタ ラン(開始 LCN と長さの組を繰り返したもの)のリストが入り、ファイルのバイトはディスク上の別の場所に存在します。属性ヘッダー自体は小さいです。
ファイルが十分小さい場合 — 通常、他の属性を考慮した上で約 700 バイト未満 — NTFS はそのバイトをレコード内にインラインで格納します。これが 常駐データ であり、フォレンジックで最も有用なアーティファクトの 1 つです。数週間前に削除された小さなテキスト ファイルの内容が、未割り当て $MFT レコード内にバイト単位で残っていることがあります。詳細は resident-data を参照してください。
最初の 16 レコードにある NTFS メタデータ ファイル
$MFT の最初の 16 レコードは NTFS 自身のブックキーピング ファイル用に予約されています。ユーザーのファイル名と衝突しないよう $ で始まります。知っておく価値があるものを示します。
| Rec # | ファイル | 内容 |
|-------|------|------------|
| 0 | $MFT | テーブル自身。 |
| 1 | $MFTMirr | $MFT の先頭レコードのバックアップ。 |
| 2 | $LogFile | クラッシュ後に未完了の操作を取り消し/再実行するためのトランザクション ログ。 |
| 3 | $Volume | ボリューム ラベルと dirty フラグ。 |
| 4 | $AttrDef | 有効な属性型のスキーマ。 |
| 5 | . | ルート ディレクトリ。 |
| 6 | $Bitmap | ボリューム上のクラスタごとに 1 ビット。割り当て状況を追跡。 |
| 7 | $Boot | ブート セクタのコピー。 |
| 8 | $BadClus | ファイル システムが不良としてマークしたすべてのクラスタを指すランを持つスパース ファイル。 |
| 9 | $Secure | セキュリティ ディスクリプタの集中保管庫。 |
| 10 | $UpCase | 大文字小文字を区別しない名前比較のための Unicode 大文字マッピング テーブル。 |
| 11 | $Extend | より新しいシステム ファイル群を含むディレクトリ: $ObjId、$Quota、$Reparse、$UsnJrnl、$RmMetadata。 |
変更ジャーナル $UsnJrnl($Extend 配下)は、フォレンジックで特に有用です — ボリュームのメタデータ変更をすべてログし、タイムライン再構築のために $MFT を補完します。usn-journal を参照してください。
$MFT に問題が起きたとき: 破損と「Windows がマスター ファイル テーブルを回復できません」
エラー メッセージ 「Windows がマスター ファイル テーブルを回復できません。CHKDSK は中止されました」 は、chkdsk が $MFT を読めず、$MFTMirr にもフォールバックできない時に表示されます。このメッセージを目にする時点で、NTFS は組み込みの自己修復を試みて失敗しています。
よくある根本原因:
- 物理メディアの故障。 MFT zone の不良セクタで読み取りがゴミを返します。SMART データが通常裏付けてくれます。
- メタデータ集中の操作中の突然の電源喪失。 トランザクション ログが通常はロールバックしますが、
$LogFileが破損するとロールバックは失敗します。 - ドライバまたはフィルタ レベルの破損。 行儀の悪いディスク暗号化スタック、ファイル システム ミニフィルタ、バグのあるストレージ ドライバが不整合なレコードを書き込むことがあります。
- 悪意ある上書き。 ワイパーや一部のランサムウェア ファミリは、ボリュームを復元しにくくするため
$MFTを意図的に書き荒らします。
フォレンジック的に健全な対応は以下の通りです。
- ボリュームへの書き込みを直ちに停止する。 これ以上書き込めば、復元の可能性は下がります。
- FTK Imager、
dd、またはddrescueで ディスクをイメージング し、信頼できる保存先に保管します。ハッシュを検証します。 - オリジナルではなくイメージに対して作業します。
testdisk、R-Studio、またはボリュームを直接シグネチャ スキャンしてFILEレコードを見つける手動解析を試します — ディスク上の$MFTへのポインタが失われていても、レコード自体は通常まだ識別可能です。 - データ復旧ではなくボリュームをオンラインに戻すことが目的の場合に限り、その後にイメージに対して
chkdsk /fを実行します。
書き込み可能ボリュームに対する chkdsk /b は不良クラスタ マーカーを消せますが、理解できないレコードを破棄することもあります。可用性がフォレンジック忠実度に勝ると決めた上で、イメージを取得した後でだけ、オリジナルに対して実行してください。
$MFT を読む方法
現実的な選択肢は 3 つあります。
- MFTECmd(Eric Zimmerman)— Windows の CLI で、ほとんどのタイムライン ツールが期待する bodyfile に近いレイアウトの CSV を生成します。インシデント レスポンダーの事実上の標準。
omerbenamram/mft— Rust クレートと CLI。本サイトと同じパーサーで、解析をスクリプト化したり、大きなパイプラインに組み込んだりしたい時に便利です。- 本サイトのブラウザ パーサー — トップ ページ に
$MFTをドロップすると、WebAssembly にコンパイルされた同じ Rust パーサーがブラウザ内で完全に動作します。何もアップロードされません。インストール無しで素早く読みたい場合や、クラウド サービスに証拠を送ることがポリシーで禁じられている場合に有用です。
具体的な長所と短所の比較は mft-parser-tools を参照してください。解析済み $MFT を活用する実践的なワークフローは build-mft-timeline、deleted-files、extracting-mft を参照してください。
よくある質問
MFT は何の略ですか?
MFT は Master File Table の略です。ディスク上では $MFT と書かれます — NTFS ではドル記号がメタデータ ファイルの名前の接頭辞だからです。
マスター ファイル テーブルは何に使われますか?
NTFS がボリューム上のすべてのファイルとディレクトリを見つけるために使うインデックスです。各エントリにはファイル名、タイムスタンプ、セキュリティ情報、属性、データのディスク上の位置が格納されます。
マスター ファイル テーブルにはどのファイル属性が保存されますか?
最小限、すべてのレコードは $STANDARD_INFORMATION(タイムスタンプ、DOS フラグ)、$FILE_NAME(名前と 2 組目のタイムスタンプ)、$DATA(ファイルの内容またはそのポインタ)を持ちます。レコードはファイルに応じて $ATTRIBUTE_LIST、$OBJECT_ID、$SECURITY_DESCRIPTOR、$INDEX_ROOT、$INDEX_ALLOCATION、$BITMAP、$REPARSE_POINT、$EA、$LOGGED_UTILITY_STREAM も持ち得ます。完全な一覧は上の属性表にあります。
マスター ファイル テーブルの大きさはどのくらいですか?
各レコードは 1,024 バイトです。テーブルは既定でボリュームの約 12.5%(MFT zone)を予約しますが、実際に必要な領域しか消費しません。100 万ファイルのボリュームでは $MFT はおよそ 1 GB になります。
$MFT と $MFTMirr は同じものですか?
いいえ。$MFTMirr は $MFT の最初のいくつかのレコードの部分的なバックアップで、メイン テーブルのヘッダーが破損した場合に NTFS が回復をブートストラップできるよう、ディスク上の別の場所に置かれます。
破損した Master File Table はどう修復しますか?
まずディスクをイメージング してください。その後、イメージに対して chkdsk /f を実行する(速いがレコードを破棄することがある)か、FILE シグネチャを走査してテーブルを生のクラスタから再構築できる復旧ツールを使う(遅いがより多くの証拠を保存)かのどちらかです。イメージング前にオリジナルのボリュームで chkdsk を絶対に実行しないでください。
Linux や macOS で $MFT を読めますか?
はい。$MFT はただのファイルです。生の $MFT ダンプを受け入れるあらゆるパーサーは、どの OS でも動作します — omerbenamram/mft、analyzeMFT、本サイトのブラウザ ツールなど。稼働中のマウント済みボリュームから 抽出 するためにのみ Windows が必要です。