CmRegisterCallback监控注册表框架

本文介绍了一个使用CmRegisterCallback函数来监控Windows注册表更改的驱动程序实现。通过注册回调,可以跟踪特定的注册表操作,如删除键和删除值。文章详细展示了如何获取注册表项的完整路径,并在卸载驱动程序时正确释放资源。

首先用CmRegisterCallback注册注册表回调
记得在Unload函数里面释放注册的回调
RegNtPreDeleteKey:
RegNtPreDeleteValueKey:
这里我只监控了上面两个动作

#include <ntddk.h>

#define REGISTRY_POOL_TAG 'lxw'

LARGE_INTEGER	cookie;

NTKERNELAPI NTSTATUS ObQueryNameString
(
IN  PVOID Object,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN  ULONG Length,
OUT PULONG ReturnLength
);

NTKERNELAPI NTSTATUS RtlUnicodeStringCopy
(
__out  PUNICODE_STRING DestinationString,
__in   PUNICODE_STRING SourceString
);


NTSTATUS	Unload(PDRIVER_OBJECT driver)
{
	DbgPrint("unload driver");
	CmUnRegisterCallback(cookie);
	return STATUS_SUCCESS;
}

BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING pRegistryPath, PUNICODE_STRING pPartialRegistryPath, PVOID pRegistryObject)
{
	BOOLEAN foundCompleteName = FALSE;
	BOOLEAN partial = FALSE;
	if ((!MmIsAddressValid(pRegistryObject)) || (pRegistryObject == NULL))
		return FALSE;
	/* Check to see if the partial name is really the complete name */
	if (pPartialRegistryPath != NULL)
	{
		if ((((pPartialRegistryPath->Buffer[0] == '\\') || (pPartialRegistryPath->Buffer[0] == '%')) ||
			((pPartialRegistryPath->Buffer[0] == 'T') && (pPartialRegistryPath->Buffer[1] == 'R') &&
			(pPartialRegistryPath->Buffer[2] == 'Y') && (pPartialRegistryPath->Buffer[3] == '\\'))))
		{
			RtlCopyUnicodeString(pRegistryPath, pPartialRegistryPath);
			partial = TRUE;
			foundCompleteName = TRUE;
		}
	}
	if (!foundCompleteName)
	{
		/* Query the object manager in the kernel for the complete name */
		NTSTATUS status;
		ULONG returnedLength;
		PUNICODE_STRING pObjectName = NULL;
		status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, 0, &returnedLength);
		if (status == STATUS_INFO_LENGTH_MISMATCH)
		{
			pObjectName = ExAllocatePoolWithTag(NonPagedPool, returnedLength, REGISTRY_POOL_TAG);
			status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, returnedLength, &returnedLength);
			if (NT_SUCCESS(status))
			{
				RtlCopyUnicodeString(pRegistryPath, pObjectName);
				foundCompleteName = TRUE;
			}
			ExFreePoolWithTag(pObjectName, REGISTRY_POOL_TAG);
		}
	}
	return foundCompleteName;
}

NTSTATUS RegistryCallback(
	IN PVOID CallbackContext,
	IN PVOID Argument1,//操作类型,
	IN PVOID Argument2//操作的结构体指针
)
{
	long type;
	NTSTATUS	CallbackStatus = STATUS_SUCCESS;
	UNICODE_STRING	RegPath;
	DbgPrint("Enter RegCallback Success");
	RegPath.Length = 0;
	RegPath.MaximumLength = 2048 * sizeof(WCHAR);
	RegPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, RegPath.MaximumLength, REGISTRY_POOL_TAG);
	if (RegPath.Buffer == NULL)
		return STATUS_SUCCESS;
	type = (REG_NOTIFY_CLASS)Argument1;
	switch (type)
	{
	case	RegNtPreDeleteKey:
		GetRegistryObjectCompleteName(&RegPath, NULL, ((PREG_DELETE_KEY_INFORMATION)Argument2)->Object);
		DbgPrint("DeleteKey:%wZ", RegPath);
		break;
	case	RegNtPreDeleteValueKey:
		GetRegistryObjectCompleteName(&RegPath, NULL, ((PREG_DELETE_KEY_INFORMATION)Argument2)->Object);
		DbgPrint("DeleteValueValName: %wZ", ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName);
		DbgPrint("DeleteValue:%wZ", RegPath);
		//return STATUS_ACCESS_DENIED;//防止删除键
		break;
	default:
		break;
	}
	if (RegPath.Buffer != NULL){
		ExFreePoolWithTag(RegPath.Buffer, REGISTRY_POOL_TAG);
	}
	return CallbackStatus;
}

NTSTATUS	DriverEntry(PDRIVER_OBJECT	driver, PUNICODE_STRING	RegPath)
{
	DbgPrint("Driver Entry");
	
	driver->DriverUnload = Unload;

	CmRegisterCallback(RegistryCallback, NULL, &cookie);
	return STATUS_SUCCESS;
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值