Master File Table のすべてのエントリは 1,024 バイトで、同じレイアウトで配置されています。固定ヘッダー、小さな修復構造、その後に型付き属性のストリームが続きます。この記事はそのレイアウトを詳しく見ていきます — $MFT の生バイトを 16 進エディタで読んだり、自前のパーサーを書いたりするときに必要となる種類の詳細です。
FILE シグネチャ
すべてのレコードの最初の 4 バイトは ASCII 文字列 FILE(46 49 4C 45)です。パーサーはこれを錨として、生のボリュームから孤立したレコードをスキャンします。FILE で始まる 1,024 バイト境界はすべて MFT レコードであり、テーブル自身のヘッダーが読めなくても認識できます。
chkdsk が修復できなかったレコードは、代わりに BAAD(42 41 41 44)というシグネチャを持ちます。NTFS はこれらのレコードを消去せずに残します — スロットのシーケンス番号は保持されます — が、残りのバイトは信頼してはいけません。
レコード ヘッダー
シグネチャの後の 56 バイトは、これがどんな種類のレコードか、そしてどう安全に読むかを記述します。
- 更新シーケンス配列のオフセット(2 バイト)と 配列のサイズ(16 ビット ワード単位)(2 バイト)。両方でフィックスアップ データを記述します(後述)。
$LogFileシーケンス番号(8 バイト)。クラッシュ リカバリのためにトランザクション ログを指し返します。- シーケンス番号(2 バイト)。レコード スロットが再利用されるたびに加算されます。
- ハード リンク カウント(2 バイト)。
$FILE_NAME属性 1 つにつき 1。 - 最初の属性へのオフセット(2 バイト)。
- フラグ(2 バイト)。ビット 0 が
IN_USE、ビット 1 がディレクトリを示します。 - 使用サイズ(4 バイト)と 割り当てサイズ(4 バイト)。標準ボリュームでは割り当てサイズは常に 1,024 です。
- 基底ファイル レコード参照(8 バイト)。1 ファイルの属性が 1 レコードに収まりきらないときに使われる 拡張レコード では非ゼロになります。
- 次の属性 ID(2 バイト)。新しい属性に一意な ID を割り当てるために使われます。
- レコード番号(4 バイト、NTFS 3.1+)。自己参照で、解析の整合性チェックに便利です。
削除済みファイルの解析の信頼性は、シーケンス番号が支えています。レコード番号単独では再利用されますが、64 ビットの ファイル参照(レコード番号 + シーケンス番号)は再利用されません。あるレコード番号における現在のシーケンスと食い違う参照は、以前の住人 — 通常は削除されたファイル — を指すポインタです。
フィックスアップ配列
NTFS は 更新シーケンス配列(USA、または フィックスアップ配列)という小さな仕組みで、書き込み途中破損(torn write)を検出します。1,024 バイトのレコードはまた 512 バイトのセクタ 2 つに分割されています。NTFS は次の処理を行います。
- 16 ビットの 更新シーケンス番号(USN — 同じ頭字語ですが
$UsnJrnlの USN とは無関係)を選びます。 - 書き込み前に 各 512 バイト セクタの末尾 2 バイト をその USN で置き換えます。
- 各セクタの元の末尾 2 バイトを、USN 自身の直後にフィックスアップ配列内に順番に格納します。
読み出し時、NTFS は各セクタの末尾 2 バイトが USN と一致するか確認します。一致すれば、セクタは一緒に書かれたと判断し、元のバイトをフィックスアップ配列から取り出して戻します。どれかのセクタの末尾が一致しなければ、書き込みは途切れており、そのレコードは疑わしいと判定されます。
つまり、フィックスアップを適用せずに $MFT を 1 バイト単位で読むパーサーは、各レコードのオフセット 510 と 1022 でゴミを受け取ります。本格的な MFT パーサーは、レコードを見つけた直後にまずフィックスアップを適用します。
属性ストリーム
ヘッダー(とフィックスアップ配列)の後にファイルの属性が続きます。各属性はそれ自身の短いヘッダー — 型コード、長さ、常駐/非常駐フラグ、任意の名前 — から始まり、続いて属性のデータが置かれます。属性は 8 バイト境界で整列され、隙間なく書かれ、0xFFFFFFFF の番兵で終端されます。
最小限のレコードは 3 つを持ちます。
$STANDARD_INFORMATION(0x10)— タイムスタンプと DOS フラグ。$FILE_NAME(0x30)— 名前、親ディレクトリ参照、もう 1 組のタイムスタンプ。$DATA(0x80)— ファイルの内容。小さなファイルではインラインで常駐、それ以外ではクラスタ ランのリスト。
レコードはこれよりも多くを持つことがあり、ファイルの属性が 1 つの 1,024 バイト スロットに収まらないときには $ATTRIBUTE_LIST も含まれます。完全な一覧は Master File Table のリファレンス にあります。
フォレンジックで重要な理由
安定した 1,024 バイトのレイアウトと FILE シグネチャの組み合わせが、削除された NTFS ファイルのカービングを可能にしています。$MFT 自身がなくなっていても、生ボリュームを FILE ヘッダーで走査すれば、ほとんどのレコード — 削除エントリの名前、タイムスタンプ、そして(小さなファイルでは)データ — が回復できます。フィックスアップ機構によって、USA が検証される限り、回収されたこれらのレコードを信頼できます。