概述
点击打开链接
由于Windows需要支持多个CPU, 因此Windows内核中为此定义了一套以处理器控制区(Processor Control Region)即KPCR为枢纽的数据结构, 使每个CPU都有个KPCR. 其中KPCR这个结构中有一个域KPRCB(Kernel Processor Control Block)结构, 这个结构扩展了KPCR. 这两个结构用来保存与线程切换相关的全局信息.
通常fs段寄存器在内核模式下指向KPCR, 用户模式下指向TEB.
KPCR结构如下:
其中比较重要的是KdVersionBlock这个指针, 它指向一个DBGKD_GET_VERSION64这个结构.
这个结构体里面包含了一些重要信息。如:PsLoadedModuleList ,它是Windows加载的所有内核模块构成的链表的表头。
由此可以看到,两个处理器对应的KPCR结构是有区别的,只有第一个处理器的KPCR域KdVersionBlock才指向DBGKD_GET_VERSION64这个结构。
下面我们通过具体的代码举个例子,通过KPCR枚举到Ntoskrnl的基地址:
- /*
- * AUTHOR : 莫灰灰
- * BLOG : http://blog.csdn.net/hu3167343
- * DESCRIBE : KPCR->KdVersionBlock->PsLoadedModuleList->ntoskrnl base address
- */
- #include "ntddk.h"
- NTKERNELAPI VOID KeSetSystemAffinityThread ( KAFFINITY Affinity );
- NTKERNELAPI VOID KeRevertToUserAffinityThread ( VOID );
- VOID
- DriverUnload(IN PDRIVER_OBJECT pDriverObj)
- {
- KdPrint(("Unloaded Successrn"));
- return;
- }
- NTSTATUS
- DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
- {
- NTSTATUS status = STATUS_SUCCESS;
- ULONG FSAddr;
- pDriverObj->DriverUnload = DriverUnload;
- KeSetSystemAffinityThread(1); //使当前线程运行在第一个处理器上
- __asm{
- push eax
- mov eax, fs:[0x34] ;得到KdVersionBlock的地址
- add eax,18h ;得到指向PsLoadedModuleList的地址
- mov eax,[eax] ;得到PsLoadedModuleList的地址
- mov eax,[eax] ;取出PsLoadedModuleList里面的内容, 即KLDR_DATA_TABLE_ENTRY结构
- mov eax,[eax+18h] ;取出DllBase, 即ntoskrnl.exe的基地址
- mov FSAddr, eax
- pop eax
- }
- KeRevertToUserAffinityThread();//恢复线程运行的处理器
- KdPrint(("0x%08Xn", FSAddr));
- return STATUS_SUCCESS;
- }
最后
以上就是忧郁萝莉为你收集整理的KPRC的全部内容,希望文章能够帮你解决KPRC所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复