windbg查看当前IRQL

这是个老生常谈的问题,对于XP没有什么好办法,对于Server 2003开始的系统,可以使用!irql
命令:
kd> !irql 1
Debugger saved IRQL for processor 0x1 -- 0 (LOW_LEVEL)

 

有一个名为 KiOldIrql 的全局变量,在 KeFreezeExecution 把 IRQL 提升到 HIGH_LEVEL 的时候会把原先的 IRQL 保存在这个变量里。

 

Good point!但是这个变量一直没有导出,很长一段时间内也没有“回放”到公开符号中,所以对于早期的XP版本,要用这个变量也不太容易。首先很多人不知道这个变量,知道了也不知道它的地址。

新版本的公开符号文件中包含这个符号了,比如XP的SP3也如此。

91810 0x5  0x124618 0x124618  KiOldIrql  7 91811 91812

因此对于这些新版本,是可以观察这个全局变量,但是对于多处理器来说,还是有问题,全局变量只有一个,处理器有多个,因此全局变量记录的只是作为发起这次break的那个CPU的原本IRQL。   

为了根本解决这个问题,在Svr 2003时,在KPRCB结构中加了一个字段DebuggerSavedIRQL来专门保存旧的IRQL。并增加了一个!irql命令。如果针对SVR2K3之前的目标执行时会看到:

kd> !irql
nt!_KPRCB.DebuggerSavedIRQL not found, error : 0x4.
Saved IRQL not available prior to Windows Server 2003

归纳一下,对于XP SP1或者更老的目标,那么可用的方法在0和1之间,看是否有私有符号,或者是否有耐心通过看汇编,找到KiOldIrql的地址。

对于Svr2K3开始的目标,可以用2-3种方法,看KiOldIrql变量,观察_KPRCB.DebuggerSavedIRQL和执行!irql(后两种等价)。比如,下面是针对Win7目标的执行结果:

kd> dd nt!kioldirql l1
831717c4  0000001c

kd> dt _KPRCB 8313cd20 -y Debug
nt!_KPRCB
   +0x4c4 DebuggerSavedIRQL : 0x1c ''

 kd> !irql
Debugger saved IRQL for processor 0x0 -- 28 (CLOCK2_LEVEL)

 

posted @ 2012-01-26 21:56  robinh00d  阅读(2185)  评论(0编辑  收藏  举报