IRQL的理解和认识

2023-11-01

介绍:

   中断请求(IRQ,Interrupt Request)一般有两种,一种是外部中断,也就是硬件产生的中断(例如:键盘中断、打印机中断、定时器中断):另一种是由软件指令 int n 产生的中断(例如:INT 3 断点中断、INT 1 单步中断)。后来 Windows 将中断进行的扩展,提出一个中断请求级(IQRL)的概念。其中规定了 32个中断请求级别,分别是 0-2 级别为软件中断,3-31 为硬件中断。

 

Windows IRQL的宏定义

#define PASSIVE_LEVEL 0                               // Passive release level
#define LOW_LEVEL 0                                      // Lowest interrupt level
#define APC_LEVEL 1                                       // APC interrupt level
#define DISPATCH_LEVEL 2                            // Dispatcher level
#define CMCI_LEVEL 5                                     // CMCI handler level
#define PROFILE_LEVEL 27                             // timer used for profiling.
#define CLOCK1_LEVEL 28                              // Interval clock 1 level - Not used on x86
#define CLOCK2_LEVEL 28                              // Interval clock 2 level
#define IPI_LEVEL 29                                        // Interprocessor interrupt level
#define POWER_LEVEL 30                               // Power failure level
#define HIGH_LEVEL 31                                    // Highest interrupt level
#define CLOCK_LEVEL (CLOCK2_LEVEL)

对于驱动编程,我们通常只会接触到 0 到 2 的 IRQL 以及 DIRQL。

PASSIVE_LEVEL 0: 

     IRQL最低级别,没有被屏蔽的中断(无法屏蔽其他中断),在这个级别上,线程执行用户模式,可以访问分页内存。用户模式的代码是运行在最低级别的PASSIVE_LEVEL中,驱动程序的DriverEntry函数,派遣函数、AddDevice函数一般运行在PASSIVE_LEVEL中(驱动程序的StartIO和DPC函数运行在DISPATCH_LEVEL中),它们在必要的时候可以申请进入
DISPATCH_LEVEL级别(为了保证当前例程不会被CPU切换到其他地方),使用内核函数KeGetCurrentIrql()可以知道系统的当前IRQL。

APC_LEVEL 1 :

    在这个级别上,只有处于APC级别的中断被屏蔽,可以访问分页内存。当有APC发生时,处理器提升到APC级别,这样,就屏蔽掉其他的APC,为了和APC执行一些同步,驱动程序可以手动提升到这个级别。APC级别仅仅比PASSIVE_LEVEL高,这也是在一个线程中插入一个APC可以打断该线程(如果该线程运行在PASSIVE_LEVEL上)运行的原因。 

 DISPATCH_LEVEL 2:

     DISPATCH_LEVEL是一个重要的区分点,它代表了线程调度器正在运行。一个处理器运行运行在IRQL上,代表他可能正在做两件事之一:正在进行线程调度;正在处理硬件中断的后半部(不那么重要的部分),这个被称为DPC(Deferred Procedure Call:延迟调用)。这个级别,DPC(延迟过程)和更低的中断被屏蔽,不能访问分页内存,所有的被访问的内存不能分页。因为只能处理非分页内存,所有在这个级别上,能够访问的Api大大减少。

     Windows负责线程调度的组件运行在DISPATCH_LEVEL级别,当前线程运行完时间片时,操
作系统自动从PASSIVE_LEVEL提升到DISPATCH_LEVEL级别,从而可以使得线程调度组件可以
调度其他线程。当线程切换完成后,操作系统又从DISPATCH_LEVEL级别恢复到
PASSIVE_LEVEL级别。

线程优先级和 IRQL

    线程优先级是指线程是否有更多的机会运行在CPU上,线程优先级高的线程有更多的机会被内核调用。ReadFile内部创建IRP_MJ_READ,然后这个IRP被传递到驱动程序的派遣函数中,这时派遣函数运行于ReadFile所在的线程中,或者说ReadFile和派遣函数位于同一个线程的上下文中。
    线程运行在PASSIVE_LEVEL级别,这个时候OS随时可能将当前线程切换到别的线程中去。但是将IRQL提升到DISPATCH_LEVEL级别时,这时则不会出现线程切换。这是一种很常用的处理机制,但是这种方法只能使用于单CPU的系统,对于多Cpu的系统,需要采用别的同步处理机制。 

