如何使用windbg在驱动加载时下断
2012-10-17 13:10
561 查看
首先说说应用层的调试吧.当我们在调试windows可执行程序的时候,通过将PE文件头中的ImageBase和AddressOfEntryPoint相加,从而得出第一条指令的地址.针对这个地址下断之后目标程序就中断在了了入口处.但是这个方法在驱动调试的时候却有心无力.这是因为可执行程序都是首先被加载到各自的私有地址空间,他们不会有地址冲突.然而驱动程序运行在内核里面,所有的驱动程序共享一个地址空间.所以需要重新设定基地址.
在VMware客户机里,安装驱动后,敲下 net start TestDevice之后,系统理所应当的被断下来了.
假如我们调试的驱动并不是以DriverEntry作为入口函数,bu针对符号下断也就没有了意义.但是我们可以使用模块加偏移的方式下断.假设TestDriver的入口函数的偏移为0xFB4.直接bu TestDriver+0xFB4即可.
dv命令只显示了参数,还是用esp靠谱一点,至少给出了我们返回地址0x80582377.接下来该ln命令登场了
返回地址位于nt!IopLoadDriver+0x66d处,直接反汇编一下吧,看看再哪里调用了DriverEntry
0x80582377处是nt!IopLoadDriver+0x66d.前面的call指令占了3个字节.所以我们下断在nt!IopLoadDriver+0x66a就能在进入DriverEntry之前中断下来.
这里我们要设置一下Load module事件为break, sxe -set enable sxd - set disable sxi -set ignore sxn -set output
加载我们的驱动吧,在load module的时候系统中断
然后我们找到模块基址,并在入口处下断即可.
解析一下pe文件
然后bp TestDriver+0xFB4即可让系统中断在我们驱动程序的入口处.
1.利用bu命令下延迟断点.
之前提到过,bu可以针对符号下断点.这里是用bu下延迟断点的意义在于即使目标驱动没有被加载,windbg也允许我们针对符号设置断点.当新加载驱动程序后,windbg就会检查驱动程序中是否包含了设置了延迟断点的函数.如果找到了,就把断点替换为地址形式,然后再设置断点.笔者的测试驱动程序为TestDriver.sys.0: kd> .sympath Symbol search path is: E:\Symbol\windbg Symbols;E:\Code\Vc_code\Ring3Ring0\Driver\objchk_wxp_x86\i386 Expanded Symbol search path is: e:\symbol\windbg symbols;e:\code\vc_code\ring3ring0\driver\objchk_wxp_x86\i386 0: kd> .srcpath Source search path is: E:\Code\Vc_code\Ring3Ring0\Driver
在VMware客户机里,安装驱动后,敲下 net start TestDevice之后,系统理所应当的被断下来了.
Breakpoint 0 hit TestDriver!DriverEntry: f8c4ee10 8bff mov edi,edi
假如我们调试的驱动并不是以DriverEntry作为入口函数,bu针对符号下断也就没有了意义.但是我们可以使用模块加偏移的方式下断.假设TestDriver的入口函数的偏移为0xFB4.直接bu TestDriver+0xFB4即可.
2.在系统调用DriverEntry之前下断.
现在来看看我们的程序,中断在了DriverEntry之中.我们能不能在进入DriverEntry之前下断.首先我们dv和esp看一下当前的栈1: kd> dv pDriverObject = 0x81f346e8 pRegistryPath = 0x81865000 "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\TestDevice" status = 0n8 1: kd> r esp esp=f8af9c88 1: kd> dd f8af9c88 L8 f8af9c88 80582377 81f346e8 81865000 00000000 f8af9c98 b2926cf4 00000000 00000018 00000000
dv命令只显示了参数,还是用esp靠谱一点,至少给出了我们返回地址0x80582377.接下来该ln命令登场了
1: kd> ln 80582377 (80581d0a) nt!IopLoadDriver+0x66d | (80582442) nt!IopLoadUnloadDriver
返回地址位于nt!IopLoadDriver+0x66d处,直接反汇编一下吧,看看再哪里调用了DriverEntry
0: kd> bu TestDriver!DriverEntry 0: kd> bl 0 eu 0001 (0001) (TestDriver!DriverEntry) 1: kd> u nt!IopLoadDriver+0x660 nt!IopLoadDriver+0x660: 8058236a 8b7d80 mov edi,dword ptr [ebp-80h] 8058236d ffb570ffffff push dword ptr [ebp-90h] 80582373 57 push edi 80582374 ff572c call dword ptr [edi+2Ch] 80582377 3bc3 cmp eax,ebx 80582379 8b8d68ffffff mov ecx,dword ptr [ebp-98h] 8058237f 8945ac mov dword ptr [ebp-54h],eax 80582382 8901 mov dword ptr [ecx],eax
0x80582377处是nt!IopLoadDriver+0x66d.前面的call指令占了3个字节.所以我们下断在nt!IopLoadDriver+0x66a就能在进入DriverEntry之前中断下来.
3.使用事件异常
先来看看系统中提供了哪些事件异常吧.直接sx下1: kd> sx ct - Create thread - ignore et - Exit thread - ignore cpr - Create process - ignore epr - Exit process - ignore ld - Load module - output ud - Unload module - ignore ser - System error - ignore ibp - Initial breakpoint - break iml - Initial module load - ignore out - Debuggee output - output
这里我们要设置一下Load module事件为break, sxe -set enable sxd - set disable sxi -set ignore sxn -set output
1: kd> sxe ld 1: kd> sx ct - Create thread - ignore et - Exit thread - ignore cpr - Create process - ignore epr - Exit process - ignore ld - Load module - break ud - Unload module - ignore ser - System error - ignore ibp - Initial breakpoint - break iml - Initial module load - ignore out - Debuggee output - output
加载我们的驱动吧,在load module的时候系统中断
然后我们找到模块基址,并在入口处下断即可.
1: kd> lm n start end module name [...] f8b9c000 f8b9d100 WMILIB WMILIB.SYS f8b9e000 f8b9f580 intelide intelide.sys f8ba0000 f8ba1700 dmload dmload.sys f8ba4000 f8ba5280 vmmouse vmmouse.sys f8bb0000 f8bb1100 swenum swenum.sys f8bb6000 f8bb7280 USBD USBD.SYS f8bba000 f8bbbf00 Fs_Rec Fs_Rec.SYS f8bbe000 f8bbf080 Beep Beep.SYS f8bc2000 f8bc3080 mnmdd mnmdd.SYS f8bc6000 f8bc7080 RDPCDD RDPCDD.sys f8bf8000 f8bf9a80 ParVdm ParVdm.SYS f8bfc000 f8bfde00 vmmemctl vmmemctl.sys f8c4e000 f8c4f300 TestDriver TestDriver.sys [...]
解析一下pe文件
1: kd> !dh -a f8c4e000 File Type: EXECUTABLE IMAGE FILE HEADER VALUES 14C machine (i386) 6 number of sections 5077C38E time date stamp Fri Oct 12 15:15:26 2012 0 file pointer to symbol table 0 number of symbols E0 size of optional header 102 characteristics Executable 32 bit word machine OPTIONAL HEADER VALUES 10B magic # 9.00 linker version C00 size of code 280 size of initialized data 0 size of uninitialized data FB4 address of entry point 480 base of code ----- new ----- [...]
然后bp TestDriver+0xFB4即可让系统中断在我们驱动程序的入口处.
相关文章推荐
- 如何使用windbg在驱动加载时下断
- 如何使用windbg在驱动加载时下断
- 如何使用windbg在驱动加载时下断
- Linux如何加载raid驱动以便使用RAID安装系统
- 如何使用java代码加载指定包下面的所有类
- 如何使用DLL函数动态加载-静态加载
- 使用HttpWebRequest请求远端服务器时如何加载SSL证书
- cocos2dx 3.10如何把cocosstudio中的散图合图并且能在程序中加载plist使用
- Android如何使用ImageView加载网络图片
- 如何使用Gson工具类,以及使用listview加载相应的解析项
- 如何Vue-cli开始使用在Vue.js项目中启动TDD(测试驱动开发)
- 如何使用Openlayers 3加载谷歌离线地图
- 【swift基础】08在swift如何使用闭包、懒加载、和自定义类
- laravel 中使用tinker 验证驱动加载是否成功
- 驱动中使用加载回调来监控进程加载 或者DLL加载 驱动加载
- JDBC系列-<驱动加载原理全面解析>-<JDBC层次结构和基本构成>-存储过程 CallableStatement(创建和使用)
- clover如何使用UEFI引导和EFI驱动选择
- 如何去掉IE控件的垂直滚动条(使用QAxWidget加载IE控件)
- 用eclipse连接MySQL的一点心得体会,如何加载数据库驱动
- 如何使用FormPanel的SetValues方法加载EntityFramework实体类数据到FormPanel上