windows內核情景分析之—— KeRaiseIrql函數與KeLowerIrql()函數
阿新 • • 發佈:2018-07-31
fine tca down 調用 def exec pri logs ron
windows內核情景分析之—— KeRaiseIrql函數與KeLowerIrql()函數
1.KeRaiseIrql函數
這個 KeRaiseIrql() 只是簡單地調用 hal 模塊的 KfRaiseIrql() 函數,返回原來的 IRQL 寫入 KeRaiseIrql() 的第 2 個參數裏,將它寫回 C 代碼如下:
VOID KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql) { KIRQL Irql = KfRaiseIrql(NewIrql); *OldIrql = Irql; } KIRQL KfRaiseIrql(KIRQL Irql) { KIRQL OldIrql = GetCurrentKPcr()->Irql; // 從 _KPCR.Irql(fs:[24])得到 Irql 值 if (HalpEnableIrqlAudit != 0) { eflags = GetCurrentElfags(); // 得到 eflags 值 DisableInterrupt(); // 關閉中斷 HalpValidatePendingInterrts(); if (HalpEnableIrqlAudit == 0 || OldIrql >= DPC_LEVE || OldIrql >= ((USHORT *)GetCurrentKPcr()->HalReserved)[1]; // fs:[96h] || HalpAssertFailedOnce != 0) { if (eflags.IF == 0) EnableInterrupt(): // 開中斷 } } if (HalpEnableIrqlAudit == 0 || OldIrql <= Irql) { // 空,跳出 if() } else { HalpAssertFailedOnce = 1; DbgBreakPoint(); // 被斷下 } GetCurrentKPcr()->Irql = Irql; // 設置新的 IRQL 值 return OldIrql;// 返回舊的 IRQL 值 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
KfRaiseIrql() 函數能提升 IRQL 需符合下面的條件之一:
1.HalpEnableIrqlAudit 為 0(HalpEnableIrqlAudit 是個 hal 模塊內的全局變量,但我不知道它是什麽意思
2.NewIrql >= OldIrql(也就是要提升的 IRQL 必須大於或等於原值)
2.KeLowerIrql()函數
#define KeLowerIrql(a) KfLowerIrql(a) VOID FASTCALL KfLowerIrql (KIRQLNewIrql) { if (NewIrql > KeGetPcr()->Irql) { KEBUGCHECK(0); for(;;); } HalpLowerIrql(NewIrql); } VOID HalpLowerIrql(KIRQL NewIrql) //主要函數 { if (NewIrql >= PROFILE_LEVEL) //如果所要降到的中斷請求級大於PROFILE_LEVEL,則直接設置當前的中斷請求級 { KeGetPcr()->Irql = NewIrql; return; } HalpExecuteIrqs(NewIrql); if (NewIrql >= DISPATCH_LEVEL) //如果所要降到的中斷請求級大於DISPATCH_LEVEL,則直接設置當前的中斷請求級 { KeGetPcr()->Irql = NewIrql; return; } //NewIrql低於DISPATCH_LEVEL KeGetPcr()->Irql = DISPATCH_LEVEL; //所要降到的中斷請求級小於DISPATCH_LEVEL,設置當前的中斷請求級為DISPATCH_LEVEL, //然後掃描dpc隊列,如果不為空,則觸發dpc軟件中斷 if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST]) { //DPC請求隊列非空 ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; KiDispatchInterrupt(); } KeGetPcr()->Irql = APC_LEVEL; //所要降到的中斷請求級小於APC_LEVEL,設置當前的中斷請求級為APC_LEVEL, //然後掃描apc隊列,如果不為空,則觸發apc軟件中斷 if (NewIrql == APC_LEVEL) { return; } //NewIrql低於APC_LEVEL if (KeGetCurrentThread() != NULL && KeGetCurrentThread()->ApcState.KernelApc Pending) { KiDeliverApc(KernelMode, NULL, NULL); } KeGetPcr()->Irql = PASSIVE_LEVEL; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- jpg 改 rar
windows內核情景分析之—— KeRaiseIrql函數與KeLowerIrql()函數