园子里面已经有文章介绍如何在windows下如何借助windows提供的原生API读取USN日志,本随笔介绍的是解析现有的$usnjrnl文件,得到其中的内容。
经过分析msdn对usn记录的描述(传送门https://docs.microsoft.com/en-us/windows/desktop/api/winioctl/ns-winioctl-usn_journal_data_v2);
typedef struct USN_JOURNAL_DATA_V2 { DWORDLONG UsnJournalID; USN FirstUsn; USN NextUsn; USN LowestValidUsn; USN MaxUsn; DWORDLONG MaximumSize; DWORDLONG AllocationDelta; WORD MinSupportedMajorVersion; WORD MaxSupportedMajorVersion; DWORD Flags; DWORDLONG RangeTrackChunkSize; LONGLONG RangeTrackFileSizeThreshold; } *PUSN_JOURNAL_DATA_V2;
结合分析usn文件本身的内容,本人认为该文件所存储的内容即是如上结构体数据的线性排列,结构比较简单,便只贴代码了。
/// <summary> /// Contains the USN Record Length(32bits), USN(64bits), File Reference Number(64bits), /// Parent File Reference Number(64bits), Reason Code(32bits), File Attributes(32bits), /// File Name Length(32bits), the File Name Offset(32bits) and the File Name. /// </summary> public class UsnRecordV2 { private const int FR_OFFSET = 8; private const int PFR_OFFSET = 16; private const int USN_OFFSET = 24; private const int DateTime_OFFSET = 32; private const int REASON_OFFSET = 40; private const int FA_OFFSET = 52; private const int FNL_OFFSET = 56; private const int FN_OFFSET = 58; private const int StructWithoutFileName_Size = 60; /// <summary> /// 记录在流中的位置,非原结构体中成员; /// </summary> public long RecordPosition { get; private set; } public UInt32 RecordLength { get; private set; } public UInt64 FileReferenceNumber {