系统提供的 Windows 内核模式进程和线程管理器控制进程和线程在 Windows作系统中的执行方式。 了解此管理器对于需要创建线程、监视进程创建或同步对共享资源的访问的内核模式驱动程序开发人员至关重要。
ObCallback 驱动程序示例演示如何在内核模式驱动程序中使用进程和线程通知例程。
进程和线程概述
进程是当前在 Windows 中运行并由唯一进程 ID(PID)标识的软件程序。 在每个进程中,一个或多个 线程 表示运行程序代码的实际执行单元。 每个线程在其进程中也有唯一的线程 ID(TID)。
线程通过共享处理器时间启用多任务。 在单处理器计算机上,可以分配多个线程,但一次只能执行一个线程。 处理器在线程之间快速切换,从而产生同时执行的错觉。 在多处理器系统上,当线程在不同处理器上同时运行时,会发生真正的并行执行。
Windows 内核模式进程和线程管理器处理进程中所有线程的执行。 无论你是否拥有一个处理器或更多处理器,都必须在驱动程序编程中非常小心,以确保进程的所有线程都经过设计,以便无论处理线程的顺序如何,驱动程序都会正常运行。
如果来自不同进程的线程尝试同时使用相同的资源,则可能会出现问题。 Windows 提供了几种方法来避免此问题。 确保来自不同进程的线程不会接触同一资源的技术称为 同步。 有关同步的详细信息,请参阅 同步技术。
为进程和线程管理器提供直接接口的例程通常以字母“Ps”为前缀;例如 ,PsCreateSystemThread。 有关内核 DDI 的列表,请参阅 Windows 内核。
实现进程和线程相关的回调函数的最佳做法
这组准则适用于以下回调例程:
- PCREATE_PROCESS_NOTIFY_ROUTINE
- PCREATE_PROCESS_NOTIFY_ROUTINE_EX
- PCREATE_THREAD_NOTIFY_ROUTINE
- PLOAD_IMAGE_NOTIFY_ROUTINE
- POB_PRE_OPERATION_CALLBACK
- POB_POST_OPERATION_CALLBACK
请使用这些最佳做法:
- 保持例程简短而简单。
- 不要调用用户模式服务来验证进程、线程或映像。
- 不要进行注册表调用。
- 不要进行阻止和/或进程间通信 (IPC) 函数调用。
- 不要与其他线程同步,因为这可能导致重入性死锁。
- 使用 系统工作线程 将工作排在队列中,尤其是涉及的工作:
- 速度缓慢的 API 或调用其他进程的 API。
- 任何可能中断核心服务中的线程的阻塞行为。
- 如果使用系统工作线程,请不要等待工作完成。 这样做会挫败排队工作以异步方式完成的目的。
- 考虑内核模式堆栈使用情况的最佳做法。 有关示例,请参阅如何防止驱动程序耗尽内核模式堆栈?以及关键驱动程序概念和提示。
子系统进程
从 Windows 10 开始,适用于 Linux 的 Windows 子系统(WSL)使用户能够与其他 Windows 应用程序一起在 Windows 上运行本机 Linux ELF64 二进制文件。 有关运行二进制文件所需的 WSL 体系结构和用户模式和内核模式组件的信息,请参阅 适用于 Linux 的 Windows 子系统 博客上的文章。
其中一个组件是一个 子系统进程 ,用于托管未修改的用户模式 Linux 二进制文件,例如 /bin/bash。 子系统进程不包含与 Win32 进程关联的数据结构,例如进程环境块(PEB)和线程环境块(TEB)。 对于子系统进程,系统会将系统调用和用户模式异常调度到配对的驱动程序。
下面是对进程和线程管理器例程的更改,以支持子系统进程:
WSL 类型由SUBSYSTEM_INFORMATION_TYPE枚举中的 SubsystemInformationTypeWSL 值指示。 驱动程序可以调用 NtQueryInformationProcess 和 NtQueryInformationThread 来确定基础子系统。 WSL 中这些调用返回 SubsystemInformationTypeWSL。
其他内核模式驱动程序可以通过 PsSetCreateProcessNotifyRoutineEx2 调用注册其回调例程来获取有关子系统进程创建/删除的通知。 若要获取有关线程创建/删除的通知,驱动程序可以调用 PsSetCreateThreadNotifyRoutineEx,并将 PsCreateThreadNotifySubsystems 指定为通知类型。
扩展了PS_CREATE_NOTIFY_INFO结构,以包含IsSubsystemProcess成员,该成员指示是否为Win32以外的子系统。 其他成员(如 FileObject、 ImageFileName、 CommandLine )指示有关子系统进程的其他信息。 有关这些成员的行为的信息,请参阅 SUBSYSTEM_INFORMATION_TYPE。