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)