程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> KeRaiseIrql理解,閱讀理解

KeRaiseIrql理解,閱讀理解

編輯:關於C語言

KeRaiseIrql理解,閱讀理解


先說總結:說白了提升IRQL其實就是從hal!HalpIRQLtoTPR獲取要提升的IRQL級對應的TPR(Tast Preritory Register)值,改寫到APIC_TPR地址上去(0xFFFE0080). 然後將舊TPR值,從byte ptr hal!HalpVectorToIRQL,獲取到舊的IRQL值。x64不一樣,x64就CR8寄存器單獨干這個。   windgb:2003版本之前獲取當前IRQL只能從反匯編入手獲取。之後的版本可以!irql命令。KPRCB.DebuggerSavedIRQL,保存。 有一個名為 KiOldIrql 的全局變量,在 KeFreezeExecution 把 IRQL 提升到 HIGH_LEVEL 的時候會把原先的 IRQL 保存在這個變量裡。所以2003之後的版本可以直接dd nt!KiOldIrql L1 查看。之前的話。自己找吧。貌似通過調試器中斷下被調試系統來會導致IRQL切換,而如果崩潰則不會發生。  
  1 直接看反匯編。
  2 kd> u nt!KeRaiseIrql
  3 nt!KeRaiseIrql:
  4 8053b888 ff25a0864d80    jmp     dword ptr [nt!_imp__KeRaiseIrql (804d86a0)]               **此處地址是間接地址,指向的是導入表數據的地址,別整錯了**
  5  
  6 kd> uf Hal!KeRaiseIrql
  7 hal!KeRaiseIrql:
  8 806d775c 8bff            mov     edi,edi
  9 806d775e 55              push    ebp
 10 806d775f 8bec            mov     ebp,esp
 11 806d7761 8a4d08          mov     cl,byte ptr [ebp+8]
 12 806d7764 e80fbbffff      call    hal!KfRaiseIrql (806d3278)
 13 806d7769 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
 14 806d776c 8801            mov     byte ptr [ecx],al
 15 806d776e 5d              pop     ebp
 16 806d776f c20800          ret     8
 17  
 18 kd> u 806d3278
 19 hal!KfRaiseIrql:
 20 806d3278 0fb6d1          movzx   edx,cl                                   // 獲取要提升的IRQL級
 21 806d327b 0fb68a58326d80  movzx   ecx,byte ptr hal!HalpIRQLtoTPR (806d3258)[edx]     // 將新傳入的irql作為索引,找到一個值                             806d3282 a18000feff      mov     eax,dword ptr ds:[FFFE0080h]                    // 保存舊的。不清楚FFDFF000以上的結構
 22 806d3287 890d8000feff    mov     dword ptr ds:[0FFFE0080h],ecx               // 把新的值存到這個位置
 23 806d328d c1e804          shr     eax,4
 24 806d3290 0fb68088e06d80  movzx   eax,byte ptr hal!HalpVectorToIRQL (806de088)[eax]   // 取得舊值
 25 806d3297 c3              ret
 26  
 27 kd> u KeGetCurrentIrql
 28 hal!KeGetCurrentIrql:
 29 806d32e8 a18000feff      mov     eax,dword ptr ds:[FFFE0080h]
 30 806d32ed c1e804          shr     eax,4
 31 806d32f0 0fb68088e06d80  movzx   eax,byte ptr hal!HalpVectorToIRQL (806de088)[eax]
 32 806d32f7 c3              ret
 33  
 34 x64下
 35 nt!KfRaiseIrql:
 36 fffff800`0451ab90 440f20c0        mov     rax,cr8
 37 fffff800`0451ab94 0fb6c9          movzx   ecx,cl
 38 fffff800`0451ab97 440f22c1        mov     cr8,rcx
 39 fffff800`0451ab9b c3              ret
 40  
 41  
 42 摘錄WRK的源碼
 43 extern PUCHAR HalpIRQLToTPR;
 44 extern PUCHAR HalpVectorToIRQL;
 45 #define APIC_TPR ((volatile ULONG *)0xFFFE0080)
 46  
 47 #define KeGetCurrentIrql _KeGetCurrentIrql
 48 #define KfLowerIrql _KfLowerIrql
 49 #define KfRaiseIrql _KfRaiseIrql
 50  
 51 KIRQL
 52 FORCEINLINE
 53 KeGetCurrentIrql (
 54     VOID
 55     )
 56 {
 57     ULONG tprValue;
 58     KIRQL currentIrql;
 59  
 60     tprValue = *APIC_TPR;
 61     currentIrql = HalpVectorToIRQL[ tprValue / 16 ];
 62     return currentIrql;
 63 }
 64  
 65 VOID
 66 FORCEINLINE
 67 KfLowerIrql (
 68     __in KIRQL NewIrql
 69     )
 70 {
 71     ULONG tprValue;
 72  
 73     ASSERT( NewIrql <= KeGetCurrentIrql() );
 74  
 75     tprValue = HalpIRQLToTPR[NewIrql];
 76     KeMemoryBarrier();
 77     *APIC_TPR = tprValue;
 78     *APIC_TPR;
 79     KeMemoryBarrier();
 80 }
 81  
 82 KIRQL
 83 FORCEINLINE
 84 KfRaiseIrql (
 85     __in KIRQL NewIrql
 86     )
 87 {
 88     KIRQL oldIrql;
 89     ULONG tprValue;
 90  
 91     oldIrql = KeGetCurrentIrql();
 92  
 93     ASSERT( NewIrql >= oldIrql );
 94  
 95     tprValue = HalpIRQLToTPR[NewIrql];
 96     KeMemoryBarrier();
 97     *APIC_TPR = tprValue;
 98     KeMemoryBarrier();
 99     return oldIrql;
100 }
101  
102 KIRQL
103 FORCEINLINE
104 KeRaiseIrqlToDpcLevel (
105     VOID
106     )
107 {
108     return KfRaiseIrql(DISPATCH_LEVEL);
109 }
110  
111 KIRQL
112 FORCEINLINE
113 KeRaiseIrqlToSynchLevel (
114     VOID
115     )
116 {
117     return KfRaiseIrql(SYNCH_LEVEL);
118 }
119  
120 #define KeLowerIrql(a) KfLowerIrql(a)
121 #define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a)

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved