Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(五)

子文档五:PKI 签名模块(pki.c)

pki.c 是 libwdi 中最复杂的模块之一,它负责创建自签名证书、安装证书到系统存储、生成 CAT 文件以及对其进行 Authenticode 签名。该模块依赖 Windows CryptoAPI 和 MSSign32,实现了完整的代码签名流程。

自签名证书的创建与安装

CreateSelfSignedCert 函数执行以下步骤:

  1. 获取密钥容器 :调用 CryptAcquireContext 创建一个名为 libwdi key container 的密钥容器(若已存在则打开),并生成一个 4096 位的 RSA 密钥对(CryptGenKey,AT_SIGNATURE)。
  2. 设置主题名称 :通过 CertStrToNameA 将主题字符串(如 CN=USB\VID_1234&PID_5678 (libwdi autogenerated))编码为 ASN.1 格式。
  3. 配置证书扩展 :
    • 增强密钥用法(EKU) :设置为代码签名(1.3.6.1.5.5.7.3.3),且标记为关键(fCritical=TRUE),确保证书只能用于代码签名。
    • 主题备用名称(SAN) :添加一个 RFC822 名称 Created by libwdi (http://libwdi.akeo.ie),用于标识。
    • 证书策略 :包含 CPS(Certification Practice Statement)指针 http://libwdi-cps.akeo.ie,使证书在 Windows 中显示"颁发者声明"按钮。
  4. 创建证书 :调用 CertCreateSelfSignCertificate,指定签名算法(Windows 7 使用 SHA-1,Windows 8+ 使用 SHA-256),有效期至 2029 年。
  5. 安装证书 :AddCertToStore 将证书添加到本地机器的 Root 和 TrustedPublisher 存储区,使得系统信任该证书签署的任何驱动。

CAT 文件生成

CreateCat 函数创建目录文件(.cat),其流程:

  1. 调用 CryptCATOpen 创建 CAT 文件(CRYPTCAT_OPEN_CREATENEW)。
  2. 添加全局属性:HWID(硬件 ID,如 USB\VID_1234&PID_5678)和 OS(操作系统版本列表,如 7_X86,7_X64,...)。
  3. 对于文件列表中的每个文件(由 CAT 模板提供),计算其 SHA-1 哈希(CryptCATAdminCalcHashFromFileHandle)。
  4. 调用 CryptCATPutMemberInfo 将文件哈希作为成员添加到 CAT 中,指定成员类型(PE 文件或 INF/CAB 文件)。
  5. 添加成员属性:File(文件名)和 OSAttr(操作系统属性,如 2:5.1,2:5.2,...)。
  6. 调用 CryptCATPersistStore 将 CAT 数据写入磁盘。

签名与密钥销毁

SelfSignFile 函数对 CAT 文件进行 Authenticode 签名:

  1. 调用 SignerSignEx,传入自签名证书句柄,指定 SHA-256 算法,添加 Authenticode 扩展属性(SPC_SP_OPUS_INFO_OBJID 和 SPC_STATEMENT_TYPE_OBJID)。
  2. 签名成功后,调用 DeletePrivateKey:通过 CryptAcquireCertificatePrivateKey 获取私钥句柄,然后调用 CryptAcquireContext 配合 CRYPT_DELETEKEYSET 删除密钥容器。
  3. 删除私钥至关重要:防止恶意攻击者利用残留的私钥对其他文件进行签名,从而绕过安全措施。

证书安装到受信任发布者

AddCertToTrustedPublisher 函数用于将外部证书(如嵌入的 .cer 文件)安装到 TrustedPublisher 存储区。它首先检查证书是否已存在,若不存在且用户确认(disable_warning 为 FALSE 时弹出警告对话框),则添加证书。该函数在 wdi_install_trusted_certificate API 中被调用。

依赖的 DLL

pki.c 动态加载 Crypt32.dll、MSSign32.dll 和 WinTrust.dll,通过 GetProcAddress 获取所需函数指针,避免静态链接这些系统库,增加兼容性。

错误处理

所有 PKI 操作均检查返回值,失败时调用 winpki_error_str 将错误码转换为可读字符串,并通过 wdi_warn/wdi_err 输出日志。


相关推荐
A1Book2 天前
Win11 开机项治理方案:四层扫描、分级决策与可回滚落地
windows
FY@-@2 天前
VMware ESXi 7.0 实验全记录:嵌套安装 → 网络配置 → 存储 → Windows 10 虚拟机部署
运维·网络·windows·云计算
数据狐(Datafox)2 天前
一文读懂京东商品详情API:返回字段解读与 JSON 样例
java·开发语言·数据库·windows·json
富洋金锐2 天前
使用nssm创建windows服务
windows
tryCbest2 天前
宝塔 Windows 面板安装使用
windows·宝塔·服务面板
政在远航2 天前
看不见的后门:Windows入侵深度排查思路|2026应急响应实操
windows·windows 入侵·windows 入侵排查·漏洞加固
Keith Guo2 天前
Event Task Matrix(ETM)工作机制
驱动开发·esp32·etm
林兴洋2 天前
使用nssm创建windows服务
windows·后端
桌管小李2 天前
终端安全一体化实战:AI 审计、行为分析、零信任、防拍照与远程运维全解析
运维·服务器·网络·人工智能·windows·安全·macos
我命由我123452 天前
Python 开发 - Python 项目部署(Windows 与 Linux)
java·linux·windows·后端·python·java-ee·python3.11