引用注明>> 【作者:张佩】【原文:www.yiiyee.cn/blog】
前几天某个早晨,大概5点钟我就醒在床上,怎么也睡不着。想到手头还有一个驱动需要debug,就立刻发现了人生目标一样地爬了起来。匆匆洗漱完毕后,打开电脑,打开VS2012驱动项目。先把代码逻辑仔细的看过一遍,有了一点小发现,改了几行代码。按下F7开始编译。
编译结束后,很惊讶地发现“输出”试图中报了一个错误,是driver package工程报错。这里要说一下相关的背景,通过VS2012的工程向导创建的驱动项目(solution)总是包含两个工程(project):一个是驱动工程,所有的源代码都在此,编译后生成驱动文件(一般是.sys文件);一个是driver package工程,无源码,它的编译过程乃针对inf文件和sys文件进行处理,产生一个可安装的驱动包(driver package)。
头一次遇到package工程失败的情况,会是什么原因呢?
1>------ 已启动生成: 项目: Test Package, 配置: Win7 Debug x64 ------ 1> ....................... 1> Signability test failed. 1> 1> Errors: 1> 22.9.7: DriverVer set to incorrect date (postdated DriverVer not allowed) in \Test.inf. The current date (UTC) is 1/7/2014. 1> 1> Warnings: 1> None 1>x64\Win7Debug\inf2catOutput.log : Inf2Cat error -2: "Inf2Cat, signability test failed." Double click to see the tool output. ========== 生成: 成功 0 个,失败 1 个,最新 1 个,跳过 0 个 ==========
Package工程
Package工程在生成可安装驱动安装包的过程中,会调用三个工具,为相关的文件进行数字签名:Stampinf.exe/ testsign.exe /inf2cat.exe。下面对这三个工具作一一介绍。
时间戳工具(Stampinf)
Stampinf.exe用来为inf文件生成时间戳和版本号。这个时间戳对应于inf文件中的DriverVer值,下面是一个示例:
[version] DriverVer=01/10/2014,1.0.0.0 ; time stamp(时间戳)+ version(版本号)
StampInf.exe工具可以在WDK安装包中找到,针对不同的硬件平台有不同的版本,x86版本的相对路径是:bin\x86\staminf.exe。我们可以在控制台环境中运行此工具,以观察它的使用方法。
C:\Users\mozhang>stampinf.exe #输出内容有所删减和整理 USAGE: stampinf -f filename [-s section] [-d <xx/yy/zzzz> | *] -a architecture -n [-c catalogfile] [-v | *] [-k nnnnn] [-u nnnnn] [-i path]
-f:指定inf文件的路径
-a:指定硬件平台,可使用x86或AMD64二者之一。如果你指定的inf文件中含有关键字$ARCH$,stampinf会自动把它们都替换成指定的x86或AMD64值。这种情况下,inf文件中的“NT$ARCH$”最终会变成”NTx86“或”NTAMD64“。如果inf文件中包含了关键字$ARCH$,但没有指定-a参数,stampinf会自动删除所有的关键字。这种情况下,inf文件中的“NT$ARCH$”最终会变成”NT“。
-d:指定具体的时间戳。如果指定为“*”,Stampinf会以当前时间来设置。这个选项可选,默认使用当前时间。
-v:指定版本信息,比如可以指定为:1.0.0.0。但如果指定的值为“*”,则表示使用“时.分.秒.毫秒”的形式来设置版本号。这个选项可选,默认使用“时.分.秒.毫秒”方式。
-k/-u:这两个值用来指定KMDF和UMDF的版本,可用指定的值替换inf文件中KMDF的关键字$KMDFVERSION$和$KMDFCOINSTALLERVERSION$,以及UMDF的关键字$UMDFVERSION$和$UMDFCOINSTALLERVERSION$。
下面是一个例子,我在控制台中执行命令为cy001.inf文件打时间戳:
C:\Users\mozhang>"stampinf.exe" -f "c:\cy001.inf" -d "*" -v "1.0.0.0" Stamping c:\cy001.inf [Version] section with DriverVer=01/10/2014,1.0.0.0
打开cy001.inf文件查看:
DriverVer=01/10/2014,1.0.0.0
如果把-v的参数换成”*”:
C:\Users\mozhang>"stampinf.exe" -f "c:\cy001.inf" -d "*" -v "*" Stamping c:\cy001.inf [Version] section with DriverVer=01/10/2014,11.24.18.11
打开cy001.inf文件查看:
DriverVer=01/10/2014,11.24.18.11
打开Package工程的属性页,查看stampinf这一项的属性,能看到它默认使用的参数如下:
-k “1.11” -d ”*” –a “amd64” –u “1.11.0” –v “*”
它使用当前时间设置时间戳,用时.分.秒.毫秒的格式设置版本号。
TestSign
关于签名工具TestSign.exe,我曾在介绍64Signer的时候有过介绍。它使用指定的数字证书,给指定的镜像文件进行数字签名。参考64Signer的说明文档。
Inf2Cat
此工具用来生成cat文件。VS2012先把驱动安装有关的所以文件都拷贝到一个目录中,然后调用inf2cat.exe来生成cat文件。这些必须被拷贝的文件包括:.inf文件,.sys文件,其它文件包括WDF框架的co-installer文件等。Inf文件所在的位置代表了driver package的位置。
为了试验,我把test.inf、test.sys、WdfCoInstaller01011.dll这三个文件手动拷贝到E:\Test目录下面,然后调用inf2cat命令:
C:\Users\mozhang>Inf2Cat.exe driver:"E:\test" /os:"7_x86"
.......................
Signability test complete.
Errors:
None
Warnings:
None
Catalog generation complete.
E:\test\test.cat
参数中,/Driver:path指定了driver package的目录,亦即inf文件所在目录;/OS:指定了目标系统。最后生成了test.cat文件。
可以把Inf2Cat的工作分成三步:分析inf文件,收集信息;验证驱动包,包括验证时间戳、验证文件完整性;生成cat文件。
验证时间戳就是把inf文件DriverVer值和当前时间进行比较,看是否匹配。我在文章开始遇到的错误,正是时间戳验证失败导致的。验证文件完整就是确保inf文件中涉及的所有文件都能在Driver Package目录中找到。比如用WDF框架编写的驱动,Driver Package中必须有WDF的co-installer文件。
时间戳验证
回到开头的错误,再把重要的错误信息列举如下:
DriverVer set to incorrect date (postdated DriverVer not allowed) in \test.inf. The current date (UTC) is 1/7/2014. Inf2Cat error -2: "Inf2Cat, signability test failed."
是inf2cat工具在执行的时候发生了错误,错误原因看上去是时间戳验证失败了。第一行告诉我,从DriverVer中拿到的时间不对,当前的UTC时间是1/7/2014。我特地看了一下电脑的当前时间并截了一幅图。我的当前时间是北京时间1月8号上午7点,和inf文件中DriverVer的值相同:
北京时间要比UTC标准时间提前8个小时,所以北京时间的8号凌晨7点钟,对应UTC时间的7号晚上11点。所以Inf2Cat使用的UTC时间正好和Inf文件中的Local时间差一天。这正是时间戳验证失败的原因所在(可以推测,inf2cat是只验证日期而不验证时分秒的,这才使得我只有在凌晨8点以前编译驱动,才有机会“碰巧”遇到这个错误)。
解决问题
解决问题的方法非常简单,只要让Inf2Cat验证的时候使用local时间就可以了。打开package工程的属性,在inf2cat工具的属性中进行设置。
531,923 total views, 33 views today
张佩老师您好,我根据解决方法设置了以后还是会出先这个错误,您能否帮忙分析一下可能是那边出错了,谢谢。
那说明不是这个问题引起的。你可以把问题mail联系我。
Son of a gun, this is so hefplul!
这个问题刚刚碰到了……今晚第一次把US和虚拟机配置好,然后刚好是凌晨一点钟,然后就”偶遇”这个问题了,o>_<o 哪怕是按照别人说的一步一步的配置好这一系列的任务,然后还遇到了问题,最后按照老师的方法解决了,真的很兴奋!感觉驱动编程的大门正在为我打开
欢喜你的欢喜,恭喜你!
您好,我用VS2013按照MSDN的步骤一步一步做的,生成驱动用InstDrv能够加载但是不能启动,用winDBG查看调试信息,不管是通过重启,还是工具驱动都不能启动,驱动程序是MSDN上的那个HolleWord,完全复制,逐步设置编译生成的!
Unloaded modules:
fffff880`03ad5000 fffff880`03add000 KmdfHelloWorld.sys
Timestamp: unavailable (00000000)
Checksum: 00000000
ImageSize: 00008000
这是失败的提示信息
在入口函数里面设置断点,看为什么返回失败了。
半夜搞程序的伤不起啊,刚还好好的,突然就有问题了..
方法实测好用
实测好用
不错,冷静的分析+详细的记录+分享,赞!
好牛逼啊,这个方法果然好用,我是00:56的时候编译的,佩服!另外我买了你的竹林蹊径 哈哈
Is there such a thing as an attempted suicide survivor day? I think there should be. For the people that tried, but did not actually end their life?