← 返回博客

从 USN 日志还原用户活动时间线

三分钟的 $UsnJrnl 记录,通常就够你还原用户在做什么 — Office、浏览器、下载、写代码。如何把日志当作一份行为日志来读。

阅读约 2 分钟

「这台电脑下午 2 点到 4 点发生了什么」这类问题,很大一部分能直接从 USN 日志答出来。日志不是 syscall 日志,也不带用户标记 — 但它有一个几乎同样有用的东西:对机器触碰过的每个文件,都有高频、按操作的记录。掌握一点模式,你能以 Office 保存、浏览器导航、IDE 重建、午饭休息 这样的粒度还原用户行为。

本文是把日志当行为时间线读的现场指南。

为什么这能行

USN 日志记录 哪个文件何时何种方式 发生变化 — 而桌面上用户能看到的动作,绝大多数都会产生一段可识别的文件活动签名。用户点 Word 的保存;Word 写一个临时文件,原子重命名,再对结果做一次 BasicInfoChange | Close。Chrome 开一个新标签;磁盘缓存在追加。IDE 重新编译;上千个对象文件涌现出来。

这些签名并未在任何官方文档中写明 — 它们是经验学来的。下面是一份入门集,以及让它们好处理的解析器控件。

Office 在野

当用户保存一个 Word、Excel 或 PowerPoint,你会看到:

FileCreate | Close            ~$<filename>.docx     (锁文件)
FileCreate | Close            <filename>.tmp        (原子临时)
DataExtend | Close            <filename>.tmp        × N
RenameOldName | Close         <filename>.docx
FileDelete | Close            <filename>.docx
RenameNewName | Close         <filename>.docx       (原本是 <filename>.tmp)
FileDelete | Close            ~$<filename>.docx
BasicInfoChange | Close       <filename>.docx

~$ 锁文件是 Office 表明「文档已打开」的信号;它的 FileCreateFileDelete 标出文档的开关时刻。.tmp.docx 的原子重命名就是保存本身。前面的 ~$ 文件出奇有用,因为它们 只在文档打开期间存在

透视小技巧:过滤文件名以 ~$ 开头的 FileCreate,就能枚举出该用户在窗口内打开过的所有 Office 文档。再减去同名的 FileDelete,就找到了取证时仍处于「开着」状态的文档(从一台运行中机器取镜像时,可能会有从未正确关闭的锁文件)。

浏览器活动

现代浏览器在文件系统上维护着相当重的缓存。Chrome 和 Edge 使用 \Users\<u>\AppData\Local\<browser>\User Data\Default\Cache\Cache_Data\(或 Code Cache\);Firefox 使用 \Users\<u>\AppData\Local\Mozilla\Firefox\Profiles\<id>\cache2\

浏览期间你会看到:

  • 缓存目录里持续低频的 FileCreate | CloseDataExtend | Close
  • LRU 淘汰旧条目时,偶尔出现 FileDelete | Close
  • 索引被压缩时,每隔几分钟出现一次缓存文件的 RenameNewName

缓存写入的爆发与访问媒体重度站点或 SPA 高度相关;安静时段则与用户离开或页面长时间加载相关。

缓存文件名不会告诉你访问了哪些 URL(那在浏览器自己的数据库里),但缓存 I/O 的 节奏 在告诉你「这人在浏览」。把它与日志在用户 Downloads\ 下的 FileCreate 事件结合,就能识别有意的下载。

写代码活动

如果用户是开发者,IDE 的重建会产生非常有特征的爆发:

  • Webpack/Vite/Turbopack — 在 node_modules\.cache\dist\ 中产生大量 FileCreate,一次构建往往数百次。
  • Visual Studio C++ — 在 Debug\Release\ 子树中产生 .obj.pdbFileCreate
  • Cargo (Rust) — 增量构建大量触碰 target\debug\incremental\;完整构建则触碰 target\debug\deps\

node_modules\ 中的一阵 5 分钟 FileCreate 爆发,后面紧跟 dist\bundle.js 上的 DataExtend 一团,就是「跑了构建,然后 dev server 重载了」。

下载与安装

直接下载会产生:

FileCreate | Close             \Users\<u>\Downloads\<file>.crdownload   (Chrome)
DataExtend | Close             \Users\<u>\Downloads\<file>.crdownload  × N
RenameNewName | Close          \Users\<u>\Downloads\<file>
BasicInfoChange | Close        \Users\<u>\Downloads\<file>

扩展名 .crdownload.part.download 分别对应 Chrome、Firefox、Edge。最后那一次原子重命名让文件「完成」。

新程序安装通常如此:Downloads 中一个 .exe/.msi 安装器的 FileCreate,然后在 \Program Files\\Program Files (x86)\\Users\<u>\AppData\Local\Programs\ 出现一阵 FileCreate。按分钟的直方图让安装识别变得轻而易举。

合起来:一天的时间线

写一份「用户今天做了什么」报告的菜谱:

  1. 把该用户当天的解析日志取出来。限定到 \Users\<u>\ 以下的记录以去掉系统噪声。
  2. 按 10 分钟桶计算 FileCreateDataExtendBasicInfoChange 的件数。
  3. 画三条序列。形状告诉你大致的活动:
    • 大量 create + extend:在写/保存内容。
    • 只见大量 BasicInfoChange:在浏览、滚动、轻度编辑。
    • 大量 extend、少 create:大下载或多媒体播放。
    • Cache\ 目录下持续 create:在浏览。
    • node_modules\ / Debug\ / target\ 持续 create:在写代码。
  4. 检查每个桶里最频繁的文件名给峰值打注。Office 文件名是极好的锚点;缓存文件名可以无视。

本站解析器的时间线组件直接公开了按分钟直方图 — 点击某根柱子就能把表格过滤到对应窗口,无需写一行代码就完成了上面这套流程。

陷阱

  • 备份和杀软扫描 会产生卷范围的 BasicInfoChange 爆发,表面上像用户活动。它们大多按计划运行并遍历所有目录而非仅用户目录,所以容易识别并排除。
  • 同步代理(OneDrive、Dropbox)会生成 看似 用户活动的日志流量,其实是代理自己干的活。把过滤限定在同步文件夹 之外 的路径,就能聚焦到用户发起的工作。
  • 后台索引器(SearchIndexer.exe)会触碰 \Users\<u>\AppData\Roaming\Microsoft\Windows\Recent\\ProgramData\Microsoft\Search\ 下的文件 — 容易归入系统噪声。

下一步去哪

光靠日志替代不了一套像样的超级时间线。但对 80% 的调查,「下午 2 点到 4 点用户在做什么」只用 $J$MFT 就能答 — 用的时间不超过把它们拖到本页所需。