警告
强制执行应用控制时,如果 COM () 对象的注册 GUID 与系统在运行时计算的 GUID 不匹配,则 .NET 不会加载某些组件对象模型。 发生这种情况时,用户会看到一个常规的 COM 加载错误对话框,但不会将事件或其他信息记录到系统。 有关详细信息,请参阅应用控制管理员提示 & 已知问题:.NET 不会加载 GUID 不匹配的 COM 对象。
(用高级语言(如 C#) )编写的 .NET 应用编译为中间语言 (IL) 。 IL 是一种可在任何作系统或体系结构上支持的紧凑代码格式。 大多数 .NET 应用使用在多个环境中支持的 API,只需运行 .NET 运行时。 IL 需要编译为本机代码才能在 CPU 上执行,例如 Arm64 或 x64。 在具有应用控制用户模式策略的设备上将 IL 编译为本机映像 (NI) 时,它首先检查原始 IL 文件是否通过当前应用控制策略。 如果是这样,.NET 会在生成的 NI 文件上设置一个 NTFS 扩展属性 (EA) ,以便应用控件也知道信任它。 当 .NET 应用运行时,应用控件会在 NI 文件上看到 EA 并允许它。
在 NI 文件上设置的 EA 仅适用于当前处于活动状态的应用控制策略。 如果更新了某个活动应用控制策略或应用了新策略,则 NI 上的 EA 文件将失效。 应用下次运行时,应用控制将阻止 NI 文件。 .NET 正常处理块并回退到原始 IL 代码。 如果 IL 仍通过最新的应用控制策略,则应用运行没有任何功能问题。 由于 IL 现在是在运行时编译的,因此你可能会注意到应用的性能略有下降。 当 .NET 必须回退到 IL 时,.NET 还会安排一个进程在下一个维护时段运行,以重新生成所有 NI 文件,从而为通过最新应用控制策略的所有代码重新建立应用控制 EA。
在某些情况下,如果 NI 文件被阻止,你可能会在 CodeIntegrity -作事件日志中看到“误报”阻止事件,如应用控制管理员提示 & 已知问题中所述。
为了缓解在应用控制 EA 无效或缺失时导致的任何性能降低:
- 避免经常更新应用控制策略。
-
ngen update
在) 的所有计算机体系结构上运行 (,以强制 .NET 在对应用控制策略应用更改后立即重新生成所有 NI 文件。 - 将应用程序迁移到 .NET Core (.NET 6 或更高版本) 并启用 本机 AOT。
应用控制和 .NET 动态代码安全性强化
安全研究人员发现,允许应用从外部源加载库或在运行时生成新代码的一些 .NET 功能可用于规避应用控制。 为了解决此潜在漏洞,应用控制包括一个名为 “动态代码安全性 ”的选项,该选项可与 .NET 配合使用,以验证在运行时加载的代码。
启用动态代码安全性后,应用控制策略将应用于 .NET 从外部或远程源(如 Internet 或网络共享)加载的库。 它还检测 .NET 生成的到磁盘的代码中的篡改,并阻止加载被篡改的代码。 此外,动态代码安全性不支持的某些 .NET 加载功能(包括加载使用 System.Reflection.Emit 生成的未签名程序集)始终会被阻止。
通常,当动态代码被阻止时,其父进程会停止或崩溃。 若要使用 ASP.NET 防止出现这种情况,可以仅针对部署预编译动态代码。 请参阅 ASP.NET 预编译概述中的“仅限部署的预编译”。
重要提示
.NET 动态代码安全性仅在 Windows 11 24H2 及更高版本以及Windows Server 2025 及更高版本在审核模式下工作。 Windows 10或早期版本的 Windows 11 和 Windows Server 上没有针对动态代码安全性的审核模式。 如果任何应用控制策略在这些早期版本上设置了选项 19 Enabled:Dynamic Code Security ,则即使策略处于审核模式,也会 启用并强制实施 动态代码安全强化。 在将应用控制策略部署到生产环境时,始终全面测试应用并使用安全部署做法。
动态代码安全性可缓解潜在的攻击技术,通常称为“二阶”攻击。 这意味着攻击者有权访问系统并能够运行代码。 第二次攻击可能是试图获得持久性或进一步模糊攻击者的活动。 尽管动态代码安全性非常重要,建议使用,但Microsoft还建议在运行 Windows 11 24H2 及更高版本(Windows Server 2025 及更高版本)的系统上以审核模式测试策略,然后再强制实施它。
动态代码安全性阻止的代码使用 CodeIntegrity -作 事件日志中的事件 ID 3114 进行记录。 除了使用其中一个不支持的 .NET 功能(如 System.Reflection.Emit)加载的代码外,还可以创建规则以允许使用事件中的信息阻止的动态代码。 请参阅 使用应用控件向导从应用控件事件日志创建规则。
注意
.NET 尝试使用两种不同的方法来运行动态生成的代码。 如果应用控制策略阻止第一种方法,.NET 将尝试第二种方法。 两次尝试中的每一次都会引发不同的 3114 事件。 当 3114 事件单独发生时,可以放心地忽略为“误报”,因为它仅涵盖 .NET 首次尝试运行代码。 仅当在同一代码的毫秒内看到两个 3114 事件背靠背时,才会指示要查看的实际问题。
若要启用动态代码安全性,请使用应用控制向导、set-ruleoption PowerShell cmdlet 或将以下内容<Rules>
添加到应用控制策略 XML 部分,将选项 19 - Enabled:Dynamic Code Security 添加到应用控制策略:
<Rule>
<Option>Enabled:Dynamic Code Security</Option>
</Rule>