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)

  

你可能感兴趣的:(理解)