Windows内核学习笔记(一)

前言

此随笔为本人笔记,并非系统学习应当使用

内核

ntoskrnl.exe 是 Windows 操作系统的核心内核程序文件,全称为 Windows NT Operating System Kernel。它是 Windows 操作系统正常运行的基础

内核层级

R0是内核层,R3是应用层,而R1、R2不使用
这样就解决了我之前不理解R1、R2是什么应用的问题

Windows内核中主要可以分成三层:硬件抽象层(HAL),内核层(也称微内核micro-kernel),执行体层

Ntdll.dll的功能

  • 作为桥梁:Ntdll.dll是用户模式代码和内核模式系统服务之间的连接纽带。它使得用户模式的应用程序能够方便地调用内核提供的系统服务,而无需直接与内核进行交互,从而保证了系统的稳定性和安全性。
  • 提供存根函数:对于内核提供的每一个系统服务,Ntdll.dll都对应提供一个存根函数。这些存根函数的名称以“Nt”作为前缀,例如NtCreateProcess(用于创建进程)、NtOpenFile(用于打开文件)等。存根函数的作用是为用户模式代码提供一个接口,当用户模式代码调用这些存根函数时,Ntdll.dll会将调用请求转发给相应的内核模式系统服务。
  • 提供系统级支持函数:除了存根函数,Ntdll.dll还提供了许多系统级的支持函数,用于实现各种系统功能。这些支持函数按照功能不同有不同的前缀,例如:
  • 映像加载器函数(以“Ldr”为前缀):用于加载和管理程序的映像文件,例如LdrLoadDll(加载动态链接库)等。
  • 系统时间函数(以“Etw”为前缀):用于与系统时间相关的操作,例如EtwStartTrace(开始跟踪事件)等。
  • 一般的运行支持函数(以“Rtl”为前缀):提供各种运行时支持功能,例如RtlAllocateHeap(分配堆内存)等。
  • 字符串支持函数:用于字符串操作,例如RtlCompareString(比较字符串)等。

中断请求级别

在Windows操作系统中调用内核函数时,必须关注中断请求级别(IRQL,Interrupt Request Level),原因如下:

IRQL的定义与作用

IRQL是一个表示中断优先级的数字,用于确定中断处理的优先顺序。它确保处理器在处理不同任务时维持正确的操作顺序和安全性。Windows内核通过IRQL管理对硬件资源的访问,以及处理不同级别的中断和异常。

不同IRQL级别对内核函数调用的限制

  • PASSIVE_LEVEL:最低的IRQL级别,大多数线程操作和内核函数在此级别运行。可以访问分页内存,且不会被中断。
  • APC_LEVEL:禁止异步过程调用(APC),某些内核函数在此级别不可用。
  • DISPATCH_LEVEL:禁止调度器操作,只能访问非分页内存,许多内核函数在此级别无法调用。
  • DIRQL(设备IRQL):用于硬件中断处理,几乎无法调用普通内核函数。
  • 高IRQL(HIGH_LEVEL):这是最高的IRQL级别,用于系统关键操作,此时几乎所有的中断都被禁止。

调用内核函数时IRQL的重要性

  • 内核函数通常对IRQL有明确的要求,调用时必须确保当前IRQL与函数要求的级别相符。如果不遵守这一规则,可能导致系统崩溃或数据损坏。
  • 驱动程序开发中,合理管理IRQL至关重要。例如,某些函数只能在低IRQL下运行,而当前IRQL较高时,直接调用这些函数会导致系统不稳定。
  • 避免死锁和性能问题
  • 在高IRQL级别下,系统资源的访问和同步机制受到严格限制。开发者需要确保在高IRQL级别下尽量减少资源持有时间,避免复杂操作,以防止死锁和性能问题。

因此,调用内核函数时必须关注IRQL,以确保系统的稳定性和数据一致性。

疑问

作者在阅读资料后提出:
何时应当处理中断级别?何时应当修改中断级别?

何时应当处理中断级别?

