このページは USN Parser が入力に対して何を行い、なぜ出力を信頼してよく、どこに限界があるかを文書化します。フォレンジック チェーン オブ カストディの裏付けに使えるよう、レポートで USN Parser を引用する場合に参照すべきページです。
入力
$UsnJrnl:$J: 必須。ボリューム ルートの\$Extend\$UsnJrnlから抽出されたスパースな代替データ ストリーム。必ず$Jストリームでなければなりません —$Maxはサイズ メタデータのみです。$MFT: 任意。同一ボリュームのマスター ファイル テーブル。親ディレクトリ参照をフル パスに解決する目的にのみ使用します。
両ファイルともメモリに読み込み、WebAssembly パーサに渡します。ブラウザは postMessage と明示的な転送リストでバイト バッファを worker に手渡します — メモリに残る不用なコピーを避け、高速です。
パーシング アルゴリズム
usnrs (Airbus CERT、Apache-2.0) を wasm32-unknown-unknown 向けにコンパイルします。Microsoft の NTFS リファレンス に記載の USN_RECORD_V2 構造を実装します。
リーダの動作:
- 先頭のスパースなゼロ領域を、最初の非ゼロ バイト(最初のレコードの開始)までスキップ。
- 前進しつつ、各オフセットで 4 バイトの
RecordLengthを読み、次のレコードへ進む。 - 4 バイトのゼロ列に出会った時点で停止(有効レコードの末尾)。
- レコードごとに、major/minor が
2.0であることを検証し、固定長ヘッダと可変長ファイル名をデコード。
$MFT が与えられた場合は、親参照のチェーンをたどってフル パスを解決します。解決後の末端名がジャーナルの filename と一致する場合に限りフル パスを採用します — 古い MFT エントリが誤った確信のパスを生むことを避けるためです。
出力
各レコードが公開する項目:
usn(u64): ジャーナル内の位置timestampMs(i64): Windows FILETIME を UTC の Unix ミリ秒に変換した値filename(UTF-16 をデコードしたもの)fullPath(string または null):$MFTが与えられ、かつ一致した場合のみreasons(string[]):Reasonビットマスクを可読名に展開した配列attributes(string[]): ファイルに立っている NTFS 属性mftEntry、mftSequence、parentMftEntry、parentMftSequence
出力はタブを閉じるまでブラウザのメモリに留まります。
限界
USN_RECORD_V3未対応。 V3 (ReFS で導入された可変長ファイル参照) は通常の NTFS ボリュームでは生成されないため、実務ではほぼ問題になりません。- リング バッファの巻き戻しは不可視: 最も古いレコードより前に何が上書きされたかは分かりません。さらに古い履歴が必要なら
$LogFileとボリューム シャドウ コピーを併用してください。 - タイムスタンプの検証なし: レコード中の FILETIME を信頼します。タイムスタンプ改ざんを検出するには、SI 対 FN の比較記事 が
$MFTとの標準的なクロス チェックを示します。
チェーン オブ カストディ
レポートに引用する参照としては、USN Parser のバージョンは GitHub リポジトリのフッターに表示されるデプロイ コミット ハッシュで識別できます。wasm 成果物は wasm-pack build --release でソースから再現可能で、ソース リビジョンごとに .wasm のハッシュは安定します。