Windbg内核调试之三: 调试驱动
这次我们通过一个实际调试驱动的例子,来逐步体会Windbg在内核调试中的作用.
由于条件所限,大多数情况下,很多人都是用VMware+Windbg调试内核(VMware的确是个好东西).但这样的调试需要占用大量的系统资源,对于和我一样急性子的朋友来说这是不可接受的:).利用双机调试就可以让你一边喝咖啡一边轻松的看结果,而不至于郁闷的等待每次长达数分钟的系统响应.有关双机调试的基本设置,请参考:http://www.cnblogs.com/Sonic2007/archive/2008/03/20/1114807.html
本次调试驱动所构建的环境如下:
host computer: WinXP+Windbg
Target computer: Vista SP1
driver object: sys
connect setting: 1394数据线
说明: 1.1394卡在很多机器上都已经没有了,Vista也取消了1394的数据连接协议(调试还是可以的),但不可否认的是利用1394数据线连接调试要比COM口和USB速率快很多(为什么好用的东西却得不到支持!
).2.本次调试的driver是公司开发的某个软件的驱动程序,拿来尝试在Vista SP1下track.由于涉及到商业机密,本驱动源代码不便公开.3.Vista SP1就没什么好说的了,前些天才发布,MS又一个失败的典型.
OK,Let's go!
该驱动是一个类型sr.sys(MS的System Restore驱动)的Filter Driver,属于文件系统过滤驱动,加载在文件系统驱动上层,由Filter Manager负责与用户层和底层通信.连接到目标机后,按下Ctrl+break中断当前状态.(注:你也可以进入到explorer之后再中断,为了了解驱动加载时的进入点,以及系统启动时内核的装态,我们中断到这里)
Microsoft (R) Windows Debugger Version 6.6.0007.5
Copyright (c) Microsoft Corporation. All rights reserved.
Using 1394 for debugging
Opened \\.\DBG1394_INSTANCE01
Waiting to reconnect...
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: D:\symbolslocal; D:\IR\SystemOK\Restore\Driver\objchk_wlh_x86\i386
Executable search path is:
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntkrnlmp.exe -
Windows Vista Kernel Version 6000 MP (1 procs) Free x86 compatible
Built by: 6000.16584.x86fre.vista_gdr.071023-1545
Kernel base = 0x81800000 PsLoadedModuleList = 0x81908ad0
System Uptime: not available
WARNING: Whitespace at start of path element
WARNING: Whitespace at start of path element
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*
* You are seeing this message because you pressed either
* CTRL+C (if you run kd.exe) or,
* CTRL+BREAK (if you run WinDBG),
* on your debugger machine's keyboard.
*
* THIS IS NOT A BUG OR A SYSTEM CRASH
*
* If you did not intend to break into the debugger, press the "g" key, then
* press the "Enter" key now. This message might immediately reappear. If it
* does, press "g" and "Enter" again.
*
*******************************************************************************
nt!RtlpBreakWithStatusInstruction:
818355e8 cc int 3
然后,在Command line里键入lm,查看当前系统加载的模块和驱动(会发现我们的driver列在其中):
kd> lm
start end module name
80404000 80412000 PCIIDEX (deferred)
80412000 80419000 intelide (deferred)
80419000 80429000 mountmgr (deferred)
80429000 80438000 volmgr (deferred)
80438000 8045d000 pci (deferred)
8045d000 80465000 msisadrv (deferred)
80465000 8046e000 WMILIB (deferred)
8046e000 804b1000 acpi (deferred)
804b1000 804be000 WDFLDR (deferred)
804be000 80539000 Wdf01000 (deferred)
80539000 8061a000 CI (deferred)
8061a000 80655000 CLFS (deferred)
80655000 8065d000 BOOTVID (pdb symbols)
8065d000 80666000 PSHED (deferred)
80666000 806c6000 mcupdate_GenuineIntel (deferred)
806c6000 806ce000 kdcom (deferred)
81800000 81b95000 nt (pdb symbols)
81b95000 81bc9000 hal (pdb symbols)
81c06000 81c0e000 spldr (deferred)
81c0e000 81c44000 volsnap (deferred)
81c44000 81cae000 ksecdd (deferred)
81cae000 81db6000 Ntfs (deferred)
81db6000 81def000 NETIO (deferred)
81def000 81e1a000 msrpc (deferred)
81e1a000 81f1e000 ndis (deferred)
81f1e000 81f270c0 PxHelp20 (deferred)
81f28000 81f4f000 sys32v (private pdb symbols)
81f4f000 81f5f000 fileinfo (deferred)
81f5f000 81f90000 fltmgr (deferred)
81f90000 81fae000 ataport (deferred)
81fae000 81fb6000 atapi (deferred)
81fb6000 82000000 volmgrx (deferred)
8234f000 82358000 crcdisk (deferred)
82358000 82368000 agp440 (deferred)
82368000 82389000 CLASSPNP (deferred)
82389000 8239a000 disk (deferred)
8239a000 823bd000 fvevol (deferred)
823bd000 823e2000 ecache (deferred)
823e2000 823f1000 mup (deferred)
823f1000 82400000 partmgr (deferred)
注: 若符号文件没有加载成功,Windbg会提示响应的符号找不到,不过一般Windbg会自己寻找符号文件路径.实在找不到时,就包含
srv*c:\symbols*http://msdl.microsoft.com/download/symbols, 然后reload一下(!reload).
另外,键入lm t n, 我们可以查看更为详细的模块及驱动信息.
然后,键入!thread和Kp,查看当前的线程详细信息和堆栈(或者Alt+6也可以看stack).注意当前thread的ID:
kd> !thread
THREAD 84254ae8 Cid 0004.0008 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
Owning Process 84254d90 Image: System
Wait Start TickCount 0 Ticks: 1 (0:00:00:00.015)
Context Switch Count 1
UserTime 00:00:00.0000
KernelTime 00:00:00.0015
Win32 Start Address nt!Phase1Initialization (0x819433ae)
Stack Init 81c06000 Current 81c05db8 Base 81c06000 Limit 81c03000 Call 0
Priority 31 BasePriority 8 PriorityDecrement 0
ChildEBP RetAddr Args to Child
81c05af0 818aa92c 00000001 81867999 0002625a nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0])
81c05af8 81867999 0002625a 00000000 00000001 nt!KdCheckForDebugBreak+0x22 (FPO: [0,0,0])
81c05b18 81836cfd 81928100 000000d1 81c05b9c nt!KeUpdateRunTime+0x270
81c05b18 81ba4130 81928100 000000d1 81c05b9c nt!KeUpdateSystemTime+0xed (FPO: [0,2] TrapFrame @ 81c05b28)
81c05b9c 81ba3fd0 81bb28a0 8181dced 81c05bc8 hal!XmGetCodeByte+0x30 (FPO: [Non-Fpo])
81c05bac 81ba40c5 81bb28a0 0000c000 00001da4 hal!XmEmulateStream+0x88 (FPO: [Non-Fpo])
81c05bc8 81ba374d 00000010 81c05c0c 8181dced hal!XmEmulateInterrupt+0x80 (FPO: [Non-Fpo])
81c05bdc 81ba0a1c 00000010 81c05c0c 00000000 hal!x86BiosExecuteInterruptShadowed+0x43 (FPO: [Non-Fpo])
81c05bf8 81ba0a5b 00000010 81c05c0c 00000000 hal!x86BiosCall+0x22 (FPO: [Non-Fpo])
81c05c2c 80656697 80806ae0 8080f438 00000000 hal!HalpBiosDisplayReset+0x25 (FPO: [Non-Fpo])
81c05c58 81b2cd6d 00000001 81b0ab01 80806ae0 BOOTVID!VidInitialize+0x135 (FPO: [Non-Fpo])
81c05c7c 81b3f098 00000001 80806ae0 00000007 nt!InbvDriverInitialize+0x81
81c05d74 819433bb 81c05dc0 819afbad 80806ae0 nt!Phase1InitializationDiscard+0xd0
81c05d7c 819afbad 80806ae0 81c0e680 00000000 nt!Phase1Initialization+0xd
81c05dc0 8189a346 819433ae 80806ae0 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
kd> kp
ChildEBP RetAddr
81c05af0 818aa92c nt!RtlpBreakWithStatusInstruction
81c05af8 81867999 nt!KdCheckForDebugBreak+0x22
81c05b18 81836cfd nt!KeUpdateRunTime+0x270
81c05b18 81ba4130 nt!KeUpdateSystemTime+0xed
81c05b9c 81ba3fd0 hal!XmGetCodeByte+0x30
81c05bac 81ba40c5 hal!XmEmulateStream+0x88
81c05bc8 81ba374d hal!XmEmulateInterrupt+0x80
81c05bdc 81ba0a1c hal!x86BiosExecuteInterruptShadowed+0x43
81c05bf8 81ba0a5b hal!x86BiosCall+0x22
81c05c2c 80656697 hal!HalpBiosDisplayReset+0x25
81c05c58 81b2cd6d BOOTVID!VidInitialize+0x135
81c05c7c 81b3f098 nt!InbvDriverInitialize+0x81
81c05d74 819433bb nt!Phase1InitializationDiscard+0xd0
81c05d7c 819afbad nt!Phase1Initialization+0xd
81c05dc0 8189a346 nt!PspSystemThreadStartup+0x9d
00000000 00000000 nt!KiThreadStartup+0x16
键入!process [PID] 0, 查到当前进程:
kd> !process 0004.0008 0
PROCESS 84254d90 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 00122000 ObjectTable: 830001d0 HandleCount: 1.
Image: System
VadRoot 00000000 Vads 0 Clone 0 Private 0. Modified 0. Locked 0.
DeviceMap 00000000
Token 83003830
ElapsedTime 00:00:00.015
UserTime 00:00:00.000
KernelTime 00:00:00.000
QuotaPoolUsage[PagedPool] 0
QuotaPoolUsage[NonPagedPool] 0
Working Set Sizes (now,min,max) (4, 0, 0) (16KB, 0KB, 0KB)
PeakWorkingSetSize 0
VirtualSize 0 Mb
PeakVirtualSize 0 Mb
PageFaultCount 0
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 0
THREAD 84254ae8 Cid 0004.0008 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
在lm命令列出的信息中,start是模块的起始地址,通过键入"u 驱动起始地址",我们可以反汇编出它的代码:
kd> u 81f28000
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x0):
81f28000 4d dec ebp
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x1):
81f28001 5a pop edx
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x2):
81f28002 90 nop
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x3):
81f28003 0003 add byte ptr [ebx],al
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x5):
81f28005 0000 add byte ptr [eax],al
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0x7):
81f28007 000400 add byte ptr [eax+eax],al
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0xa):
81f2800a 0000 add byte ptr [eax],al
sys32v!SysAllocatePostCopyWorkItem <PERF> (sys32v+0xc):
81f2800c ff ???
逐步查找(enter),最终我们可以发现driver的入口点.这个过程其实是非常慢的,因为系统内核在加载驱动实际代码的过程中进行了N多次调用.如果我们本身有驱动的代码,也可以直接包含源代码路径,通过在实际代码中设置断点,让Windbg自己中断到相应的代码位置(在实际调试内核的过程中,这几乎是不可能的,因为你不会得到Windows内核或某个驱动程序的源代码.Linux系列的某些driver们又另当别论).这里为了方便,我包含了sys的源代码,增加断点直接走到DriverEntry例程:
kd> u 81f42780
sys32v!DriverEntry [隐藏了address]:
81f42780 8bff mov edi,edi
81f42782 55 push ebp
81f42783 8bec mov ebp,esp
81f42785 51 push ecx
81f42786 c745fc010000c0 mov dword ptr [ebp-4],0C0000001h
81f4278d a1749cf481 mov eax,dword ptr [sys32v!SysDbgFlags (81f49c74)]
81f42792 83e004 and eax,4
81f42795 7424 je sys32v!DriverEntry+0x3b (81f427bb)
其中显示的汇编代码,是内核调用驱动是进行的操作,其实也和实际代码相对应.
在driver代码中,如果要查看当前参数值,用dv命令:
kd> dv
DriverObject = 0x84663730
RegistryPath = 0x8084b560
status = 8
dontload = 0
另外,用"dt 参数名"可以看某个参数的当前值.
kd> dt DriverObject
Local var @ 0x81c05af8 Type _DRIVER_OBJECT*
0x84663730
+0x000 Type : 4
+0x002 Size : 168
+0x004 DeviceObject : (null)
+0x008 Flags : 2
+0x00c DriverStart : 0x81f28000
+0x010 DriverSize : 0x27000
+0x014 DriverSection : 0x84230a68
+0x018 DriverExtension : 0x846637d8 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\FileSystem\Sys"
+0x024 HardwareDatabase : 0x81af6ed8 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0x81f4a005 sys32v!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : (null)
+0x038 MajorFunction : [28] 0x8189a5c1 nt!IopInvalidDeviceRequest+0
这样,我们就可以通过上述的这些命令,逐步分析一个驱动程序在加载和执行过程中的情况。另外,Windbg还有众多内核调试命令,如!irp可以查看一个对象的数据结构,!devobj可以查看设备对象等,在今后的操作系统内核学习过程中会不断用到这些命令。
从上面的操作过程我们可以看出,利用Windbg调试驱动程序,或者说进行内核调试,是非常方便的。如果我们对Windows内核有一定的了解,同时拥有一定汇编语言的功底,就可以有Windbg进行简单的系统排障(比如系统加载是出现蓝屏,或是某个系统模块出现问题)、驱动学习等。同时,这个过程也可以让我们更深入的理解操作系统原理。另外,Windbg也可以进行系统服务(service)的调试,这就是User mode的调试过程了。
Windbg内核调试之三: 调试驱动的更多相关文章
- Windbg内核调试之四: Dump文件分析
Dump 文件分析很大程度上就是分析蓝屏产生的原因.这种系统级的错误算是Windows提示错误中比较严重的一种(更严重的还有启动黑屏等硬件或软件兼容性错误等等).说它是比较严重,是因为毕竟Window ...
- Windbg内核调试之一: Vista Boot Config设置
Windbg进行内核调试,需要一些基本的技巧和设置,在这个系列文章中,我将使用Windbg过程中所遇到的一些问题和经验记录下来,算是对Kernel调试的一个总结,同时也是学习Windows系统内核的另 ...
- 使用WinDbg内核调试[转]
Technorati 标签: windbg,内核调试 WINDOWS调试工具很强大,但是学习使用它们并不容易.特别对于驱动开发者使用的WinDbg和KD这两个内核调试器(CDB和NTSD是用户态调试器 ...
- windbg源码驱动调试 + 无源码驱动调试
windbg源码驱动调试 环境信息 虚拟机:win7 32位 windbg:6.12(版本不存在太大影响) 设置过程 windbg与虚拟机连接:链接 配置windbg 配置好双机调试后,点击win ...
- Windbg 内核态调试用户态程序然后下断点正确触发方法(亲自实现发现有效)
先开启真机内核态kernel调试 !process 0 0 svchost.exe 找到进程cid的地址 然后进入 .process /p fffffa8032be2870 然后 .process ...
- 在WinDbg里使用MEX调试扩展
简介 针对WinDbg的MEX调试扩展可以帮助您简化常见的调试器任务,并为调试器提供强大的文本筛选功能.此扩展被Microsoft支持工程师广泛用于解决流程应用程序的故障. 下载&安装 下载m ...
- 内核用户模式调试支持(Dbgk)
简介 将详细分析Windows调试的内核模式接口.希望读者对C和通用NT内核体系结构和语义有一些基本的了解.此外,这并不是介绍什么是调试或如何编写调试器.它可以作为经验丰富的调试器编写人员或好奇的安全 ...
- 无法在web服务器上启动调试。调试失败,因为没有启用集成windows身份验证
----注意:以管理员身份运行VS C#中ASP.NET Web应用程序编译时的错误:无法在web服务器上启动调试.调试失败,因为没有启用集成windows身份验证. 解决:打开IIS,在IIS里查看 ...
- Linux gcc/g++下GDB调试及其调试脚本的使用
GDB调试及其调试脚本的使用返回脚本百事通一.GDB调试 1.1. GDB 概述 GDB 是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB ...
随机推荐
- $用python玩点有趣的数据分析——一元线性回归分析实例
Refer:http://python.jobbole.com/81215/ 本文参考了博乐在线的这篇文章,在其基础上加了一些自己的理解.其原文是一篇英文的博客,讲的通俗易懂. 本文通过一个简单的例子 ...
- 06_Hadoop配置伪分布式模式详解
查看IP地址,设为手动模式: 配置hadoop用户sudo权限 su切换到root身份,配置vim /etc/sudoers文件,加入 hadoop ALL=(root)NOPASSWD:ALL ...
- [SCOI2013]火柴棍数字(背包)
题目 做饭 由于越高位越好,我们先得出能组成的最高位 \(f[i][j][k]\)表示从低到高位第\(i\)位,手里拿着\(j\)根火柴,第\(i\)位是否为\(0\)所需要的最少火柴 我们转移仅需得 ...
- 大话设计模式之PHP篇 - 单例模式
在编写PHP代码的时候,经常使用new关键字实例化一个对象,比如 <?php Class Database { } $db = new Database; 这是最常规的实例化操作方法,像数据库操 ...
- C语言中static的使用方法【转】
本文转自:http://blog.csdn.net/renren900207/article/details/21609649 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量 ...
- 音乐下载api
青檬音乐 http://tingapi.ting.baidu.com/v1/restserver/ting?from=android&version=5.6.5.6&format=js ...
- 堆栈在linux内存中的使用
链接:https://www.zhihu.com/question/57013926/answer/151506606 1.Linux 内核中使用 task_struct 作为进程描述符,该结构定义在 ...
- What's the difference between using “let” and “var” to declare a variable in JavaScript?
https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare ...
- android、ipone在文本框中输入文字的不同
1.android机会输入时会在键盘上先显示,你确定后再填充如文本框 2.ipone机是你输入时就直接填充到文本框,当你选择输入信息时,就会先把文本框的内容清空,在填充选择的文字,这时就会有个问题,如 ...
- JavaWeb -- JSP+JavaBean模式
SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. JSP+JavaBean模式适合开发业务 ...