状态分离
状态分离是一种改进的服务和安全模型,它使用更清晰的安全边界来实现以下目的:
- 帮助提高关键系统区域的安全性
- 实现更快、更简洁的更新和系统重置
此模型用于所有工厂 OS 映像。 安全边界按以下状态分类:
状态 | 说明 | 示例 |
---|---|---|
不可变 | 此区域不能永久更改,操作系统本身发起的更改除外。 |
|
可变,高值 | 可以进行更改,并期望这些更改在重新启动或更新后保留,但不能在系统重置后保留 |
|
可变,低值 | 可以进行更改,但它们将在重新启动或系统重置后消失。 | 某些组件可能需要写入注册表配置单元,例如 HKLM\SYSTEM 和 HKLM\SOFTWARE 。 这些注册表区域作为易失存储区加载,因此组件仍可以执行特定运行时的写入操作。 下次重新启动时,更改将消失。 |
用户数据 | 可更改。 每个用户数据配置文件都在其自己的分区上加密,因此更改只影响登录的用户 |
|
对于工厂测试,可以将日志文件和其他测试文件存储到数据分区或 %PROGRAMDATA%
中。
状态分离冲突
以下情况中会发生状态分离冲突:
- 组件尝试写入 MainOS 卷上的文件系统。
- 组件写入
HKLM\SYSTEM
或HKLM\SOFTWARE
注册表配置单元。
为帮助开发符合这些规则的组件,每当组件尝试写入这些位置之一时,Windows 就会进行记录。
请注意,Windows 跟踪写入操作并不一定意味着存在问题:预期更改是易失性更改时,组件有时可能会有意写入 HKLM\SYSTEM
或 HKLM\SOFTWARE
注册表配置单元。
检测
有几种方法可以收集注册表和文件系统活动的日志。 确定要使用的适当方法取决于用例,以及驱动程序何时在启动序列中变为活动状态。 下表汇总了何时使用每种方法来查找状态分离和驱动程序隔离冲突。
方法 | 运行时机 | 它查找的内容 |
---|---|---|
早期启动自动记录器 | 想要查找驱动程序验证程序无法找到的文件冲突,或者想要在同一跟踪中查看文件和注册表冲突 | 所有文件冲突以及大多数注册表冲突 |
按需记录器 | 想要查找驱动程序验证程序无法找到的文件冲突,或者想要在同一跟踪中查看文件和注册表冲突 | 所有文件冲突以及大多数注册表冲突 |
启动跟踪 | 想要获得导致冲突的详细堆栈信息 | 所有文件和注册表操作,无论它们是否冲突 |
驱动程序验证器驱动程序隔离检查 | 想要在设备启动、通用驱动程序测试和/或认证测试期间查找所有注册表冲突 | 无文件冲突和所有注册表冲突 |
冲突实时视图
跟踪状态分离冲突的最简单方法是通过 Windows 设备门户实时查看 Windows 的事件跟踪 (ETW)
注意
提供此遥测的筛选器驱动程序可能会在组件之后加载。 如果组件是在启动过程的早期执行的,则需要查看下一部分。
- 在受测设备上登录 Windows 设备门户
- 转到左侧的“ETW 日志记录”选项卡。
- 在“自定义提供程序”下,启用以下提供程序:d6e1490c-c3a6-4533-8de2-18b16ce47517。
- 重现场景。 表中将显示冲突。
- 收集足够的数据后,单击“保存到文件”,获取包含捕获的冲突的文本文件 (.csv)。 处理下载的数据通常比执行实时分析更容易。
早期启动的自动记录器
使用早期启动的自动记录器,捕获在启动路径早期执行的操作的 ETW 跟踪:
运行跟踪日志,配置自动记录器来侦听提供程序 GUID:d6e1490c-c3a6-4533-8de2-18b16ce47517。
将缓冲区设置为 128 KB,最少包含 12 个缓冲区,最多包含 34 个缓冲区(较低的值可能会导致事件被删除)。
对于会话 guid,可以使用
uuidgen
生成 GUID,然后在它之前添加数字符号 (#),也可以提供包含 GUID 的文件名。可以将日志文件保存到任何位置,但我们建议使用用户或应用数据文件夹中的位置(例如
-f %ProgramData%\Fabrikam\log.etl
)。Tracelog.exe -addautologger StateSeparationViolationsAutologger -sessionguid #aabbccdd-1234-5678-90ab-a00bb00ccdd -f %ProgramData%\Fabrikam\log.etl -guid #d6e1490c-c3a6-4533-8de2-18b16ce47517 -b 128 -min 12 -max 34
重新启动设备以开始自动记录器跟踪会话
停止自动记录器:
Tracelog.exe -stop StateSeparationViolationsAutologger
获取 ETL 文件并查看数据:
a. 捕获设备的 ProgramData 目录的值(例如
E:\ProgramData
)。cmd-device -InformationVariable echoInfo echo %ProgramData% $deviceProgramData = $echoInfo[0]
b. 使用此值将 ETL 文件从设备复制到本地电脑。 示例:
PS C:\> getd E:\ProgramData\Fabrikam\log.etl C:\hostdir\log.etl
使用 Windows 性能分析器 (WPA) 或其他工具查看跟踪日志记录活动数据。
按需记录器
使用按需记录器捕获按需 ETW 跟踪。
配置日志记录会话以侦听提供程序 GUID d6e1490c-c3a6-4533-8de2-18b16ce47517:
Tracelog.exe -start StateSeparationViolations -f <path to save ETL> -guid #d6e1490c-c3a6-4533-8de2-18b16ce47517
重现场景或运行测试(只要设备不重新启动)。
停止日志记录会话。
Tracelog.exe -stop StateSeparationViolations
从设备中复制 ETL 文件。
PS C:\> getd C:\ProgramData\Fabrikam\log.etl C:\hostdir\log.etl
打开日志文件,然后使用 Windows 性能分析器查看跟踪日志记录活动数据。
启动跟踪
正确设置早期启动 ETW 跟踪后,可以在跟踪中捕获所有注册表操作和/或文件操作,并捕获每个操作的堆栈(详细说明导致该注册表操作的代码路径)。
注册启动跟踪(注册表、fileio 或两者)
wpr -boottrace -addboot registry wpr -boottrace -addboot fileio
重新启动设备以开始捕获跟踪。
再次使用 TShell 连接到设备。
停止跟踪:
wpr -boottrace -stopboot <path where to write ETL>
从设备中复制 ETL 文件。
PS C:\> getd C:\<path on device to the>\log.etl C:\hostdir\log.etl
打开日志文件,然后使用 Windows 性能分析器打开跟踪日志记录活动数据。
在 WPA 中,告知它加载符号,以便可以在堆栈跟踪中解析正在调查的二进制文件,然后打开注册表摘要表。
建议筛选表,以仅显示对 SYSTEM 和 SOFTWARE 配置单元的操作。 如果要查看“基本键树”列,请依次展开“注册表”和“计算机”。 同时选择“系统”和“软件”,然后右键单击并选择“筛选到所选内容”。
建议将表筛选为仅包含堆栈中涉及正在调查的二进制文件的操作。 此筛选可以在上面推荐的对 SYSTEM 和 SOFTWARE 配置单元的筛选基础上进行。 单击“堆栈”列并打开搜索框。 输入要调查的二进制文件的名称,然后单击“查找全部”。 右键单击堆栈中包含二进制名称的突出显示行之一,然后选择“筛选到所选内容”。
驱动程序验证器驱动程序隔离检查
驱动程序验证器 (DV) 是一种随 Windows 提供的工具,用于监视驱动程序是否有不当的函数调用或可能破坏系统的操作。 从 OS 内部版本 19568 开始,驱动程序验证器具有新功能,可以通过监视违反驱动程序包隔离要求的行为来为 Windows 驱动程序的开发人员提供支持。 为遵守状态分离要求,驱动程序包隔离是驱动程序在工厂 OS 系统上必须遵循的关键要求。
驱动程序验证器将监视工厂 OS 系统上是否存在不允许的不正确注册表读写操作。 在驱动程序开发的早期使用此工具,了解并修复组件违反驱动程序隔离要求的情况。
语法:
注意
如果要在工厂 OS 系统上启用,请参阅使用 SSH 进行连接以通过 SSH 连接到工厂 OS 系统
verifier /rc 33 36 /driver myDriver.sys
这将对目标驱动程序 (myDriver.sys) 启用驱动程序隔离检查。 还可以通过用空格分隔列表来选择多个驱动程序:
verifier /rc 33 36 /driver myDriver1.sys myDriver2.sys
需要重新启动才能启用验证设置。 为此,可以指定:
shutdown /r /t 0
预期行为 - 遥测模式:
在驱动程序启动的初始阶段,这些检查的建议行为是遥测模式。这是默认行为,将为开发人员提供一种方法来查看所有冲突,不会因为检查 bug 而中断进度。
建议使用上述部分指定的语法启用 DV 驱动程序隔离检查,并附带使用内核调试器。 重启操作启用 DV 设置后,可在内核调试器输出中查看违规行为。
下面是驱动程序违反驱动程序隔离要求的一些示例场景,典型的输出如下所示:
场景:使用完整绝对路径的 ZwCreateKey:
“DRIVER_ISOLATION_VIOLATION:<driver name>:注册表操作不应使用绝对路径。 检测到创建未隔离的注册表项‘\Registry\Machine\SYSTEM’”
场景:ZwCreateKey 使用相对于句柄的路径,该句柄不是来自批准的 API:
“DRIVER_ISOLATION_VIOLATION:<driver name>:注册表操作应仅使用从 WDF 或 WDM API 返回的密钥句柄。 检测到创建未隔离的注册表项‘\REGISTRY\MACHINE\SYSTEM\SomeKeyThatShouldNotExist’”
利用遥测模式为组件建立所有违规的基线,开始逐个修复这些冲突,并随时进行测试。
预期行为 - Bugcheck 模式:
驱动程序开发过程中,在使冲突明显化的模式中启用驱动程序隔离检查可能很有价值。 发生冲突时,可以将 DV 配置为 induceabugcheck。
这将生成一个内存转储,该转储提供冲突发生位置的精确详细信息。 若要在bugcheck 模式下启用 DV,请使用以下语法:
verifier /onecheck /rc 33 36 /driver myDriver1.sys
当驱动程序接近生产就绪状态并且正在经历最终的验证和测试的阶段时,此模式非常有用。
最大程度提高代码路径:
在执行 IHV 的现有测试框架期间,可以启用 DV 驱动程序隔离规则。 这有助于最大程度地提高受测驱动程序执行的代码路径。
通过命令行进行设备基础测试是用于执行驱动程序的典型代码路径的良好测试基线。 开发人员可以使用 DV 驱动程序隔离检查启用这些测试,以最大程度地提高尽早捕获驱动程序隔离冲突的可能性。
开发模式:禁用强制执行
出于开发目的,可以通过在状态分离开发模式下运行状态分离来关闭状态分离的强制执行。 这样,便可以开发、测试和运行不符合要求的和驱动程序(例如工厂测试应用)。
在开发模式中:
- MainOS 分区是可写的。
HKLM\SYSTEM
和HKLM\SOFTWARE
中的更改会在重新启动时保留。- Windows 将继续监视可能违反状态分离规则的活动。
可以通过将功能 STATESEPARATION_ON
替换为 STATESEPARATION_DEVMODE
,在映像创建时配置开发模式。
下表详细说明了每种模式之间的差异。
状态分离模式 | 不可变文件系统访问 | 不可变注册表访问 |
---|---|---|
强制模式 | 不允许写入 | 注册表更改不会在重新启动时保留 |
ETW 和调试器输出中会出现冲突警告 | ETW 和调试器输出中会出现冲突警告 | |
开发模式 | 允许读取/写入 | 注册表更改会在重新启动时保留 |
ETW 和调试器输出中会出现冲突警告 | ETW 和调试器输出中会出现冲突警告 |