资讯动态

Windows驱动CAT文件:签名机制、inf2cat与代码52排查

发布时间:2026/10/1 3:41:29 来源:尧图企业网站定制
1. 先搞清楚cat文件在Windows驱动生态里到底管什么折腾 Windows 驱动程序的朋友大概率都见过 .cat 文件它躺在驱动包目录里体积不大名字常和 INF 对应但安装时一旦它出问题设备管理器就会甩出代码 52。CAT 文件是 Windows 驱动程序的目录文件本质上是把驱动包里的 INF、SYS、DLL 等文件的哈希值集中起来再用代码签名证书做一次签名。它解决的问题很直接让系统确认驱动包来自可信来源并且没有被替换或篡改。凡是给 Windows 做内核驱动、用户模式驱动、USB、蓝牙、串口、虚拟网卡驱动的开发者或者做企业驱动分发、测试签名的同学都绕不开它。下面我按实际项目里的流程把 cat 文件的内部结构、生成、签名、安装、排错摊开讲。1.1 从一次代码52说起cat文件不是驱动本体设备管理器里的代码 52 大家应该不陌生“Windows 无法验证此设备所需的驱动程序的数字签名。最近的硬件或软件更改安装了未签名或损坏的驱动程序。”很多人第一次看到这句话第一反应是去替换 SYS 文件或者重新安装 INF结果折腾半天还是黄叹号。问题往往不在 SYS 本身而在 CAT 文件。SYS 是驱动二进制INF 是安装说明书CAT 是签名目录。系统在安装驱动时会读取 INF 里的CatalogFilexxx.cat再用 CAT 里的哈希逐个比对驱动包中的文件。只要有一个文件对不上或者 CAT 本身签名无效系统就会拒绝加载内核驱动。这也是为什么你改了一行 INF却没有重新生成 CAT安装时照样报签名错误。我在一个 USB 转多串口项目里就踩过这个坑。当时为了改一个端口名直接在打包目录里编辑了 INF然后拿旧的 CAT 去安装。测试机上设备管理器立刻给了代码 52。后来用signtool verify /v /pa验证 CAT发现哈希不匹配。重新跑inf2cat再签名问题消失。这个经历说明一个道理CAT 不是装饰文件它是驱动包的“封条”一旦包内文件变化封条就作废。1.2 cat、inf、sys、pnputil的分工关系很多初学者容易把 CAT 和 INF、SYS 混在一起理解。可以这样类比INF 是菜谱SYS 是食材CAT 是密封包装上的防伪标签和配料哈希。Windows 在安装驱动时不是只看 SYS 能不能跑而是先看这个包有没有被可信签名覆盖。PNPUTIL 是 Windows 自带的驱动包管理工具它负责把 INF、SYS、CAT 作为一个整体加入 DriverStore。驱动包进入 DriverStore 后系统还会在C:\Windows\System32\DriverStore\FileRepository下留一份副本。后续设备加载驱动时用的是这个副本而不是你原始目录里的文件。文件/工具角色关键点INF安装描述文件指定硬件 ID、安装节、服务、CatalogFileSYS驱动二进制内核模式或用户模式驱动主体CAT目录签名文件保存包内文件哈希和签名供系统验证PNPUTIL驱动包管理工具添加、枚举、删除驱动包触发安装DriverStore系统驱动仓库存放已安装驱动包副本避免路径依赖这张表看起来简单但实际排错时非常有用。比如你明明替换了原始目录里的 SYS设备管理器却还是加载旧版本很可能是因为 DriverStore 里已经有旧包系统优先用了缓存。此时用pnputil /enum-drivers找到对应的 oemXX.inf再用pnputil /delete-driver oemXX.inf /uninstall /force清掉重新安装新包才能让新 CAT 和新 SYS 生效。注意删除驱动包可能影响正在使用的设备生产环境要谨慎操作。1.3 为什么微软用目录文件而不是直接签每个二进制有人会问为什么不直接给每个 SYS、DLL 签名还要多一个 CAT这背后有几个现实考虑。第一驱动包往往包含多个文件直接签每个文件会让签名操作变多证书和时间戳开销也更大。第二CAT 把多个文件的哈希集中在一个结构里验证时系统只需要校验 CAT 签名和文件哈希效率更高。第三CAT 可以在不修改二进制的情况下通过重新生成目录来覆盖新的文件组合适合驱动包版本管理和 WHQL 提交流程。第四CAT 让“文件完整性”和“发布者身份”绑定在一起系统不需要信任每个二进制里的签名只需要信任目录签名。从安全角度看这种方式也更稳妥。假设攻击者替换了包里的某个 DLL但没有能力重新签名 CAT系统在安装时就会发现哈希不匹配从而拒绝加载。对于内核驱动这一点尤其重要因为内核驱动拥有很高权限。微软从 64 位 Windows Vista 开始强化内核驱动签名要求后来在 Windows 10 及 Windows Server 版本上继续收紧。对开发者来说理解 CAT 的存在不是为了应付安装而是理解 Windows 驱动信任模型的基础。2. 拆开一个cat文件看内部格式、哈希与信任链2.1 cat文件本质是PKCS#7/CMS结构CAT 文件虽然扩展名特殊但内部并不是微软自创的二进制格式它通常是一个 PKCS#7 或 CMS 结构里面包含证书、签名值以及被签名的属性。你可以把它理解成“带签名的文件清单”。这个清单里会记录驱动包中各个文件的哈希常见算法包括 SHA1、SHA256。老驱动包可能还有 SHA1新驱动包基本以 SHA256 为主。CAT 里还会包含签名证书链以及时间戳信息。时间戳非常关键它证明签名行为发生在证书有效期内即使证书后来过期只要时间戳有效签名仍然可以被系统接受。如果你用文本编辑器打开 CAT只会看到乱码。正确方式是使用certutil -dump或signtool verify。例如certutil -dump MyDevice.cat这个命令会输出 CAT 中的证书信息、哈希算法、签名算法、时间戳等。注意不同 Windows SDK 版本里 certutil 输出格式略有差异但核心字段都能看到。对于排查签名问题最值得关注的是签名者证书、证书链是否完整、时间戳是否存在、文件哈希列表是否包含你正在安装的 INF 和 SYS。2.2 驱动包哈希怎么算进去CAT 里的哈希不是随便写的它由inf2cat工具根据 INF 文件和驱动目录内容生成。inf2cat会读取 INF 中的CatalogFile、DriverVer、SourceDisksFiles等条目然后扫描目录中的目标文件计算哈希并写入 CAT。也就是说CAT 和 INF 是强绑定的。你改了 INF 里的版本号、文件名、服务名都必须重新生成 CAT否则哈希列表和实际文件不一致。这里有一个很容易被忽略的细节inf2cat生成的 CAT 并不一定包含目录下所有文件而是根据 INF 中引用的文件列表来收集。假如你的驱动包里有多个架构的 SYS比如 x64、x86、arm64INF 需要正确声明inf2cat也需要指定对应的 OS 参数。常见命令如下inf2cat /driver:C:\Drv\MyDevice /os:10_X64,10_X86,Server2016_X64/os参数决定了生成哪些目标系统的目录信息。你给 Windows 10 x64 用却只生成了 Server2016_X64安装时就可能遇到不匹配。很多“为什么测试机能装客户机不能装”的问题最后都追到 OS 参数或架构不匹配上。2.3 信任链从证书到微软根到WHQLCAT 能不能被系统接受不只看签名本身还看证书链。签名证书通常由中间 CA 签发中间 CA 又由根证书签发。Windows 内置了一组受信任根证书如果证书链能追溯到这些根系统才会认为签名可信。对于普通企业代码签名证书证书链一般由公共 CA 提供。对于内核驱动尤其是需要 WHQL 的场景微软会参与签名形成“双签名”或“微软签名 厂商签名”的结构。WHQL 流程中开发者先用自有 EV 代码签名证书签署驱动包和 CAT再通过微软 Partner Center 提交。微软完成测试和签名后会返回一个带有微软签名的 CAT。这个 CAT 里既有厂商签名也有微软签名。Windows 在加载内核驱动时会检查微软签名链。这样即使厂商证书链在某些系统上不被完全信任微软签名也能提供背书。这里要提醒不要试图伪造或绕过这个信任链。正规流程虽然麻烦但它是驱动能够在客户机上稳定安装的前提。2.4 查看cat文件的几种方式实际工作中我常用三种方式检查 CAT。第一种是signtool verify /v /pa MyDevice.cat它适合快速判断签名是否有效、是否有时间戳。第二种是certutil -dump MyDevice.cat适合看证书链和哈希列表。第三种是 PowerShell 的Get-AuthenticodeSignature适合在脚本里批量检查。例如Get-AuthenticodeSignature .\MyDevice.cat | Format-List *这个命令会输出签名状态、签名者证书、时间戳等。如果状态是Valid说明当前系统信任该签名如果显示UnknownError或NotSigned就要继续查证书链或时间戳。还有一个容易被忽略的点验证 CAT 时要用/pa参数它表示按默认验证策略检查。只用/v有时会给出不完整的结论。signtool verify /v /pa MyDevice.cat如果你在 CI 里自动打包建议把这条命令作为质量门禁。CAT 验证不通过就不要发布。很多现场问题如果在打包阶段拦住能节省大量返工。3. 从零做一个可安装驱动包inf2cat、signtool与签名流程3.1 准备驱动工程和INF文件一个规范的驱动目录通常长这样MyDevice.inf、MyDevice.sys、MyDevice.cat可能还有 co-installer DLL、配置文件。INF 里必须有CatalogFileMyDevice.cat并且DriverVer要写清楚日期和版本。DriverVer不建议用未来日期也不建议长期不更新。它会影响驱动排名和安装选择。SourceDisksFiles要列出 SYS 等文件确保inf2cat能找到它们。我见过一些项目把 CAT 名称写成MyDevice.cat但 INF 里写CatalogFilemydevice.cat。Windows 文件系统不区分大小写通常能过但在某些打包工具或自动化脚本里可能出问题。建议大小写保持一致。另外驱动目录路径尽量用英文避免空格和特殊字符。虽然 Windows 支持中文路径但inf2cat、signtool在部分旧版本 SDK 下对中文路径处理不够稳容易报“找不到文件”。这是一个很实际的避坑点。3.2 inf2cat生成.cat生成 CAT 的命令不复杂关键是参数要对。假设驱动目录是C:\Drv\MyDevice目标系统是 Windows 10 x64 和 Windows 11 x64可以这样写inf2cat /driver:C:\Drv\MyDevice /os:10_X64,10_X86,Server2016_X64如果你的驱动只支持 x64就不要加 x86否则inf2cat可能因为缺少 x86 SYS 而报错。/os参数支持的值可以通过inf2cat /?查看。生成成功后目录里会出现MyDevice.cat。此时 CAT 还没有签名只是一个未签名目录。你可以用certutil -dump查看哈希列表确认 INF 和 SYS 都在里面。常见错误包括INF 中没有CatalogFileinf2cat会提示没有目录文件可生成INF 中引用的文件不存在会报错DriverVer格式不对也可能失败。遇到报错不要急着手工造 CAT先看inf2cat的输出日志。它会明确告诉你哪个文件缺失、哪个 OS 参数不支持。3.3 自签名证书与signtool命令测试阶段可以用自签名证书。PowerShell 里可以这样创建代码签名证书New-SelfSignedCertificate -Type CodeSigningCert -Subject CNContoso Test Driver -CertStoreLocation Cert:\CurrentUser\My -KeyUsage DigitalSignature -KeySpec Signature -NotAfter (Get-Date).AddYears(2)导出 PFX$cert Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Subject -eq CNContoso Test Driver} Export-PfxCertificate -Cert $cert -FilePath .\TestDrv.pfx -Password (ConvertTo-SecureString -String Test123! -Force -AsPlainText)然后在测试机受信任根里导入证书或者用测试签名模式。签名 CAT 的命令signtool sign /v /fd sha256 /f TestDrv.pfx /p Test123! /tr http://timestamp.digicert.com /td sha256 MyDevice.cat这里的/fd sha256指定文件摘要算法/td sha256指定时间戳摘要算法。时间戳服务器可以用公共时间戳服务也可以企业内网时间戳服务。注意自签名证书只适合测试机不要拿到生产环境分发。生产驱动应该使用正规代码签名证书内核驱动还需要走微软签名流程。3.4 测试签名与正式签名差异测试签名和正式签名的差异不只是证书不同。测试签名通常需要测试机开启测试签名模式系统会接受由测试根证书签发的驱动。正式签名则要求证书链被系统信任并且内核驱动要满足微软的签名策略。测试签名模式不适合日常办公机也不适合客户现场。它的价值在于开发调试阶段让驱动快速迭代。如果你在测试机上开启测试签名模式可以用管理员命令bcdedit /set testsigning on重启后系统右下角会出现测试模式水印。调试完成后建议关闭bcdedit /set testsigning off重要提醒生产环境不要依赖测试签名模式也不要用自签名证书给客户安装。这不仅会导致代码 52还可能带来合规风险。正规做法是申请 EV 代码签名证书走 WHQL 或微软硬件开发者计划。3.5 安装与验证pnputil和setupapi.dev.log安装驱动包时我推荐用 PNPUTIL而不是右键 INF 安装。命令如下pnputil /add-driver MyDevice.inf /install这个命令会把驱动包加入 DriverStore并尝试为匹配设备安装。查看已安装驱动包pnputil /enum-drivers如果安装失败第一时间看日志C:\Windows\INF\setupapi.dev.log这个日志会记录驱动包解析、CAT 验证、文件复制、服务创建等过程。搜索你的 INF 文件名或设备实例 ID能看到具体失败原因。常见关键字包括“签名验证失败”“哈希不匹配”“找不到文件”。这个日志比设备管理器给出的错误码详细得多是排查 CAT 问题的核心工具。4. 企业发布与WHQLcat文件怎么过微软签名4.1 HLK测试与提交前准备企业级驱动发布尤其涉及内核模式驱动通常要走 Windows Hardware Lab Kit 测试。HLK 会验证驱动在目标 Windows 版本上的稳定性、兼容性和签名要求。测试通过后生成 HLK 包再通过 Partner Center 提交。提交时需要提供驱动包、CAT、测试结果和签名信息。微软会重新签名 CAT并返回给开发者。这个返回的 CAT 包含微软签名适合分发到客户机。提交前要做的准备包括确保 INF 和 CAT 匹配确保DriverVer有效确保所有目标架构都包含确保没有测试签名残留确保驱动包不包含调试版本二进制。我见过一个项目把调试版 SYS 打包提交结果 HLK 测试通过但微软签名后客户机蓝屏。调试版和发布版行为可能不同提交前一定要用 Release 配置重新构建、重新生成 CAT、重新签名。4.2 双签名与时间戳双签名通常指 SHA1 和 SHA256 同时签名或者厂商签名加微软签名。对于新系统SHA256 是主流。时间戳的作用是延长签名有效期。没有时间戳的签名在证书过期后会失效有时间戳的签名只要时间戳在证书有效期内系统仍然认可。给 CAT 签名时务必加上时间戳参数。命令示例signtool sign /v /fd sha256 /f MyCert.pfx /p 密码 /tr http://timestamp.digicert.com /td sha256 MyDevice.cat如果是双签名可以先签 SHA1再签 SHA256或者按微软要求顺序执行。注意每次重新生成 CAT都要重新签名。CAT 内容变了旧签名自然失效。不要试图只签一次然后反复修改包内文件。4.3 目录文件更新与版本管理驱动包版本管理里CAT 应该和 INF、SYS 一起纳入版本控制。每次修改 INF 或 SYS都要重新生成 CAT 并签名。版本号建议遵循语义化版本或日期版本例如1.0.0.20250101。DriverVer的日期会影响驱动安装排名新版本通常要高于旧版本。如果版本号回退系统可能拒绝更新或者继续使用旧包。在 CI 里可以把inf2cat和signtool做成脚本。每次构建 Release 包时自动生成 CAT、自动签名、自动验证。签名证书私钥不要放在普通构建机上应该放在安全存储或硬件加密模块里通过受控签名服务调用。这样既方便自动化又降低私钥泄露风险。4.4 常见驳回原因WHQL 提交被驳回常见原因包括CAT 哈希不匹配、INF 语法错误、DriverVer 格式不对、缺少目标架构、测试签名未清理、证书链不完整、时间戳缺失。还有一类是驱动行为问题比如电源管理、PnP 状态、卸载重装失败。签名问题通常可以在提交前用signtool verify和inf2cat自检发现。建议在提交前跑一遍完整安装、卸载、重装流程确认设备管理器没有黄色感叹号日志里没有签名错误。5. 常见故障与排查cat文件引发的代码52、代码39、代码285.1 代码52签名验证失败的排查顺序代码 52 是 CAT 问题最典型的表现。排查顺序可以这样走先确认 INF 里的CatalogFile和实际 CAT 名称一致再用signtool verify /v /pa验证 CAT然后看证书链是否受信任再看时间戳是否存在最后看 DriverStore 里是否混入旧包。如果 CAT 未签名需要先签名再安装。如果 CAT 已签名但验证失败可能是证书链不完整或者系统不信任该根证书。测试环境可以导入测试根证书生产环境必须使用正规证书。还有一个隐蔽原因CAT 生成后有人又改了 INF 或 SYS但没有重新生成 CAT。此时 CAT 里的哈希和实际文件不一致系统会认为文件被篡改报代码 52。解决办法就是重新inf2cat重新signtool。5.2 代码39/28/31驱动文件与安装状态代码 39 通常表示驱动损坏或缺失代码 28 表示未安装驱动代码 31 表示 Windows 无法加载设备所需驱动。这些错误不全是 CAT 导致但 CAT 不匹配会让系统拒绝加载 SYS表现也可能类似。排查时先看设备管理器里的驱动版本和提供商。如果提供商是“Microsoft”或“未知”说明驱动没有正确安装。用pnputil /enum-drivers查看 DriverStore 里的包确认 oemXX.inf 对应的是你的驱动。必要时删除旧包重新添加。代码 31 还常见于 SYS 架构不对比如把 x86 驱动装到 x64 系统。CAT 里如果只包含 x86 文件系统也无法在 x64 上加载。生成 CAT 时指定正确的/os参数可以避免这类问题。5.3 时间戳证书过期导致验证失败时间戳证书过期是容易忽略的问题。如果签名时没有加时间戳证书过期后签名就会失效。加了时间戳签名在证书过期后仍然有效。验证方法是用signtool verify /v /pa查看时间戳信息。如果显示“无时间戳”且证书已过期就需要重新签名。重新签名时务必加/tr和/td参数。另外时间戳服务器不可用也会导致签名失败。CI 里如果依赖公共时间戳服务要做好重试和备用服务配置。签名失败时不要跳过时间戳否则后患无穷。5.4 多版本cat冲突与DriverStore缓存Windows 会缓存驱动包尤其是同硬件 ID 的多个版本。你安装了新版本但系统可能仍然使用旧版本。此时 CAT 没有问题问题在版本选择。可以查看C:\Windows\System32\DriverStore\FileRepository下的目录找到对应驱动包确认 CAT 和 SYS 版本。用pnputil /delete-driver删除旧包再重新安装。删除时加/uninstall可以卸载关联设备加/force可以强制删除。操作前确认没有其他设备依赖该包。5.5 常用排查命令速查表目的命令说明生成CATinf2cat /driver:... /os:...根据INF生成目录文件签名CATsigntool sign /v /fd sha256 /f ... /tr ... /td sha256 ...给CAT加签名和时间戳验证CATsigntool verify /v /pa MyDevice.cat检查签名是否有效查看CATcertutil -dump MyDevice.cat查看证书链和哈希安装驱动pnputil /add-driver MyDevice.inf /install加入DriverStore并安装枚举驱动pnputil /enum-drivers查看已安装包删除驱动pnputil /delete-driver oemXX.inf /uninstall /force清理旧包查看日志C:\Windows\INF\setupapi.dev.log安装失败详细日志这张表建议收藏。实际排错时按“验证 CAT、查日志、清缓存、重安装”的顺序走大部分问题都能定位。6. 实操心得与合规建议6.1 证书私钥怎么保管代码签名证书的私钥是驱动分发的核心资产。私钥泄露别人就可以用你的名义签名恶意驱动。生产环境的私钥不要放在源码仓库不要放在普通构建机不要通过聊天工具传输。建议使用硬件加密模块或受控签名服务。导出 PFX 时设置强密码PFX 文件存放在权限受控的目录。团队里尽量只有签名服务能接触私钥开发人员只提交构建产物。6.2 测试环境与生产环境隔离测试证书、测试签名模式、测试根证书都只应该在隔离的测试机上使用。不要把测试证书导入生产机的受信任根也不要把测试签名模式带到客户现场。生产驱动必须用正规证书签名内核驱动还要满足微软签名要求。测试环境和生产环境隔离可以避免大量签名信任问题。6.3 把cat签名放进CI流水线我现在的习惯是在 CI 里做三件事构建 Release 驱动运行inf2cat生成 CAT运行signtool签名并验证。验证不通过就让流水线失败。这样每次出包都有完整 CAT不会出现“忘了签名”或“改了 INF 没重新生成 CAT”的低级错误。如果签名服务支持 API可以把签名步骤做成受控调用避免私钥落到构建机上。6.4 不要碰的坑万能签名、盗版证书与手动改cat网上偶尔能看到一些“万能签名”“驱动签名工具”这类东西风险极高。它们可能使用泄露证书、伪造证书或篡改系统验证逻辑不仅会导致驱动无法在正规系统上安装还可能触犯法律。手动改 CAT 更不可取CAT 是签名结构改一个字节就会导致签名失效。正确做法永远是改 INF 或 SYS 后重新生成 CAT重新签名重新验证。我个人在实际项目里的体会是CAT 文件虽然小但它是 Windows 驱动信任链的入口。把它当成驱动包的一部分认真管理建立自动生成、自动签名、自动验证的流程比事后在客户现场排查代码 52 要省事得多。驱动开发本来就够复杂了别让一个小小 CAT 文件拖慢整个交付节奏。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