zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

x64驱动 关闭&开启 写时保护

驱动保护 开启 关闭 X64
2023-09-11 14:13:59 时间

背景

在内核里想要写入“别人的”内存(一般指 NTOS 等系统模块的内存空间),需要遵守一个规则 : IRQL和内存保护。

  • IRQL称为中断请求级别,从0~31 共32个级别
  • 内存保护可以打开和关闭,如果在内存处于保护状态时写入,会导致蓝屏

一般来说,要写入“别人的”内核内存,必须关闭内存写保护,并把 IRQL提升到 2 才行(绝大多数候时候 IRQL 都为 0 ,当IRQL=2时,会阻断大部分线程执行,防止执行出错)。

内存是否处于写保护的状态记录在 CR0 寄存器上,因此直接修改CR0寄存器的值即可。而提升或降低IRQL则使用KeRaiseIrqlToDpcLevel和KeLowerIrql实现(WIN64的IRQL值记录在CR8寄存器上,而WIN32的IRQL值记录在KPCR上)。

代码示例

// 需要 #include <intrin.h>

// write protect off
KIRQL WPOFFx64()
{
	// 提高中断请求优先级到 DISPATCH_LEVEL 级别
    KIRQL irql = KeRaiseIrqlToDpcLevel();

	// 获取 cr0 寄存器中的值(cr0 控制 cpu 的操作模式)
    UINT64 cr0 = __readcr0();
    
    // 修改写保护
    cr0 &= 0xfffffffffffeffff;
    __writecr0(cr0);

	// 禁用中断
    _disable();
    return irql;
}

// write protect on
void WPONx64(KIRQL irql)
{
	// 获取 cr0 中的值
    UINT64 cr0 = __readcr0();

	// 恢复写保护
    cr0 |= 0x10000;
    __writecr0(cr0);

	// 恢复中断
    _enable();
    
    // 恢复 IRQL 到原始值
    KeLowerIrql(irql);
}