Windows驱动签名实践

驱动文件由zadig/libwdi生成

需要先安装Visual Studio 2022, Windows SDK, Windows Driver Kit (WDK), 参考: 下载 Windows 驱动程序工具包 (WDK)

inf2cat, signtool 等工具建议在 Developer Command Prompt for VS 2022中操作

  1. 生成自签证书
1
New-SelfSignedCertificate -Subject "CN=<Name>" -CertStoreLocation "Cert:\CurrentUser\My" -KeyAlgorithm RSA -KeyLength 4096 -HashAlgorithm SHA256 -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(10) -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.17={text}email=<email>") -KeyUsage None

关于 New-SelfSignedCertificate,参考:New-SelfSignedCertificate (PKI) | Microsoft Learn

其中 2.5.29.37 是增强型密钥用法(enhanced key usage), 1.3.6.1.5.5.7.3.3 是代码签名(code signing). 2.5.29.17 是使用者可选名称(subjectAltName). New-SelfSignedCertificate 命令有一个 -DNSName 参数似乎不支持email这样细粒度级别的配置.

另外命令还支持 -Type 参数, 指定为 CodeSigningCert 时生成出来的证书, “增强型密钥用法”前面会有一个叹号, 不确定是为什么所以最后改成TextExt这种模式了.

-KeyUsage None 可以避免证书附带上默认用途.

  1. 导出为PFX文件
1
2
$password = ConvertTo-SecureString -String "<redacted>" -Force -AsPlainText
Export-PfxCertificate -Cert "Cert:\CurrentUser\My\<Thumbprint>" -FilePath "<filename>" -Password $password
  1. 生成catalog文件
1
inf2cat /v /driver:<dir> /os:XP_X86,XP_X64,Vista_X86,Vista_X64,7_X86,7_X64

注意,这里的/os 参考: Inf2Cat - Windows drivers | Microsoft Learn

一份更全的列表可以参考: Inf2Cat 工具

这个os字符串是根据zadig/libwdi生成出来的catalog文件的安全目录OSAttr属性推出来的,OSAttr列表参见:List of Microsoft Windows versions - Wikipedia

libwdi源码中使用的是 7_X86,7_X64,8_X86,8_X64,8_ARM,10_X86,10_X64,10_ARM 但用这个字符串签出来的文件不太对, 不是很确定原因.

若要使用_ARM参数, 需要保证安装了对应架构的构建工具, 否则inf2cat会报错参数错误.

  1. 对catalog文件签名
1
signtool sign /fd SHA256 /f "<pfx file path>" /p <redacted> /t http://timestamp.digicert.com <cat file path>
  1. 导出一个CA证书cer文件随安装包发行
1
Export-Certificate -Cert "Cert:\CurrentUser\My\<Thumbprint>" -FilePath "<filename>"
  1. 打包,制作自动安装脚本 install-drivers.bat

因为certutil需要用admin权限, 加一段自动提权UAC

1
2
3
4
5
6
7
8
9
10
11
@echo off
:: Check for admin rights
NET SESSION >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
echo Requesting Administrator privileges...
powershell -Command "Start-Process cmd -Verb RunAs -ArgumentList '/c %~fnx0'"
exit
)

C:\Windows\System32\certutil.exe -addstore -enterprise -f -v root "%~dp0\DriverSigner.cer"
C:\Windows\System32\InfDefaultInstall.exe "%~dp0\drivers.inf"