標籤:tps class 提升 failed flow tca pki int() 變數
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()函數