【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)

1、创建注册表项和子项

VOID RegCreateText()
{
	HANDLE hKey;
	HANDLE hSubkey;
	NTSTATUS status;
	OBJECT_ATTRIBUTES oa;
	ULONG ulRet;
	UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey");
	UNICODE_STRING SubPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey\\SubKey");
	InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	status = ZwCreateKey(&hKey, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &ulRet);
	if (NT_SUCCESS(status))
	{
		if (ulRet == REG_CREATED_NEW_KEY)
		{
			KdPrint(("项不存在创建成功\n"));
		}
		else
		{
			KdPrint(("项存在,打开它\n"));
		}
	}
	else
	{
		KdPrint(("创建注册表项失败\n"));
	}

	InitializeObjectAttributes(&oa, &SubPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	status = ZwCreateKey(&hSubkey, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &ulRet);
	if (NT_SUCCESS(status))
	{
		if (ulRet == REG_CREATED_NEW_KEY)
		{
			KdPrint(("子项不存在创建成功\n"));
		}
		else if(ulRet == REG_OPENED_EXISTING_KEY)
		{
			KdPrint(("子项存在,打开它\n"));
		}
	}
	else
	{
		KdPrint(("创建注册表子项是失败\n"));
	}
	ZwClose(hKey);
	ZwClose(hSubkey);
}

2、打开注册表、修改注册表并读取注册表的信息

VOID RegTest()
{
	HANDLE hKey;
	NTSTATUS status;
	OBJECT_ATTRIBUTES oa;
	UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey");
	UNICODE_STRING ValueName;
	DWORD Value = -1;
	CHAR buffer[] = "hello world" ;
	PKEY_VALUE_PARTIAL_INFORMATION pvpi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 1024);
	ULONG Length;
	InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &oa);
	if (NT_SUCCESS(status))
	{
		KdPrint(("打开成功\n"));
	}
	else
	{
		KdPrint(("打开失败\n"));
	}
	//修改注册表
	RtlInitUnicodeString(&ValueName, L"字符串");
	ZwSetValueKey(hKey, &ValueName, 0, REG_SZ, L"你好", wcslen(L"你好") * sizeof(WCHAR));
	
	RtlInitUnicodeString(&ValueName, L"整数");
	ZwSetValueKey(hKey, &ValueName, 0, REG_DWORD, &Value, sizeof(DWORD));

	RtlInitUnicodeString(&ValueName, L"二进制");
	ZwSetValueKey(hKey, &ValueName, 0, REG_BINARY, buffer, strlen(buffer));

	//读取字符串
	RtlZeroMemory(pvpi, 1024);
	RtlInitUnicodeString(&ValueName, L"字符串");
	ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
	if (pvpi->Type == REG_SZ)
	{
		KdPrint(("%ls\n", pvpi->Data));
	}

	//读取整数
	RtlZeroMemory(pvpi, 1024);
	RtlInitUnicodeString(&ValueName, L"整数");
	ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
	if (pvpi->Type == REG_DWORD)
	{
		KdPrint(("%d\n", *(PULONG)pvpi->Data));
	}

	//读取二进制
	RtlZeroMemory(pvpi, 1024);
	RtlInitUnicodeString(&ValueName, L"二进制");
	ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
	if (pvpi->Type == REG_BINARY)
	{
		KdPrint(("%s\n", pvpi->Data));
	}
}

3、枚举注册表子项

VOID RegEnumTest()
{
	HANDLE hkey;
	NTSTATUS status;
	ULONG Length;
	ULONG Index;

	OBJECT_ATTRIBUTES oa;	//对象属性
	//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
	UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
	InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);	//初始化对象属性信息
	
	PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024);		//分配内存
	PKEY_BASIC_INFORMATION pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 1024);	//分配内存
	PKEY_VALUE_FULL_INFORMATION pvpi = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024);

	status = ZwOpenKey(&hkey, KEY_ALL_ACCESS, &oa);		//打开注册表
	if (!NT_SUCCESS(status))
	{
		KdPrint(("打开注册表失败\n"));
		return;
	}
	status = ZwQueryKey(hkey, KeyFullInformation, pfi, 1024, &Length);	//查询注册表
	if (NT_SUCCESS(status))
	{
		KdPrint(("***********************************\n"));
		for (Index = 0; Index < pfi->SubKeys; Index++)	//遍历所有子项
		{
			RtlZeroMemory(pbi, 1024);
			ZwEnumerateKey(hkey, Index, KeyBasicInformation, pbi, 1024, &Length);	//枚举出注册表子项的基本信息
			if (NT_SUCCESS(status))
			{
				KdPrint(("%ls\n", pbi->Name));	//输出子项的名称
			}
		}
		KdPrint(("***********************************\n"));
		for (Index = 0; Index < pfi->Values; Index++)	//遍历所有子项的值
		{
			RtlZeroMemory(pvpi, 1024);
			status = ZwEnumerateValueKey(hkey, Index, KeyValueFullInformation, pvpi, 1024, &Length);	//枚举出注册表子项的值
			if (NT_SUCCESS(status))
			{
				switch (pvpi->Type)
				{
				case REG_DWORD:
					KdPrint(("%ls:%d\n", pvpi->Name, *(PULONG)((PCHAR)pvpi + pvpi->DataOffset)));
					break;
				case REG_SZ:
				case REG_MULTI_SZ:
				case REG_EXPAND_SZ:
					KdPrint(("%ls:%ls\n", pvpi->Name, (PCHAR)pvpi + pvpi->DataOffset));
					break;
				default:
					break;
				}
			}
		}
	}
	ZwClose(hkey);
	if (pfi != NULL)
	{
		ExFreePool(pfi);
	}
	if (pbi != NULL)
	{
		ExFreePool(pbi);
	}
	if (pvpi != NULL)
	{
		ExFreePool(pvpi);
	}
}

4、代码实现效果图
(1)注册表的创建、打开、修改、读取
在这里插入图片描述
(2)注册表子项的枚举
在这里插入图片描述
补充:
也可使用微软封装的RTL函数来进行注册表的相关操作。
请添加图片描述

//微软封装的RTL函数
VOID RtlTest()
{ 
	NTSTATUS status;
	status = RtlCreateRegistryKey(RTL_REGISTRY_SERVICES, L"MyService");
	if (NT_SUCCESS(status))
	{
		KdPrint(("Rtl创建子项成功\n"));
	}
	status = RtlCheckRegistryKey(RTL_REGISTRY_SERVICES, L"MyService");
	if (NT_SUCCESS(status))
	{
		KdPrint(("注册表子项存在\n"));
	}
	status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, L"MyService", L"字符串", REG_SZ, L"你好世界", 8);
	if (NT_SUCCESS(status))
	{
		KdPrint(("写入成功\n"));
	}

	status = RtlDeleteRegistryValue(RTL_REGISTRY_SERVICES, L"MyService", L"字符串");
	if (NT_SUCCESS(status))
	{
		KdPrint(("删除成功\n"));
	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邢饱饱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值