线程的IRQL级别

    xiaoxiao2025-08-06  6

    中断就是硬件发给CPU的电信号。cpu通过中断处理表调用相关函数处理中断信号,中断分为下面两种

    异常

    cpu内部中断,IF位保持不变,不关,就是中断标志位不变不关,同时可以相应其他硬件发出中断。,异常也封两种。

    故障:比如除0,缺页,越界堆栈段错误。

    陷阱:如调试指令int3,溢出等。

    中断:

    其他硬件发出的中断,中断标志位清零,关中断。分为

    非屏蔽中断,计算机内部出错引起的异常

    屏蔽中断。

    为了确定CPU先处理哪种中断,所以通过优先级的区分来优先处理。

    上下文区别:

    进程上下文:可理解为内核系统代替进程做一些事情,比如应用层发读写请求到内核,内核做一些事情,可睡眠,睡觉(因为进程是可以调度的)。

    中断上下文:可理解为内核系统代替硬件做一些事情,接到中断请求做的事情,其他时候在进程上下文,不可睡眠,受伤(没有调度机制)

    遵守

    中断级别的遵守

    个人理解各个级别级别越高相当于注意点越多,越在靶心,所以要求多,比如只能用非分页,然后不能允许低级别函数。

    要清楚驱动中各个函数的中断级别

    比如DriverEnty,DriverUnload,各个分发函数,在passive级别,完成函数各种NDIS回调,在Dispatch级别。

    要明白调用的API运行级别

    本质因为函数内部没有访问分页内存,只要函数访问了分页内存,只能在passive低级别使用。这有一些规律大部分zw开头函数在passive级别。跟IO相关大部分也都在passive级别。

    passive级别可以使用任何函数和内存,要求最低。

    DISPATCH级别只能访问运行在dispatch级别的API和非分页内存。

    NoNPAGEPOOL内存可在任何级别使用

    PAGEDOOL只能在passive_level和APC_LEVEL级别使用。

    在PASSIVE_LEVEL和APC级别代码中加:PAGED_CODE()宏

    #define PAGED_CODE()\ if(KeGetCurrentIRQL()>APC_LEVEL){ kdPrint(("EX:Pageable code called at IRQL %d\n",KeGerCurrentlrql()));\ ASSERT(FALSE);\ }\

    当我们不知道我们在什么级别时候可以这样判断。

    那如果我们想做键盘过滤程序,如何在高IRQL级别下保存文件(文件相关函数都是在PASSIVE_LEVEl,我们是通过完成例程做的)

    我们可以在完成例程里开启一个工作者线程。然后操作文件都在这个线程中,工作者线程是PASSIVE_LEVEL级别。

     

    最新回复(0)