所谓0x80000000内存,还是线性地址也就是虚拟地址,而不是物理地址。在非GUI线程中win32k.sys没有映射到虚拟地址,所以这样的线程寻址不到它。
至于HOOK,不存在“HOOK不就没用了”的问题。
要说清这个问题,首先应该说明用户态情况下的模块和内核模块的内存映射上的不同。
用户态模块如ntdll.dll,是有Copy on Write机制的,也就是当在用户态写ntdll.dll等dll模块的内存(对函数进行HOOK)时,系统“拷贝”一份DLL模块映像的新“备份”,把这个“备份”映像给程序,所以程序对这个“备份”的写入效果只对自身进程有效,其他进程所访问的ntdll.dll在物理地址上是另一个“备份”,所以不受影响。
而内核模块如ntoskrnl.exe和win32k.sys等,没有Copy On Write机制,也就是说所有内核线程访问到的ntoskrnl.exe模块,都对应于物理地址上同一个区域,因此对这个区域的写入操作,影响的就是所有线程。win32k.sys也是同样的。只不过对非GUI线程,由于其没有加载win32k.sys,所以win32k.sys没有映射到其线性地址中,所以访问不到。而对于GUI线程,win32k.sys有被映像到其线性地址中,可以访问到,而对它的写入操作影响也是全局性的。