内核扩展属性

从 Windows 8 开始,NTFS 支持内核扩展属性(内核 EA)。 验证镜像的签名是一项昂贵的操作。 存储有关以前验证的二进制文件是否已更改的信息会减少映像必须进行完整签名检查的实例数。 出于此原因使用内核 EA 可提升映像文件签名验证的性能。

名称前缀 $Kernel 的 EA 只能从内核模式修改。 以此字符串开头的任何 EA 都被视为内核 EA。 在检索必要的更新序列号(USN)之前,应首先发出 FSCTL_WRITE_USN_CLOSE_RECORD 命令,以提交文件上所有未决的 USN 日志更新。 否则,设置内核 EA 后, FileUSN 值可能会很快更改。

内核 EA 应至少包含以下信息:

  • USN UsnJournalID

    • UsnJournalID 字段是一个 GUID,用于标识 USN 日志文件的当前化身。 USN 日志可以在每个卷的用户模式下删除和创建。 每次创建 USN Journal 时,都会生成新的 UsnJournalID GUID。 使用此字段,您可以判断 USN Journal 是否曾有一段时间被禁用,并重新进行验证。
  • USN FileUSN

    • FileUSN 值包含上次对文件所做的更改的 USN ID,并在给定文件的主文件表 (MFT) 记录内跟踪。
      • 删除 USN 日记时, FileUSN 将重置为零。

然后,将此信息以及可能需要的任何其他给定用法设置到文件中作为内核 EA。

设置内核扩展属性

若要设置内核 EA,它必须以前缀 "$Kernel." 开头,后跟有效的 EA 名称字符串。

将尝试从用户模式设置内核 EA 的操作被悄然忽略。 请求返回 STATUS_SUCCESS 但未进行实际的 EA 修改。

调用 ZwSetEaFileFltSetEaFile 等 API 以从内核模式设置内核 EA 是不够的,因为 SMB 允许跨网络设置 EA。 当设置 EA 的请求通过 SMB 时,它会从处理 SMB 请求的服务器上的内核模式发出。 基于网络的请求可能会在本地不恰当地设置内核扩展属性。

若要设置内核 EA,调用方还必须在 IRP(I/O 请求数据包)的 MinorFunction 字段中设置 IRP_MN_KERNEL_CALL 值。 由于设置此字段的唯一方法是生成自定义 IRP,因此例程 FsRtlSetKernelEaFile 是设置内核 EA 的支持函数。

从 Windows 10 版本 1803 开始,用户扩展属性和内核扩展属性可以混合使用。 设置内核扩展属性不会在 USN 日志中生成 USN_REASON_EA_CHANGE 记录。 设置任何用户 EA 时,系统会生成USN_REASON_EA_CHANGE。

查询扩展属性

从用户模式查询文件中的扩展属性(EA)将返回普通扩展属性和内核扩展属性。 它们将返回到用户模式,以最大程度地减少任何应用程序兼容性问题。 正常的 ZwQueryEaFileFltQueryEaFile 操作会从用户模式和内核模式返回正常和内核的 EA。

如果只有 FileObject 可用,则使用 FsRtlQueryKernelEaFile 可能更方便从内核模式查询内核 EA。

查询更新序列号日志信息

即使从内核模式发出,FSCTL_QUERY_USN_JOURNAL 操作也需要 SE_MANAGE_VOLUME_PRIVILEGE,除非在 IRP 的 MinorFunction 字段中已设置 IRP_MN_KERNEL_CALL 值。 例程 FsRtlKernelFsControlFile 可以轻松允许内核模式组件发出此 USN 请求。

注意 从 Windows 10 版本 1703 及更高版本开始,此作不再需要SE_MANAGE_VOLUME_PRIVILEGE。

自动删除内核扩展属性

只是因为文件的 USN ID 更改而重新扫描文件可能代价高昂,因为有许多无害的原因可能导致 USN 更新应用到该文件。 为了避免不必要的重新扫描,自动删除内核 EA 的功能已添加到 NTFS。

由于在此场景中并非所有内核扩展属性都可能需要删除,因此使用了扩展扩展属性前缀名称。 如果内核 EA 以 "$Kernel.Purge." 开头,然后如果将以下任何 USN 原因写入 USN 日志,NTFS 将删除该文件上符合给定命名语法的所有内核 EA:

  • USN_REASON_DATA_OVERWRITE(用户操作系统数据覆盖原因)
  • USN_REASON_DATA_EXTEND
  • USN_REASON_DATA_TRUNCATION
  • USN_REASON_REPARSE_POINT_CHANGE(重新解析点变更)

即使在内存不足的情况下,内核 EA 的删除也成功。

注解

用户模式组件无法篡改内核 EA。 内核 EA 可以存在于与普通 EA 相同的文件中。

另请参阅

FltQueryEaFile
FltSetEaFile
FSCTL_QUERY_USN_JOURNAL
FsRtlQueryKernelEaFileFsRtlSetKernelEaFile
ZwQueryEaFile
ZwSetEaFile