To SuperMouse,
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)
|