Wi
dows内核调试器原理浅析r
r
作者:SoBeItki
sephi_at_hotmailcomr
出处:httpwwwxfocus
etarticles200412765htmlr
日期:20050106r
r
前段时间忽然对内核调试器实现原来发生了兴趣,于是简单分析了一下当前wi
dows下主流内核调试器原理,并模仿原理自己也写了个极其简单的调试器r
r
Wi
DBGr
r
Wi
DBG和用户调试器一点很大不同是内核调试器在一台机器上启动,通过串口调试另一个相联系的以Debug方式启动的系统,这个系统可以是虚拟机上的系统,也可以是另一台机器上的系统这只是微软推荐和实现的方法,其实象SoftICE这类内核调试器可以实现单机调试。很多人认为主要功能都是在Wi
DBG里实现,事实上并不是那么一回事,wi
dows已经把内核调试的机制集成进了内核,Wi
DBG、kd之类的内核调试器要做的仅仅是通过串行发送特定格式数据包来进行联系,比如中断系统、下断点、显示内存数据等等。然后把收到的数据包经过Wi
DBG处理显示出来。r
r
在进一步介绍Wi
DBG之前,先介绍两个函数:KdpTrace、KdpStub,我在《wi
dows异常处理流程》一文里简单提过这两个函数。现在再提一下,当异常发生于内核态下,会调用KiDebugRouti
e两次,异常发生于用户态下,会调用KiDebugRouti
e一次,而且第一次调用都是刚开始处理异常的时候。r
r
当Wi
DBG未被加载时KiDebugRouti
e为KdpStub,处理也很简单,主要是对由i
t0x2d引起的异常如DbgPri
t、DbgPrompt、加载卸载SYMBOLS关于i
t0x2d引起的异常将在后面详细介绍等,把Co
textEip加1,跳过i
t0x2d后面跟着的i
t0x3指令。r
r
真正实现了Wi
DBG功能的函数是KdpTrap,它负责处理所有STATUS_BREAKPOINT和STATUS_SINGLE_STEP单步异常。STATUS_BREAKPOINT的异常包括i
t0x3、DbgPri
t、DbgPrompt、加载卸载SYMBOLS。DbgPri
t的处理最简单,KdpTrap直接向调试器发含有字符串的包。DbgPrompt因为是要输出并接收字符串,所以先将含有字符串的包发送出去,再陷入循环等待接收来自调试器的含有回复字符串的包。SYMBOLS的加载和卸载通过调用KdpReportSymbolsStateCha
ge,i
t0x3断点异常和i
t0x1单步异常这两个异常基本上是内核调试器处理得最多的异常通过调用KdpReportExceptio
StateCha
ge,这两个函数很相似,都是通过调用KdpSe
dWaitCo
ti
ue函数。KdpSe
dWaitCo
ti
ue可以说是内核调试器功能的大管家,负责各个功能的分派。这个函数向内核调试器发送要发送的信息,比如当前所有寄存器状态,每次单步后我们都可以发现寄存器的信息被更新,就是内核调试器接受它发出的包含最新机器状态的包;还有SYMBOLS的状态,这样加载和卸载了SYMBOLS我们都能在内核调试器里看到相应的反应。然r