Windows内核编程
上QQ阅读APP看书,第一时间看更新

2.5 简单的跟踪

要怎样才能确切地知道DriverEntry和Unload例程已经执行了呢?让我们来向其中加入一些简单的跟踪。驱动程序可以使用KdPrint宏来输出printf风格的文本,这些文本可以用内核调试器和其他工具查看。KdPrint是一个只在调试构建时编译进结果代码的宏,它调用了底层的DbgPrint内核API。

下面是更新后的DriverEntry和Unload例程的代码,其中用KdPrint跟踪了代码的执行:

000

注意调用KdPrint时的两个括号。这是必需的,因为KdPrint是一个宏,又像printf那样能够接受任意数目的参数。宏无法处理可变数目的参数,所以这里利用了编译器的一个小技巧,从而调用了真正的DbgPrint函数。

加上了跟踪语句之后,我们再来加载驱动程序并看看这些跟踪信息。在第4章里我们会用到内核调试器,但现在先用一个叫作DebugView的Sysinternals工具来查看信息。不过在运行DebugView之前,还有一些准备工作要做。首先,从Windows Vista开始,只有在注册表中设置了某个值之后,DbgPrint才会真正产生输出信息。这需要向注册表的HKLM\SYSTEM\CurrentControlSet\Control\Session Manager下面增加一个叫作Debug Print Filter的键(这个键通常不存在)。在这个新建的键里,增加一个叫作DEFAULTDWORD值(不是键本身的那个默认值)并置其值为8(理论上说,只要位3置位的任意值均可)。图2-6显示了RegEdit里的设置。不过还是需要重启系统才能让这个设置生效。

000

图2-6 注册表中的Debug Print Filter键

应用了这个设置之后,在权限提升的情况下运行DebugView(DbgView.exe)。在其Options菜单里选中Capture Kernel(或者按快捷键Ctrl+K)。不要选中Capture Win32和Capture Global Win32,这样来自各个进程的输出不会搞乱显示。

如果还没有构建驱动程序,请构建。从提升了权限的命令窗口再次加载驱动程序(sc start sample)。我们会看到如图2-7所示的DebugView输出内容。如果卸载驱动程序,就能看到另一条信息出现,这是因为Unload例程被调用了。(第三行来自另外一个驱动程序,与Sample驱动程序无关。)

000

图2-7 Sysinternals DebugView输出