WIndows内核模式驱动程序运行环境

本文详细介绍了Windows内核模式驱动程序的运行环境,包括系统进程环境、特定用户线程环境和任意用户线程环境。驱动程序的运行环境对其性能和资源开销有直接影响,特别是其派遣例程的上下文。当用户直接访问设备时,驱动程序的派遣例程将在发出请求的用户线程上下文中运行,反之,如果请求经过高层驱动程序转发,可能会在任意线程上下文中运行,这会影响驱动程序的操作,如文件对象和句柄的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        程序运行时所处的环境 即所谓的执行上下文是程序设计中的重要概念。 对于用户线程而言运行环境也就是线程所属进程的环境, 但对于驱动程序这个问题变得非常复杂。通常这是文件系统开发人员所关心的问题,但所有的内核模式驱动程序开发人员都能得益于对运行环境的深入理解并能使驱动程序拥有更高的性能和更低的开销。

        运行环境的概念程序例程的运行环境实际是指其线程和进程的执行环境,在NT系列操作系统中, 这个环境由当前的线程环境块TEB和进程环境块PEB建立。环境中包括虚拟内存设置(包含物理内存页面与虚拟内地址的对应信息)、句柄转换(句柄是基于进程的)、调度器信息、堆栈、通用寄存器及浮点寄存器的状态。对于特定的内核模式例程在什么运行环境下运行这个问题,首先要了解由内核调度器所建立的当前线程是系统中哪一个线程,由于每个线程都只属于一个进程,当前线程决定了当前进程。 这也意味着所有的数据包括句柄、虚拟内存、线程调度器状态、寄存器都是线程和进程唯一的。

        运行环境的种类

        内核模式例程可能运行在三种不同的环境中:系统进程环境(system进程)、一个特定的用户线程(进程)环境、任意用户线程(进程) 环境。 内核模式驱动程序运行时它
的部分代码可能在这三个环境之一运行。例如驱动程序的DriverEntry函数总是运行于一个系统进程上(system)下文中。系统进程上下文没有与之相对应的用户上下文,因此不存在线程环境块TEB也没有用户进程会映射入内核虚拟地址空间的低2GB内。而延时过程调用DPC例程,比如驱动程序为中断服务程序或是定时器溢出函数所设置的DPC例程则运行于一个任意用户线程上下文中。这意味着DPC运行期间当前线程可能是任何一个用户线程并且该线程所属的进程将映射入内核虚拟地址空间的低2GB内。

        驱动程序的派谴例程在什么样的上下文中运行是特别重要的问题,这涉及到派遣例程能调用哪些系统服务、能完成哪些工作, 大多数情况下一个内核模式驱动程序的派遣例程将会在发起调用的用户线程上下文中运行。然而,驱动程序的派遣例程并不总是在请求使用者线程的环境中运行,只有高层驱动程序比如文件系统驱动程序才能保证其派遣例程能在同一个用户模式线程的上下文中被调用。事实上,任何驱动程序只要因用户IO请求而被直接调用,而没有通过另外的驱动程序,它就能保证处于发出请求的用户线程的上下文中,这包括文件系统驱动程序。这意味着大多数用户编写的直接为应用程序提供函数的标准内核模式驱动程序将会在发出请求的用户线程的上下文中被调用。只有当用户请求首先发送给一个高层驱动程序,比如文件系统驱动程序,低层驱动程序的派遣例程才不会在发出请求的用户线程的上下文中运行。如果高层驱动程序把请求转发给一个系统工作者线程将会导致上下文的改变,当IRP请求最终被下传给低层驱动程序时,不再能保证转发IRP的高层驱动程序运行的上下文还是发出原始请求的用户线程的上下文了,低层驱动程序将会在一个任意线程上下文中运行。
        总之,当用户直接访问设备,不涉及到其它的驱动程序,则设备的驱动程序的派遣例程将运行于发出请求的用户线程的上下文中。

        运行环境对驱动程序运行的影响

        驱动程序派遣例程运行在用户线程上下文中将带来一些影响,其中有利有弊,例如$驱动程序的派遣函数使用ZwCreateFile函数来创建一个文件, 如果该派遣函数后来试图用ZwReadFile函数读取文件的内容,但它没有运行于最初创建文件时的用户线程的上下文中,函数将会失败, 这是因为文件对象及其句柄是基于每个进程进行存储的。如果读请求成功的发出,驱动程序可以选择等待一个事件对象,该对象联合着读操作,当读操作完成时该对象即被置为信号态这就是异步IO请求的工作情况,线程调度器然后寻找下一个具有最高优先级的就绪线程,将其置为当前线程并运行该线程,当读操作完成时前一线程所等待的事件对象被置为信号状态,此时驱动程序并不一定立刻就开始运。在一个有N个CPU 的多处理器系统中,有当用户线再次成为优先级最高的N个就绪线程之一时,驱动程序才会运行。

        在有些情况下在发出请求的用户线程的上下文环境中运行会非常有用。例如驱动程序的派遣例程用一个值为-2的句柄(意指当前线程)调用ZwSetInformationThread函数可以改变当前线程的各种各样的属性;类似的用函数NtCurrentProcess所返回的句柄值(Ntddk.h中定义为-1)来调用ZwSetInformationProcess可以改变当前进程的各种属性, 但是由于这两个函数由内核模式例程发出,没有做参数安全检验,这可以改变用户线程或进程自己不能访问的属性。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值