Windbg内核调试下调试应用层

来源:互联网 发布:滴滴架构 知乎 编辑:程序博客网 时间:2024/05/29 11:11

用户态上下文有额外典型的两种,Session会话上下文和Process进程上下文,由于用户态进程访问的都是虚拟内存,要想调试用户态代码,就必须切换到相应的会话上下文和进程上下文,进行相关的设置。要注意的一件事是,上下文的切换,只对当前的调试空间有效,也就是说,当F5或者g之后,绝大部分的切换都将被重置。以下:



1.会话上下文(SessionContext),关联的是登录会话。比如:


1: kd> !session
Sessions on machine: 2
Valid Sessions: 0 1
Error in reading current session


由于第一次使用!session,没有保存过session上下文,所以有Error in reading current session出现。


1: kd> .cache forcedecodeptes


Max cache size is       : 1048576 bytes (0x400 KB) 
Total memory in cache   : 0 bytes (0 KB) 
Number of regions cached: 0
0 full reads broken into 0 partial reads
    counts: 0 cached/0 uncached, 0.00% cached
    bytes : 0 cached/0 uncached, 0.00% cached
** Transition PTEs are implicitly decoded
** Virtual addresses are translated to physical addresses before access
** Prototype PTEs are implicitly decoded


上面的.cache forcedecodeptes命令强制刷新所有缓存的虚拟内存,将虚拟内存转换为物理内存。
如果出现了涉及虚拟内存的上下文切换,比如.process,.thread,!session等,每次都必须进行强制转换,否则将访问无效的虚拟内存。后面在进程上下文里也会有提及。而另一个同等作用的forcedecodeuser将用户层虚拟内存无效化,强制转换。


1: kd> !session /s 1
Sessions on machine: 2
Implicit process is now 85827750
Using session 1


设置当前的会话为Session1,在Vista之后,由于会话隔离机制的存在,默认存在2个Session。


1: kd> !sprocess
Dumping Session 1


_MM_SESSION_SPACE 8f8d9000
_MMSESSION        8f8d9d00


PROCESS 85827750  SessionId: 1  Cid: 019c    Peb: 7ffdd000  ParentCid: 018c
    DirBase: 2fed6040  ObjectTable: 94210fc0  HandleCount: 162.
    Image: csrss.exe


PROCESS 88fa7d40  SessionId: 1  Cid: 01b8    Peb: 7ffd3000  ParentCid: 018c
    DirBase: 2fed60c0  ObjectTable: 9434af18  HandleCount: 113.
    Image: winlogon.exe


//...


你也可以直接使用1: kd> !sprocess 1 0来查看会话中的进程信息。




2.进程上下文(Process Context),关联的是进程信息。


对于进程来说,访问的内存都是虚拟内存,进程使用页目录将虚拟内存翻译成物理内存,这样,要想调试进程,就必须将上下文切换到目标进程的空间中,这个可以使用.process来办到。对于安腾Itanium处理器,一个进程可以有多个页目录,这种情况可以使用.cache forcedecodeuser加上.context (DirBase)进行地址切换。


下面是一个示例:


首先枚举出当前的进程,可以使用!sprocess或者!process 0 0或者!for_each_process,比如:


0: kd> !for_each_process
PROCESS 83bffa20  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 85601c50  HandleCount: 449.
    Image: System
//...
PROCESS 88fb0c38  SessionId: 1  Cid: 0de8    Peb: 7ffd8000  ParentCid: 0648
    DirBase: 2fed62c0  ObjectTable: 9dafa868  HandleCount:  59.
    Image: notepad.exe


然后可以使用.process进行上下文切换:


0: kd> !process -1 0
PROCESS 83bffa20  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 85601c50  HandleCount: 449.
    Image: System


查看当前的进程空间,在System。


1: kd> .process /r /p 88fb0c38
Implicit process is now 88fb0c38
.cache forcedecodeuser done
Loading User Symbols
.........................


/r结合/p参数强制加载用户态模块的符号文件。起到的作用是.reload /user。
/p参数和.cache forcedecodeuser是一样的作用,如果不指定/p,那就需要手动设置.cache。
这个命令在分析Dump的时候很有用,因为Dump中无法使用下面的/i参数进行断点设置。


0: kd> .process /i 88fb0c38
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.


.process加上/i参数进行侵入式切换,这样才能在目标进程空间进行断点等操作。当目标进程获得CPU时间时,切换就会完成。


0: kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
82684394 cc              int     3


0: kd> !process -1 0
PROCESS 88fb0c38  SessionId: 1  Cid: 0de8    Peb: 7ffd8000  ParentCid: 0648
    DirBase: 2fed62c0  ObjectTable: 9dafa868  HandleCount:  59.
    Image: notepad.exe


切换完成。注意此时如果使用.context看到的结果是空,如果不使用/i参数,看到的.context就是DirBase的值2fed62c0。


0: kd> .reload /user
Loading User Symbols
.........................
0: kd> lmu


然后可以设置断点,比如:


0: kd> bp /p @$proc ntdll!RtlAllocateHeap "!process -1 0;g"
0: kd> g
PROCESS 88fb0c38  SessionId: 1  Cid: 0de8    Peb: 7ffd8000  ParentCid: 0648
    DirBase: 2fed62c0  ObjectTable: 9dafa868  HandleCount:  59.
    Image: notepad.exe


这里使用伪寄存器$proc来指定当前的进程,当目标进程有函数调用时就会中断下来,不过因为刷新的原因,时间可能要略微久点...

文章来自: http://www.newkernel.com/1/post/2009/05/081.html
0 0
原创粉丝点击