驱动层hook系统函数的时,如何屏蔽掉只读属性?
对于Intel 80486或以上的CPU,CR0的位16是写保护(Write Proctect)标志。当设置该标志时,处理器会禁止超级用户程序(例如特权级0的程序)向只读页面执行写操作;当该位复位时则反之。因此,在写前把设置该位就可以
写完后,再把该位设置回去:
- mov cr0, eax
- sti
- 主要是设置cr0的WP(Write Protect)位来禁止内存的只读保护。使用以下两个函数设置cr0
- _inline void WPOFF()
- {
- ULONG uAttr;
- _asm
- {
- cli
- push eax
- mov eax, cr0
- mov g_uCr0, eax
- and eax, 0FFFEFFFFh // CR0 16 BIT = 0
- mov cr0, eax
- pop eax
- };
- }
-
- _inline void WPON()
- {
- _asm
- {
- push eax
- mov eax, g_uCr0 //恢復原有 CR0 屬性
- mov cr0, eax
- pop eax
- sti
- };
- }
但修改的时候要注意:
1.“提升中断请求级”到DPC,屏蔽APC和普通优先级别的中断。更重要的是防止线程调度(CPU调度程序是在DPC级别),因为修改cr0的时候被中断或切换,会造出以外的结果(蓝屏死机)。使用KeRaiseIrqlToDpcLevel提高中断请求级到DPC,KeLowerIrql恢复到原中断级。
2.对于多CPU的系统,为了防止被切换到另一个CPU上运行程序,此时要加内核锁。使用KeAcquireSpinLock函数上锁,KeReleaseSpinLock函数解锁。