IRQL  与分页内存

     在使用内存分页时,可能会导致页故障。因为分页内存随时可能从物理内存交换到磁盘文件中。读取不在物理内存中的分页时,会引发一个页故障,从而执行这个异常的处理函数。异常处理函数会重新将磁盘文件的内容交换到物理内存中。页故障允许在PASSIVE_LEVEL级别的程序中,但如果在DISPATCH_LEVEL或者更高级别IRQL的程序中会带来系统崩溃。
     对于等于或者高于DISPATCH_LEVEL级别的程序不能使用分页内存,必须使用非分页内存。驱动程序的StartIO全程、DPC例程、中断服务例程都运行在DISPATCH_LEVEL或者更高的IRQL,因为这些例程不能使用分页内存,否则会导致系统崩溃。 

当 IRQL< DISPATCH_LEVEL v1 内存申请成功

 

当 IRQL 提升到 DISPATCH_LEVEL 申请分页内存,导致系统蓝屏

错误码:IRQL_NOT_LESS_OR_EQUAL

蓝屏原因:缺页中断机制是运行在 DISPATCH_LEVEL 级别下的,和当前代码处于一个级别,当代码访问到一个内存页在换页文件的时候,缺页机制无法打断当前代码的运行,从而无法进行页交换,导致访问到了一个错误的内存地址,进而蓝屏。

 

IRQL  的提升和降低

       有些时候驱动程序中需要提升IRQL级别,在运行一段时间后,再将降回原来的IRQL级别,这样做的目的一般是基于同步处理的需要。(当提升IRQL后,不允许低于当前IRQL的活动相互抢先,从而防止了潜在的冲突,这只适用于单Cpu的系统。当是多Cpu系统时,需要采用其他的同步机制,例如事件,自旋锁等等)首先驱动程序需要知道当前状态IRQL级别,可以通过KeGetCurrentIrql内核函数获取当前的IRQL级别。
       然后驱动程序使用内核函数KeRaiseIrql将IRQL提高。KeRaiseIrql需要两个参数,第一个数是提升后的IRQL级别,第二个参数是保存提升前的IRQL级别。最后,驱动程序某个时刻需要将IRQL恢复到以前的IRQL级别,驱动程序可以调用
KeLowerIrql内核函数。

      下面代码演示了驱动中如何提升和降低IRQL的代码 

 

