如何验证WDM驱动镜像数字签名并拦截无指定签名的dll、exe文件下载?
WDM驱动层PE文件(dll、exe)数字签名验证实现方案
可直接使用的内核态签名校验相关函数
Windows内核提供了原生的签名校验API,无需自己实现加密校验逻辑:
IoCheckSignatureEx:内核模式专门用于校验PE镜像签名的函数,支持校验微软签名、特定发布者签名,直接返回校验状态和签名类型WinVerifyTrustEx:内核态可用的通用签名校验接口,指定WTD_CHOICE_FILE参数可直接对文件对象做完整签名链校验CryptCATAdminCalcHashFromFileHandle:计算文件哈希,用于匹配系统安全目录中的签名记录CryptCATAdminEnumCatalogFromHash:枚举对应文件哈希的安全目录上下文,用于提取目录签名信息CryptCATCatalogInfoFromContext:从目录上下文获取签名者、证书链、证书指纹等详细签名属性
具体实现步骤
- 下载文件时先写入临时内核缓存或临时文件,所有校验通过前不要写入目标落地路径
- 获取待校验文件的内核只读句柄,申请排他锁锁定文件,避免校验过程中文件被篡改
- 基础签名有效性校验,调用
IoCheckSignatureEx快速判断文件是否带有有效签名,示例调用代码:
NTSTATUS CheckPeSignature(PFILE_OBJECT FileObject) { NTSTATUS status; ULONG SignatureType; HANDLE FileHandle = NULL; status = ObOpenObjectByPointer(FileObject, OBJ_KERNEL_HANDLE, NULL, GENERIC_READ, NULL, KernelMode, &FileHandle); if (!NT_SUCCESS(status)) { return status; } status = IoCheckSignatureEx( FileHandle, NULL, IO_CHECK_SIGNATURE_PE, 0, &SignatureType, NULL, 0 ); ZwClose(FileHandle); // 校验失败直接返回拒绝状态 if (!NT_SUCCESS(status)) { return STATUS_ACCESS_DENIED; } return STATUS_SUCCESS; }
- 自定义指定签名校验:如果需要校验是否为你指定的发布者签名,调用
WinVerifyTrustEx获取签名的证书上下文,提取证书的SHA256指纹,和驱动中预置的信任指纹逐字节比对,比对不匹配直接判定校验失败 - 所有校验通过后解除文件锁,将临时文件移动到目标路径,放行下载流程;任意一步校验失败,直接终止下载,清理所有已下载的缓存/临时文件,返回拒绝状态
注意事项
- 内核态调用
CryptCAT系列API需要先初始化相关上下文,使用完必须释放资源,避免内核内存泄漏 - 所有校验逻辑必须在WDM驱动内部完成,不要信任任何用户态传递的签名校验结果,防止被恶意篡改
- 优先校验签名的证书指纹,不要仅校验签名者名称,避免伪造同名签名绕过校验
- 大文件可以分片计算哈希后再和签名中嵌入的哈希值比对,不需要一次性加载整个文件到内核内存,降低内存占用
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

