Debug Driver Using WinDbg
1. Preface
前一段时间我们NB出货的一只软体碰到vista下的uac bug。最终的解决方法是使用一个keyboard filter driver去拦截oem scan code,然后再转给上层软体最终绕过了uac。在实现keyboard filter driver过程中我也遇到了几个问题,多亏WinDbg这个神兵利器才让我化险为夷。下面我将讲述debug keyboard filter driver的过程。
2. Begin Debug
首先要做的当然是配置WinDbg的环境,我在 Tracking ACPI/ASL Using WinDbg这篇文章中已经给出了详细的说明,请参考该文章即可。
但是有一点要提醒的是,别忘记了将driver的symbol file copy到WinDbg的symbol 路径中去噢J。参照DDK的说明我们需要做的是修改下面这个函数:
VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed )
该函数中拦截需要的scancode即可,我最初的想法是先在该函数中用DbgPrint抛些信息出来,我以前有用过DebugView调试过。我觉得这样可能会简单些。可是让我意外的是,DebugView中居然没有输出。试了无数遍,换了n台机器仍旧不行。没办法只有使用winDbg去断了。重启Debuggee,然后在Debugger按Ctrl+Break断下Debuggee然后输入下面的命令:
bu kbfiltr!DriverEntry
bu (“Breakpoint Unresolved”)命令将会延迟断点的设置时间,直到该模块被加载;也就是说WinDbg会探测kbfiltr的driver的入口函数DriverEntry被调用的时候,Debuggee将会被断下。然后go!稍等片刻WinDbg将会如下图1所示:打开watch window检查我们感兴趣的变量值。
接下来我要在KbFilter_ServiceCallback这个函数下个断点抓出scancode。输入bp kbfiltr!KbFilter_ServiceCallbackègo然后我们按下一个key,接下来就会发现KbFilter_ServiceCallback被断下了,然后我们查看一下具体scancode为什么呢?如下图2所示:
刚刚我按下一个’a’ watch window显示InputDataStart->MakeCode为0x1e InputDataEnd->MakeCode为0x00,而且InputDataStart地址为0x86471008, InputDataEnd地址为0x86471014 InputDataEnd – InputDataStart = 0(sizeof (KEYBOARD_ INPUT_DATA)为0x0c)所以目前只有一个key按下。如此我只要按下我们的oem key以后就可以拦截到相关的scancode,然后只要转给上层的AP就好了。下面的代码演示了如何将ctrl key转换成alt key做了这样的转换以后每次按下ctrl, OS都会傻傻的以为alt按下了J
VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed ) { PDEVICE_EXTENSION devExt; devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; DbgPrint(("Keyboard Filter Driver Sample - in the ServiceCallback function /n")); //left ctrl change it to left alt ++>> if(InputDataStart->MakeCode == 0x1d) { InputDataStart->MakeCode = 0x38; } //++<< (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)( devExt->UpperConnectData.ClassDeviceObject, InputDataStart, InputDataEnd, InputDataConsumed); }
该driver的制作和安装方法DDK中都已经给出了详细说明,参考即可我就不多说了。这些都是些debug的皮毛了,WinDbg还有一些如使用自动化脚
本调试,条件断点等强大的功能,我也没有仔细玩过L,以后有机会调试Driver的时候,我再来实践一把。
The end:/>
Peter