处理中断级别通常是指在内核模式代码中,开发者需要明确当前的IRQL级别,并根据当前IRQL级别调整代码逻辑。以下是一些需要特别关注IRQL的场景:

  1. 调用内核函数时

    • 每个内核函数都有其允许运行的IRQL级别范围。在调用内核函数之前,必须确认当前IRQL是否符合函数的要求。例如:
      • 大多数内核函数只能在PASSIVE_LEVEL运行。
      • 一些函数可以在APC_LEVELDISPATCH_LEVEL运行,但不能访问分页内存。
      • DIRQLHIGH_LEVEL下,几乎无法调用普通内核函数。
    • 如果当前IRQL不符合要求,直接调用这些函数可能导致系统崩溃。
  2. 访问硬件资源时

    • 当驱动程序需要访问硬件设备时,通常需要将IRQL提升到DIRQL级别,以确保在访问硬件资源时不会被其他中断打断。
    • 硬件中断处理例程(ISR)通常运行在DIRQL级别,此时需要特别注意代码的执行效率和安全性。
  3. 执行同步操作时

    • 在高IRQL级别下(如DISPATCH_LEVEL或更高),系统不允许线程切换,因此需要特别注意同步机制的使用。例如:
      • DISPATCH_LEVEL下,可以使用自旋锁(Spin Lock)来保护共享资源。
      • PASSIVE_LEVEL下,可以使用互斥锁(Mutex)或其他同步原语。
  4. 异常处理时

    • 当系统发生异常(如除零错误、访问违规等)时,异常处理例程会运行在特定的IRQL级别。此时需要根据异常的类型和优先级调整IRQL,以确保异常处理的正确性。

何时应当修改中断级别?

修改中断级别是指通过内核函数(如KeRaiseIrqlKeLowerIrql)显式地提升或降低当前处理器的IRQL。以下是需要修改IRQL的典型场景:

  1. 进入硬件中断处理

    • 当硬件设备发出中断请求时,内核会自动将IRQL提升到对应的DIRQL级别,并执行中断服务例程(ISR)。
    • 在ISR中,开发者可能需要进一步提升IRQL以执行某些高优先级操作(如处理关键硬件中断)。
  2. 执行高优先级任务

    • 当需要执行某些高优先级任务时(如系统关键操作),可以将IRQL提升到HIGH_LEVEL,以屏蔽所有中断。
    • 例如,在执行某些原子操作或访问关键链表时,可能需要将IRQL提升到HIGH_LEVEL
  3. 延迟过程调用(DPC)

    • DPC用于延迟处理某些非紧急任务,通常运行在DISPATCH_LEVEL以下的IRQL级别。
    • 在DPC中,开发者可能需要将IRQL提升到DISPATCH_LEVEL,以确保DPC的正确执行。
  4. 退出中断处理

    • 当中断处理完成时,需要将IRQL降低到之前的级别,以恢复正常的系统运行。
    • 例如,在ISR或DPC执行完成后,使用KeLowerIrql将IRQL降低到PASSIVE_LEVEL
  5. 避免死锁和性能问题

    • 在高IRQL级别下,系统资源的访问受到严格限制。如果需要访问某些资源,可能需要将IRQL降低到较低的级别。
    • 例如,如果需要访问分页内存,必须将IRQL降低到PASSIVE_LEVEL

总结

  • 处理中断级别:在调用内核函数、访问硬件资源、执行同步操作或处理异常时,必须明确当前的IRQL级别,并根据函数或操作的要求调整代码逻辑。
  • 修改中断级别:通过KeRaiseIrqlKeLowerIrql显式地提升或降低IRQL,通常用于进入硬件中断处理、执行高优先级任务、处理DPC或退出中断处理。

合理管理IRQL是确保内核模式代码稳定性和性能的关键。开发者需要根据当前的IRQL级别和操作需求,谨慎地处理和修改IRQL,以避免系统崩溃或性能问题。

posted @   Timmoc  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示