windows内核情景分析之—— KeRaiseIrql函数与KeLowerIrql()函数

本文主要探讨Windows内核中的KeRaiseIrql和KeLowerIrql函数。KeRaiseIrql通过调用hal模块的KfRaiseIrql函数提升IRQL,提升条件包括HalpEnableIrqlAudit为0或NewIrql大于等于OldIrql。而KeLowerIrql函数用于降低IRQL。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 值
}

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;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值