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); } }
、代码实现效果图
(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")); } }