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"));
}
}