首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows Kernel 深度解析:KeRaiseIrql 機制與 x86/x64 差異

     編輯:關於C語言

Windows Kernel 深度解析:KeRaiseIrql 機制與 x86/x64 差異

KeRaiseIrql 是 Windows 核心提升 IRQL(Interrupt Request Level)的核心 API,實現執行緒同步、鎖保護、DPC 執行等關鍵功能。本文通過反組譯與 WRK 原始碼,深度剖析其底層實現。

核心結論

  • x86:透過 APIC TPR (Task Priority Register, 0xFFFE0080) 硬體暫存器控制中斷屏蔽。查表 HalpIRQLtoTPR 獲取 TPR 值,寫入 APIC_TPR;舊 IRQL 從 HalpVectorToIRQL 反查。
  • x64:直接操作 CR8 暫存器(低 4 位即 IRQL),無需查表,指令 mov cr8, rcx 單指令完成。
  • 核心函式鏈:KeRaiseIrql → KfRaiseIrql (x86) / 內聯 KfRaiseIrql (x64)。

x86 反組譯追蹤

hal!KfRaiseIrql:
movzx edx, cl              ; 輸入 NewIrql
movzx ecx, byte ptr hal!HalpIRQLtoTPR[edx] ; 查表得 TPR
mov eax, dword ptr ds:[FFFE0080h]          ; 讀舊 APIC_TPR
mov dword ptr ds:[FFFE0080h], ecx          ; 寫新 TPR
shr eax, 4
movzx eax, byte ptr hal!HalpVectorToIRQL[eax] ; 反查舊 IRQL
ret

WRK 核心原始碼

#define APIC_TPR ((volatile ULONG *)0xFFFE0080)
extern PUCHAR HalpIRQLToTPR;
extern PUCHAR HalpVectorToIRQL;

KIRQL KfRaiseIrql(KIRQL NewIrql) {
    KIRQL oldIrql = KeGetCurrentIrql();
    ASSERT(NewIrql >= oldIrql);
    ULONG tprValue = HalpIRQLToTPR[NewIrql];
    KeMemoryBarrier();
    *APIC_TPR = tprValue;
    KeMemoryBarrier();
    return oldIrql;
}

KIRQL KeGetCurrentIrql() {
    ULONG tpr = *APIC_TPR;
    return HalpVectorToIRQL[tpr / 16];
}

x64 實現:CR8 暫存器

nt!KfRaiseIrql:
mov rax, cr8        ; 讀舊 IRQL (CR8 低 4 位)
movzx ecx, cl       ; NewIrql
mov cr8, rcx        ; 寫新 IRQL
ret
  • x64 以 CR8 直接映射 IRQL (0-15),無 APIC TPR 間接層,效能更高。
  • KeMemoryBarrier 確保記憶體存取順序,防止亂序執行破壞同步語義。

除錯技巧

相關 API

  • KeRaiseIrqlToDpcLevel / KeRaiseIrqlToSynchLevel:常用封裝。
  • KeLowerIrql:還原 IRQL,需配對呼叫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景命令/方法
查看當前 IRQL (Win2003+)!irql 或 dd nt!KiOldIrql L1
Win2003 前僅能反組譯 KeGetCurrentIrql 推導
KeFreezeExecution 時舊 IRQL 保存在 KiOldIrql 全域變數