VOID RaiseIRQL_Test()
{
KIRQL oldirql;
// 确保当前IRQL等于或小于DISPATCH_LEVEL
ASSERT(KeGetCurrentIrql() <= DIPATCH_LEVEL); 
// 提升IRQL到DISPATCH_LEVEL,并将先前的IRQL保存起来
KeRaiseIrql(DISPATCH_LEVEL, &oldirql);
//... 
// 恢复到先前的IRQL
KeLowerIrql(oldirql);
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IRQL的理解和认识 的相关文章

随机推荐

  • Nginx安装部署学习

    什么是Nginx Nginx engine x 是一个高性能的HTTP和反向代理web服务器 同时也提供了IMAP POP3 SMTP服务 其特点是占有内存少 并发能力强 协议 BSD like Nginx 安装 1 部署执行命令 apt
  • phpstorm部署sftp的root path跟mappings的问题

    在部署phpstorm的sftp时要注意root path的设置 例如如果想要将本地的 var www目录映射到服务器上的 var www目录 那么如果你的root path为 var www 然后mappings里面的server pat
  • C/C++基本数据类型

    学了 C 然后 C 然后 MFC Windows 然后是 C 其中数据类型很多 由基本类型衍生的 typedef 类型也 N 多 熟知基本数据类型是我们正确表达实际问题中各种数据的前提 因此我分类总结了一下 C C Windows C 基本
  • 信管备考脑图

    参考网址 https zhuanlan zhihu com p 97968103 参考教材 1 信息化与信息系统
  • 中职网络安全2022年赛题Windows(SMB服务漏洞结合NTLM中继进行渗透测试)解析

    文章目录 目录 一 赛题 二 解析 一 赛题 二 解析 任务实施 P066 综合渗透测试 使用SMB服务漏洞结合NTLM中继进行渗透测试 实验环境说明 渗透机 p10 kali 6 1 Kali Linux 用户名 root 密码 toor
  • 使用git强行切换分支

    两行代码轻松搞定 git status 一下 一堆文件为暂存的 git clean dfx 可以直接全部干掉它门 然后git checkout v2 0 切换到2 0分支去 git clean dfx public vue static j
  • Python 导入模块的3种方式

    回到顶部 一 定义 模块就是用一堆的代码实现了一些功能的代码的集合 通常一个或者多个函数写在一个 py文件里 而如果有些功能实现起来很复杂 那么就需要创建n个 py文件 这n个 py文件的集合就是模块 如果不懂可以先看下面这篇博文 http
  • Markdown基础教程

    1 标题 Markdown支持6级标题 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 标题的效果 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 2 段落及区块引用 Markdown提供了一个特殊符号 gt 用于段
  • 网红表白弹窗

    如何使用Python表白 先看效果图 一 具体步骤 1 首先我们要安装tkinter库 pip install tkinter 等待安装完成即可 2 使用步骤引入库 from tkinter import from tkinter impo
  • 配置MAC刷新ARP功能

    在以太网中 MAC地址表项用于指导设备进行二层数据转发 ARP表项通过IP地址和MAC地址的映射指导设备进行不同网段间的通信 MAC地址表项的出接口通过报文触发刷新的 ARP表项的出接口是在老化时间到后通过老化探测进行刷新的 这样就可能会出
  • 显著性检验【t-test、方差分析、ks检验】

    显著性检验 t test 方差分析 ks检验 0 目录 1显著性检验基本定义 what 2 使用显著性检验的意义 why 3 显著性检验的具体操作流程 how 1 显著性检验基本定义 统计假设检验 Statistical hypothesi
  • vue 按需引入 element-ui 组件

    新建 plugins element ui js 文件 在里面写入需要引入的组件 import Vue from vue import Button Dialog Form FormItem Loading Message Paginati
  • java char判断相等_java面试题-基础

    1 一个 java 源文件中是否可以包括多个类 不是内部类 有什么限制 可以有多个类 但只能有一个public的类 并且public的类名必须与文件名相一致 2 Java有没有goto java中的保留字 现在没有在java中使用 3 说说
  • 搭建: canal部署与实例运行

    1 准备 github https github com alibaba canal 里面有包括canal的文档 server端 client端的 例子 源码包等等 2 canal概述 canal是应阿里巴巴存在杭州和美国的双机房部署 存在
  • Adobe XD 连不上网用不了插件的解决办法

    安装了xd想用插件发现 提示 请先链接网络 只要注册一个所在地在美国的账号即可联网成功 操作如下 1 依次点击菜单栏帮助 登录 2 点击创建账户 3 输入邮箱和密码 邮箱可以随便输入 但要记住密码方便后期登录 但如果后期忘记了密码可以通过邮
  • Linux(CentOS)安装Zookeeper

    前置环境是装好Java环境 然后去zookeeper官网下载 http mirror bit edu cn apache zookeeper 下载好后把压缩包上传到服务器 去到服务器地下解压 tar zxvf apache zookeepe
  • 96. 不同的二叉搜索树

    96 不同的二叉搜索树 给你一个整数 n 求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种 返回满足题意的二叉搜索树的种数 二叉搜索树的定义 二叉搜索树是一个有序树 若它的左子树不空 则左子树上所有结点的值均小
  • Java架构直通车——Kafka介绍和高性能原因

    文章目录 Kafka介绍 Kafka高性能原因 Kafka介绍 Kafka以前说过很多次了 包括了Kafka单独的介绍 Kafka与Fabric 这里知识简单说说 Kafka的主要特点就是基于Pull模式来处理消息消费 追求高吞吐量 一开始
  • JavaScript应该被放在什么位置

    1 JavaScript被放在中 首先我们要知道的是HTML 文档加载顺序是从上至下被加载的 而且加载途中遇到JavaScript的代码时就会把JavaScript的代码放入缓冲中 当浏览器找到与它相关的标签时才进行匹配 当我们把JavaS
  • IRQL的理解和认识

    介绍 中断请求 IRQ Interrupt Request 一般有两种 一种是外部中断 也就是硬件产生的中断 例如 键盘中断 打印机中断 定时器中断 另一种是由软件指令 int n 产生的中断 例如 INT 3 断点中断 INT 1 单步中