WIN2000下修改KERNEL MODE地址区的数据

陆麟
转载请征得作者同意.
2000.3.12



出差了几天,今天继续写个小点的东西,NT LOGON留到过两天空点时候写.
大家如果用过我的HALPATCH,就会发现,HALPATCH在WIN2000中已经不能使用了.这是怎么回事呢?
嘿嘿,原来MS把KERNEL MODE的代码数据的页属性改成READONLY了.NT的内存管理器对于用户模式的代码修改系统代码页的指令发出时,会截获该指令并且提示出错,应用程序违规,杀调应用程序.但是,对于KERNEL MODE发出的类似指令则没有相应的处理机制.因为KERNEL MODE发出的任何指令都被认为是可信任的,符合NT所有规范的.当KERNEL MODE的DRIVER发出违例指令后,系统由于无法处理导致当机.
现在,老爷我就是要从KERNEL MODE修改系统代码.那么先看看NUMEGA如何处理吧.:)
NUMEGA通过OS在注册表里的微调选项改变整个NT的内存保护策略.因为NUMEGA的SOFTICE要修改键盘DRIVER的代码.:)但是NUMEGA的方法并不是我需要的.因为我不想破坏OS的整体策略.:)
现在,就公布我的代码吧.:)X86系列CPU内部的CR0位16乃是WP位.该位如果被置0,则RING0代码可以修改任意地址的数据(当然必须有物理页对应.)无论该地址对应的页是否为写保护.:)那么我们所要干的是在需要的时候让自己的代码拥有该权限,而不需要时,仍然恢复系统内存保护策略.
看如下汇编代码:

.586p
BLD_COFF EQU 1
.model flat
.data
CR0VALUE DD 0
.code

public _DisableProtection@0,_EnableProtection@0
_DisableProtection@0 Proc
mov eax,cr0
mov CR0VALUE,eax
and eax,0fffeffffh
mov cr0,eax
ret
_DisableProtection@0 endp

_EnableProtection@0 Proc
mov eax,CR0VALUE
mov cr0,eax
ret
_EnableProtection@0 endp

END
在需要的时候可以调用该PROC.:)看HALPATCH FOR WIN2000版的框架代码.:)该代码已经在我的完整版的HALPATCH使用了.:)并且同样可以运行于NT4上.:)

extern void HalProcessorIdle(void);
extern void EnableProtection(void);
extern void DisableProtection(void);

DriverEntry(PDRIVER_OBJECT pdrv,PUNICODE_STRING pus){
 //... Init and modify privalege
 DisableProtection();

 p=(int*)HalProcessorIdle;
 (int)p+=2;
 q=(int**)(*p);
 if (**q==0xccc3f4fb){
  **q=0xccc390fb;
 }
 //Restor old setting.:)
     EnableProtection();
 return 0;
}