1. 程式人生 > >windows內核情景分析之—— KeRaiseIrql函數與KeLowerIrql()函數

windows內核情景分析之—— KeRaiseIrql函數與KeLowerIrql()函數

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()函數