遍历注册表回调函数(仿PCHunter CmpBack)
typedef struct _CAPTURE_REGISTRY_MANAGER
{
PDEVICE_OBJECT deviceObject;
BOOLEAN bReady;
LARGE_INTEGER registryCallbackCookie;
LIST_ENTRY lQueuedRegistryEvents;
KTIMER connectionCheckerTimer;
KDPC connectionCheckerFunction;
KSPIN_LOCK lQueuedRegistryEventsSpinLock;
ULONG lastContactTime;
} CAPTURE_REGISTRY_MANAGER, *PCAPTURE_REGISTRY_MANAGER;
系统注册表回调函数注册流程
调用CmRegisterCallback
第一个参数就是 回调函数地址
第二个参数是 PCAPTURE_REGISTRY_MANAGER 指针
CmRegisterCallback内部会操作两个全局变量
CmpCallBackCount 注册表回调函数数组总数
CallbackListHead 注册表回调函数数组头部(每个元素是 LIST_ENTRY 对象 ->Blink 指向ExAllocatePoolWithTag申请的一个地址 为了方便这里简称Ha)
Ha+0x18 = 上面说的 CmRegisterCallback 函数的第二个参数
Ha+0x1C = 上面说的 CmRegisterCallback 函数的第一个参数
这样就可以依靠 上面的两个全局变量 遍历出来 注册表回调函数
代码(只放出重要部分)
vntoskrnlBaseAddr 内核模块基地址(ntoskn...模块)
//回调函数数组
ULONG vCmpCallBackCount = *vPCmpCallBackCount;
PLIST_ENTRY vPCallbackListHead = (PLIST_ENTRY)(vntoskrnlBaseAddr + 0x167F70);
while (vCmpCallBackCount)
{
KdPrint(("vPCallbackListHead->Flink = 0x%08X ", vPCallbackListHead->Flink));
ULONG vExAllocateAddr = (ULONG)vPCallbackListHead->Flink;
KdPrint(("CaptrueRegisterManager = 0x%08X ", *(PULONG)(vExAllocateAddr + 0x18)));
KdPrint(("RegistryCallbackFunction = 0x%08X ", *(PULONG)(vExAllocateAddr + 0x1C)));
KdPrint((" -------------------------------------------------------------- "));
vPCallbackListHead++;
vCmpCallBackCount--;
}
jpg 改 rar