NTFS USN Jornal の確認用として、新規にVHDディスクを作成し、NTFSでフォーマットします。下記図ではF:ドライブが新規に作成したNTFSボリュームになります。
fsutil コマンドを利用し、ジャーナルの状態を確認します。F:ドライブに USN ジャーナルは設定されていません。
> fsutil usn queryjournal f:
F:ドライブでUSN Jornalを有効に設定します。テスト用ですので、m と a の値は1を設定します。
fsutil usn createjournal m=1 a=1 f:
USN Jornal が有効になった事を確認します。
First Usn は 0x0000000000000000 となっています。
USN 値は $J 内のオフセット位置になっています。
Keeping an Eye on Your NTFS Drives: the Windows 2000 Change Journal Explained
より引用
The Change Journal always writes new records to the end of the file, so the implementors chose to use the file offset of a record as its USN. This makes querying the journal fast since the system can simply seek the desired record using the USN.
Autopsyを使い$UsnJrnl:$J ファイルのメタデータを確認します。この時点では、$J ストリームのサイズはゼロになっています。
F:ドライブ上にファイルa.txtを新規作成します。この操作によって、USNジャーナルにレコードが追加されます。
F:ドライブのUSNを確認します。First Usn はゼロのままで、Next Usnの値が更新されています。
メタ情報を確認します。$Jにクラスタ番号 1992 が割り当てられています。
$J のデータを参照すると、USN レコードを確認できます。
USNレコードの構造は下記のように定義されています。
USN_RECORD_V2 structure (Windows) より引用
typedef struct {
DWORD RecordLength;
WORD MajorVersion;
WORD MinorVersion;
DWORDLONG FileReferenceNumber;
DWORDLONG ParentFileReferenceNumber;
USN Usn;
LARGE_INTEGER TimeStamp;
DWORD Reason;
DWORD SourceInfo;
DWORD SecurityId;
DWORD FileAttributes;
WORD FileNameLength;
WORD FileNameOffset;
WCHAR FileName[1];
} USN_RECORD_V2, *PUSN_RECORD_V2, USN_RECORD, *PUSN_RECORD;
最初のレコードをパースしてみます。
0x00000000: 48 00 00 00 02 00 00 00 28 00 00 00 00 00 01 00 H.......(.......
0x00000010: 05 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 ................
0x00000020: 5A 9F 5D 28 A9 41 D3 01 00 01 00 00 00 00 00 00 Z.](.A..........
0x00000030: 00 00 00 00 20 00 00 00 0A 00 3C 00 61 00 2E 00 .... .....<.a...
0x00000040: 74 00 78 00 74 00 00 00
48 00 00 00 RecordLength ⇒ 0x48 ⇒ 72
02 00 MajorVersion
00 00 MinorVersion
28 00 00 00 00 00 01 00 FileReferenceNumber ⇒ MFT Record No 40
05 00 00 00 00 00 05 00 ParentFileReferenceNumber ⇒ 親 MFT Record No 5
00 00 00 00 00 00 00 00 Usn
5A 9F 5D 28 A9 41 D3 01 TimeStamp ⇒ 2017/10/10 18:21:30.6379098 JST (UTC+9)
00 01 00 00 Reason ⇒ 00 00 01 00 ⇒ USN_REASON_FILE_CREATE
00 00 00 00 SourceInfo
00 00 00 00 SecurityId
20 00 00 00 FileAttributes
0A 00 FileNameLength ⇒ 0x0A ⇒ 10
3C 00 FileNameOffset ⇒ 0x 3C ⇒ 60
61 00 2E 00 74 00 78 00 74 00 00 00 FileName ⇒ a.txt
fsutilコマンドを使い、a.txtファイルのUSN情報を取得します。
fsutil usn readdata f:\a.txt
a.txt ファイルの USN 値として 0x90 ⇒ 144 を確認できます。
上記から、a.txtに関連した最後のUSNレコードは、$Jのオフセット144にある事が分かります。
上記の USN 値は a.txt の MFT レコード内 $STANDARD_INFORMATION で確認できます。
NTFS DOC ページ9から引用
Update Sequence Number (USN)
Last Update Sequence Number of the file. This is a direct index into the file $UsnJrnl. If zero, the USN Journal is disabled.
Autopsy では File Metadata のタブで USN を確認できます。
「Last User Journal Update Sequence Number: 」の項目で USN が 0x90⇒144 である事を確認できます。
$Jファイルのパージ
$Jに保存されるレコードが増加すると、古いレコードはパージされます。
下記は $J でレコードが増加し、First Usn が更新された状態を示しています。
First Usn : 0x0000000000080000
開始USNが 0x80000 になっている $J ファイルのデータ内容を確認します。
$J のデータ先頭部分は 00 になっています。
$J データのオフセット 0x80000 ⇒ 524288 を確認します。USN レコードが保存されている事を確認できます。
$J のメタ情報で、クラスタの割り当て状況を確認します。クラスタ番号 2184 より前はスパースの為 0 になっています。128クラスタ分がスパースとなっています。(128 x 4096 = 524288 ⇒ 0x80000)
$J の DataRun を MFT レコードで確認してみます。
Data Run 1 : 02 80 00
0 F=Size of the Offset field
2 L=Size of the Length field
80 00 Offset to the starting LCN of the previous element
Data Run 2: 21 40 88 08
2
1
40 ⇒ 64
88 08 ⇒ 2184 ⇒ Cluster No 2184(DataRun 1 Offset 0 + 2184)
Data Run 3...が続く
$J のレコードが増えた場合、データ先頭部分はパージされますが、スパースを利用して USN オフセットの位置は維持されます。
USNレコードのカービング
$J が利用していたクラスタ番号 1992 (1992 x 4096 = 8159232)のデータを確認してみます。クラスタ番号 1992 には USN レコードのデータが残っていることを確認できます。この状態であれば、USN レコードのカービングが可能です。
インデックスとUSN
USN が有効でないボリュームに対して、Index を有効にすると、自動的に USN が有効になります。
参考URL: