x64回调监控注册表
发布日期:2021-06-29 01:11:26
浏览次数:3
分类:技术文章
本文共 8169 字,大约阅读时间需要 27 分钟。
x86下可以使用hook技术,x64下使用回调监控。
主要函数CmRegisterCallback(RegistryCallback, NULL, &CmHandle);
原型
NTSTATUS CmRegisterCallback( PEX_CALLBACK_FUNCTION Function, PVOID Context, PLARGE_INTEGER Cookie);
第一个参数就是我们的回调函数,自己想实现的逻辑就是在这里写,中间这个微软的解释是A driver-defined value that the configuration manager will pass as the CallbackContext parameter to the RegistryCallback routine,配置管理器将作为CallbackContext参数传递给RegistryCallback例程的驱动程序定义的值,我目前没用到过,最后一个是指向LARGE_INTEGER变量的指针,该变量接收标识回调例程的值。取消注册回调例程时,将此值作为Cookie参数传递给CmUnRegisterCallback。关闭注册表回调会用到。
第一个参数也就是我们实现的函数申明如下
NTSTATUS RegistryCallback( IN PVOID CallbackContext, IN PVOID Argument1,//操作类型, IN PVOID Argument2//操作的结构体指针)
也就是第二个参数是操作注册表的类型,然后操作内容等可以通过第三个参数拿到,下面是我进行操作的监控代码demo片段
NTSTATUS RegistryCallback( IN PVOID CallbackContext, IN PVOID Argument1,//操作类型, IN PVOID Argument2//操作的结构体指针){ if (!isOpenReg) { return STATUS_SUCCESS; } ULONG Options = 0;//记录操作类型 4创建,5删除,6设置键值,7删除键值,8重命名键 BOOLEAN isAllow = TRUE;//是否放行 PFQDRV_NOTIFICATION notification = NULL; ULONG replyLength = 0; BOOLEAN SafeToOpen; SafeToOpen = TRUE; NTSTATUS status = STATUS_SUCCESS; long type; NTSTATUS CallbackStatus = STATUS_SUCCESS; UNICODE_STRING registryPath; registryPath.Length = 0; registryPath.MaximumLength = 2048 * sizeof(WCHAR); registryPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, registryPath.MaximumLength, REGISTRY_POOL_TAG); notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(FQDRV_NOTIFICATION), 'nacS'); if (NULL == notification) { CallbackStatus = STATUS_INSUFFICIENT_RESOURCES; return CallbackStatus; } if (registryPath.Buffer == NULL) return STATUS_SUCCESS; type = (REG_NOTIFY_CLASS)Argument1; switch (type) { case RegNtPreCreateKeyEx: //出现两次是因为一次是OpenKey,一次是createKey { if (IsProcessName("regedit.exe", PsGetCurrentProcess())) { GetRegistryObjectCompleteName(®istryPath, NULL, ((PREG_CREATE_KEY_INFORMATION)Argument2)->RootObject); DbgPrint("[RegNtPreCreateKeyEx]KeyPath: %wZ", ®istryPath); //新键的路径 DbgPrint("[RegNtPreCreateKeyEx]KeyName: %wZ", ((PREG_CREATE_KEY_INFORMATION)Argument2)->CompleteName);//新键的名称 notification->Operation = 4; char newPath[MAX_PATH] = { 0 }; WCHAR newPath1[MAX_PATH] = { 0 }; UnicodeToChar(®istryPath, newPath); CharToWchar(newPath, newPath1); wcscpy_s(notification->ProcessPath, MAX_PATH, newPath1); char newName[MAX_PATH] = { 0 }; WCHAR newName1[MAX_PATH] = { 0 }; UnicodeToChar(((PREG_CREATE_KEY_INFORMATION)Argument2)->CompleteName, newName); CharToWchar(newName, newName1); wcscpy_s(notification->TargetPath, MAX_PATH, newName1); replyLength = sizeof(FQDRV_REPLY); status = FltSendMessage(FQDRVData.Filter, &FQDRVData.ClientPort, notification, sizeof(FQDRV_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_SUCCESS == status) { SafeToOpen = ((PFQDRV_REPLY)notification)->SafeToOpen; if (SafeToOpen) { CallbackStatus = STATUS_SUCCESS; } else { CallbackStatus = STATUS_ACCESS_DENIED; } } //CallbackStatus = STATUS_ACCESS_DENIED; } break; } case RegNtPreDeleteKey: { if (IsProcessName("regedit.exe", PsGetCurrentProcess())) { GetRegistryObjectCompleteName(®istryPath, NULL, ((PREG_DELETE_KEY_INFORMATION)Argument2)->Object); DbgPrint("[RegNtPreDeleteKey]%wZ", ®istryPath); //新键的路径 notification->Operation = 5; char newPath[MAX_PATH] = { 0 }; WCHAR newPath1[MAX_PATH] = { 0 }; UnicodeToChar(®istryPath, newPath); CharToWchar(newPath, newPath1); wcscpy_s(notification->ProcessPath, MAX_PATH, newPath1); replyLength = sizeof(FQDRV_REPLY); status = FltSendMessage(FQDRVData.Filter, &FQDRVData.ClientPort, notification, sizeof(FQDRV_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_SUCCESS == status) { SafeToOpen = ((PFQDRV_REPLY)notification)->SafeToOpen; if (SafeToOpen) { CallbackStatus = STATUS_SUCCESS; } else { CallbackStatus = STATUS_ACCESS_DENIED; } } //CallbackStatus = STATUS_ACCESS_DENIED; } break; } case RegNtPreSetValueKey: { if (IsProcessName("regedit.exe", PsGetCurrentProcess())) { GetRegistryObjectCompleteName(®istryPath, NULL, ((PREG_SET_VALUE_KEY_INFORMATION)Argument2)->Object); DbgPrint("[RegNtPreSetValueKey]KeyPath: %wZ", ®istryPath); DbgPrint("[RegNtPreSetValueKey]ValName: %wZ", ((PREG_SET_VALUE_KEY_INFORMATION)Argument2)->ValueName); notification->Operation = 6; char newPath[MAX_PATH] = { 0 }; WCHAR newPath1[MAX_PATH] = { 0 }; UnicodeToChar(®istryPath, newPath); CharToWchar(newPath, newPath1); wcscpy_s(notification->ProcessPath, MAX_PATH, newPath1); char newName[MAX_PATH] = { 0 }; WCHAR newName1[MAX_PATH] = { 0 }; UnicodeToChar(((PREG_SET_VALUE_KEY_INFORMATION)Argument2)->ValueName, newName); CharToWchar(newName, newName1); wcscpy_s(notification->TargetPath, MAX_PATH, newName1); replyLength = sizeof(FQDRV_REPLY); status = FltSendMessage(FQDRVData.Filter, &FQDRVData.ClientPort, notification, sizeof(FQDRV_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_SUCCESS == status) { SafeToOpen = ((PFQDRV_REPLY)notification)->SafeToOpen; if (SafeToOpen) { CallbackStatus = STATUS_SUCCESS; } else { CallbackStatus = STATUS_ACCESS_DENIED; } } //CallbackStatus = STATUS_ACCESS_DENIED; } break; } case RegNtPreDeleteValueKey: { if (IsProcessName("regedit.exe", PsGetCurrentProcess())) { GetRegistryObjectCompleteName(®istryPath, NULL, ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->Object); DbgPrint("[RegNtPreDeleteValueKey]KeyPath: %wZ", ®istryPath); DbgPrint("[RegNtPreDeleteValueKey]ValName: %wZ", ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName); notification->Operation = 7; char newPath[MAX_PATH] = { 0 }; WCHAR newPath1[MAX_PATH] = { 0 }; UnicodeToChar(®istryPath, newPath); CharToWchar(newPath, newPath1); wcscpy_s(notification->ProcessPath, MAX_PATH, newPath1); char newName[MAX_PATH] = { 0 }; WCHAR newName1[MAX_PATH] = { 0 }; UnicodeToChar(((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName, newName); CharToWchar(newName, newName1); wcscpy_s(notification->TargetPath, MAX_PATH, newName1); replyLength = sizeof(FQDRV_REPLY); status = FltSendMessage(FQDRVData.Filter, &FQDRVData.ClientPort, notification, sizeof(FQDRV_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_SUCCESS == status) { SafeToOpen = ((PFQDRV_REPLY)notification)->SafeToOpen; if (SafeToOpen) { CallbackStatus = STATUS_SUCCESS; } else { CallbackStatus = STATUS_ACCESS_DENIED; } } //CallbackStatus = STATUS_ACCESS_DENIED; } break; } case RegNtPreRenameKey: { if (IsProcessName("regedit.exe", PsGetCurrentProcess())) { GetRegistryObjectCompleteName(®istryPath, NULL, ((PREG_RENAME_KEY_INFORMATION)Argument2)->Object); DbgPrint("[RegNtPreRenameKey]KeyPath: %wZ", ®istryPath); DbgPrint("[RegNtPreRenameKey]NewName: %wZ", ((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName); notification->Operation = 8; char newPath[MAX_PATH] = { 0 }; WCHAR newPath1[MAX_PATH] = { 0 }; UnicodeToChar(®istryPath, newPath); CharToWchar(newPath, newPath1); wcscpy_s(notification->ProcessPath, MAX_PATH, newPath1); char newName[MAX_PATH] = { 0 }; WCHAR newName1[MAX_PATH] = { 0 }; UnicodeToChar(((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName, newName); CharToWchar(newName, newName1); wcscpy_s(notification->TargetPath, MAX_PATH, newName1); replyLength = sizeof(FQDRV_REPLY); status = FltSendMessage(FQDRVData.Filter, &FQDRVData.ClientPort, notification, sizeof(FQDRV_NOTIFICATION), notification, &replyLength, NULL); if (STATUS_SUCCESS == status) { SafeToOpen = ((PFQDRV_REPLY)notification)->SafeToOpen; if (SafeToOpen) { CallbackStatus = STATUS_SUCCESS; } else { CallbackStatus = STATUS_ACCESS_DENIED; } } //CallbackStatus = STATUS_ACCESS_DENIED; } break; } //『注册表编辑器』里的“重命名键值”是没有直接函数的,是先SetValueKey再DeleteValueKey default: break; } if (registryPath.Buffer != NULL) ExFreePoolWithTag(registryPath.Buffer, REGISTRY_POOL_TAG); return CallbackStatus;}
转载地址:https://blog.csdn.net/youyou519/article/details/96454731 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月17日 19时19分39秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
IP代理池之验证是否有效
2019-04-29
python反爬虫之搭建IP代理池
2019-04-29
python爬取回车桌面图片
2019-04-29
python实现简单爬虫功能
2019-04-29
99%的人都不知道的pandas骚操作(一)
2019-04-29
24式加速你的Python
2019-04-29
Scrapy爬取银行理财产品信息(共12多万条)并存入MongoDB
2019-04-29
python贪吃蛇源码分享
2019-04-29
Python爬取网易云音乐播放地址
2019-04-29
python使用selenium + PhantomJs搭建的简单漫画爬虫工具
2019-04-29
python爬取 B 站全站视频信息
2019-04-29
推荐10款最好的Python开发编辑器
2019-04-29
python爬取天天基金网所有基金数据
2019-04-29
python爬取豆瓣排行榜电影数据(含GUI界面版)
2019-04-29
python一键生成微信个人专属数据报告,了解你的微信社交历史
2019-04-29
python主从分布式爬虫
2019-04-29
Python爬虫下载Bilibili番剧弹幕
2019-04-29
python科学计算与可视化
2019-04-29
python好玩的词云和Jieba库的使用
2019-04-29
python Ajax数据爬取简介
2019-04-29