降低Irql违反文档规定却并未引起崩溃?
Windows内核调试
降低Irql违反文档规定却并未引起崩溃?
zyq8709
2011-06-22, 21:57 下午
请看一段驱动的代码
void f()
{
KIRQL o;
_asm int 3
KeRaiseIrql(APC_LEVEL,&o);
_asm int 3
KeLowerIrql(DISPATCH_LEVEL);
_asm int 3
KeRaiseIrqlToDpcLevel();
KeInitializeEvent(&e,NotificationEvent,FALSE);
_asm int 3
KeWaitForSingleObject(&e,Executive,KernelMode,FALSE,NULL);
_asm int 3
_asm int 3
PsTerminateSystemThread(STATUS_SUCCESS);
}
在XP中调试得到KfLowerIrql汇编:
hal!KfLowerIrql:
806d12d0 33c0 xor eax,eax
806d12d2 8ac1 mov al,cl
806d12d4 33c9 xor ecx,ecx
806d12d6 8a8858126d80 mov cl,byte ptr hal!HalpIRQLtoTPR (806d1258)[eax]
806d12dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
806d12e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
806d12e7 c3 ret
在KfLowerIrql中并未出现调用KiDispatchInterrupt的地方,未调用那么在降低Irql符合条件时,如何进行DPC调用和线程切换呢?
如果是对ds:[0FFFE0080h]下了一个写入断点引起HalpDispatchInterrupt并执行KiDispatchInterrupt,那么系统又是如何判断Irql符合条件呢?那么KfRaiseIrql 不是也有写入的动作,那不是也由可能引发中断吗,这不是不符合系统设计要求吗?这到底是怎么一回事呢?
wrk源码中进行了了当前与新的Irql级别的判断,而汇编中却没有这一步。而在一切的过程中都未对Irql进行校验,而在上述代码中一切都通过执行了,而并未引起崩溃,这与wdk文档中所述不一致呀。这样不是对整个系统的设计提出了重大挑战了吗?从而不是影响了系统等待函数的同步作用及Irql的处理了吗?事实上到底是怎样的呀?
请各位老师给详解一下此中原因吧,多谢!
附:wrk源码
VOID
FORCEINLINE
KfLowerIrql (
__in KIRQL NewIrql
)
{
ULONG tprValue;
ASSERT( NewIrql <= KeGetCurrentIrql() );
tprValue = HalpIRQLToTPR[NewIrql];
KeMemoryBarrier();
*APIC_TPR = tprValue;
*APIC_TPR;
KeMemoryBarrier();
}
源码中进行了判断,那么为何在执行时却并未进行呢?
Re: 降低Irql违反文档规定却并未引起崩溃?
格蠹老雷
2011-06-26, 11:07 上午
这些问题牵涉到了中断管理和内核调度这两大核心问题,很有点“底层”了,对于今天的年轻人来说,这都是“学了也没啥用”的问题,难得楼主感兴趣啊:-)
细说起来话太长,按问号顺序简要回答如下:
1)IRQL降低后,当前线程继续跑,等下个时钟中断来了时按调度规则调度... 今天的OS,包括NT,都是依赖时钟中断的,这是个需要改进的根本问题...搜索一下tickless kernel可以看到更多资料
2)变量访问断点触发的是CPU异常,发生异常时是不必KiDispatchInterrupt的
3)同上
4)异常和中断还是有本质差异的,优先级和处理过程有差异的
5)代码中的检查是个ASSERT,只有编译Checked版本时才起作用。
6)是会导致严重问题,所以DDK中“严词”声明,要求驱动程序在提升IRQL时一定要记住OldIrql,降低时要用
7)中断控制器(PIC,APIC,硬件)在这个问题上起到了关键作用,NT的IRQL是记录到APIC中的TPR(Task Priority Register)的,依赖APIC保证基本的规则,当前的任务只有可能被高优先级的任务打断...
Re: 降低Irql违反文档规定却并未引起崩溃?
zyq8709
2011-06-27, 17:49 下午
多谢张老师,我对底层的东西喜欢弄个清楚,对事物喜欢一问到底,非要搞个明明白白,要不就不舒服,可能也有点过于苛求了吧。
您讲了之后,我又上网搜了搜并看了一下wrk,我明白了这其中的关键作用就是现在用的APIC,他可以进行中断级别的智能判断和恢复挂起的中断,这就是系统所用的,是这样的吧?多谢您了!