一个老设备的驱动装不上,提醒里只写“拦截”,不写是谁拦的。而常见原因有三类:代码签名、内存完整性、或者一条策略。三类的处理方式完全不同,猜错方向的人往往会去关杀毒软件,而杀毒软件本来就没参与这件事。
先看提醒里写的是哪一句
提醒:Windows 无法验证此设备所需的驱动程序的数字签名 提醒:已阻止加载需要此设备的驱动程序,因为它与内存完整性不兼容 提醒:此操作已被应用控制策略阻止
三句分别对应三层。第一句是签名问题,64 位系统只接受带有效签名的内核驱动,十几年前的老硬件很多根本没有签名版本。第二句是内存完整性(内核隔离里的那一项)拦的,驱动虽然有签名,但它的内存使用方式不符合要求,或者它已经在微软的易受攻击驱动阻止列表里。第三句不是驱动自己的问题,而是机器上多了一条管控设置,公司发的笔记本和某些安全软件的驱动防护,多半出自这两处。
两层好分,第三层要看日志
签名和内存完整性两层在设备管理器的属性页里就能看出区别:前者在设备状态里显示为代码 52,后者会在事件日志里留下 CodeIntegrity 的记录。而策略拦截得先看两个地方:一是“应用和浏览器控制”里有没有应用控制或智能应用控制的策略,二是提醒原文里有没有“组织”两个字——家用机器上自己配置不出“组织”,那句话多半来自安全软件而不是系统。第三方产品的驱动拦截不会写进系统日志,它的记录只在自己那里,这本身就是一个区分方法。
三行命令可以把判断依据拉出来:
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace 'root\Microsoft\Windows\DeviceGuard' | Select-Object VirtualizationBasedSecurityStatus, SecurityServicesRunning
Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -MaxEvents 200 | Where-Object {$_.LevelDisplayName -eq '错误'} | Select-Object TimeCreated, Id, Message
Get-Content 'C:\Windows\INF\setupapi.dev.log' -Tail 40
第一行看内存完整性到底有没有在运行;第二行把代码完整性层报过的错列出来,能直接看到被挡的是哪个驱动文件;第三行是驱动安装自己的过程日志,里面能找到安装到哪一步中断的。三行都是只读。
三类各自的出路
签名那一类几乎没有变通的余地:只能找厂商带签名的版本,或者放弃这块硬件。把系统改成测试模式确实能装上去,但那是把内核入口完全打开,不应当作为长期方案,临时为了取一次数据可以,完事就要改回来。
内存完整性那一类还有取舍空间:先确认能不能更新驱动,不行的时候在“设备安全性”里关掉内存完整性确实能装,但这等于为了一个老硬件拆掉内核层的防护。如果这台机器还要用,建议先把“是哪个设备、是不是非用不可”想清楚,再决定关不关。这一类也是第 165 篇里那个蓝屏问题的另一面:同一个开关,一面体现在装不上,一面体现在装了会蓝。
策略那一类的出路不在驱动上:公司发的机器就去找管理员,家用机器则先看安全软件的驱动防护或设备控制选项。三类分开看就能看出一个共同点:大部分“驱动被拦”不是防护过严,而是硬件已经超出了当前内核能安全接受的范围。