(十)、内核模式下的注册表操作
一、创建打开注册表
1、创建注册表
创建一个注册表项
CreateOption:
我们一般选择REG_OPTION_NON_VOLATILE,注册表的创建保存是非易失性的
Disposition:
2、打开注册表
打开现有的注册表
二、添加项与修改注册表
1、修改注册表
ValueName: 要写入数据项的项名
Data:要写入的数据
2、读取注册表的值
ZwQueryValueKey
三、枚举注册表
1、枚举子项
KEY,子项,值
2、枚举值
四、删除注册表项与值
这两个函数比较简单,就没有做实验
五、注册表函数的封装
RtlCreateRegistryKey
看,这些函数把之前的注册表函数分装的很简单
代码
#include <ntddk.h> VOID Unload(PDRIVER_OBJECT driver) { DbgPrint("Driver Unload\n"); } VOID regeditTest1() { HANDLE hKey; NTSTATUS status; OBJECT_ATTRIBUTES oa; ULONG ulRet; UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey"); 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)) { DbgPrint("失败\n"); } else { if (ulRet == REG_CREATED_NEW_KEY) { DbgPrint("创建新项成功\n"); } else if (ulRet == REG_OPENED_EXISTING_KEY) { DbgPrint("该项已存在,打开它\n"); } } ZwClose(hKey); //完成后在注册表上SOFTWARE子目录下就会多出来一项MyKey// } VOID regeditTest2() { NTSTATUS status; HANDLE hKey; OBJECT_ATTRIBUTES oa; UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey"); UNICODE_STRING ValueName; WCHAR Buffer[] = { L"HelloWorld" }; InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &oa); if (NT_SUCCESS(status)) { DbgPrint("打开成功\n"); } else { DbgPrint("打开失败\n"); } RtlInitUnicodeString(&ValueName, L"字符串"); ZwSetValueKey(hKey, &ValueName, 0, REG_SZ, L"你好", wcslen(L"你好")*sizeof(WCHAR)); ZwSetValueKey(hKey, &ValueName, 0, REG_BINARY, Buffer, wcslen(Buffer)); ULONG leng; PKEY_VALUE_PARTIAL_INFORMATION pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool, 1024); RtlZeroMemory(pvpi, 1024); ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &leng); if (pvpi->Type == REG_BINARY) { DbgPrint("%x\n", *(PULONG)pvpi->Data); //只是输出了四个字节大小的二进制数据,但也达到了验证效果// } ZwClose(hKey); } VOID regeditTest3() { HANDLE hKey; NTSTATUS status; OBJECT_ATTRIBUTES oa; ULONG length; ULONG Index; UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control"); PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024); InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &oa); if (!NT_SUCCESS(status)) { return; } PKEY_BASIC_INFORMATION pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 1024); status = ZwQueryKey(hKey, KeyFullInformation, pfi, 1024, &length); //枚举项// if (NT_SUCCESS(status)) { for (int i = 0; i < (int)pfi->SubKeys; i++) //SubKeys:子健数// { RtlZeroMemory(pbi, 1024); status = ZwEnumerateKey(hKey, i, KeyBasicInformation, pbi, 1024, &length); if (NT_SUCCESS(status)) { DbgPrint("%ls\n", pbi->Name); } } } PKEY_VALUE_FULL_INFORMATION pvpi = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024); RtlZeroMemory(pvpi, 1024); //枚举值// for (int i = 0; i < (int)pfi->Values; i++) { RtlZeroMemory(pvpi, 1024); status = ZwEnumerateValueKey(hKey, i, KeyValueFullInformation, pvpi, 1024, &length); //枚举的值是(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control")这一项的的值// if (NT_SUCCESS(status)) { switch (pvpi->Type) { case REG_DWORD: DbgPrint("%ls: %d\n", pvpi->Name, *(PULONG)((PCHAR)pvpi + pvpi->DataOffset)); break; case REG_EXPAND_SZ: DbgPrint("%ls: %ls\n", pvpi->Name, (PCHAR)pvpi + pvpi->DataOffset); break; default: break; } } } ZwClose(hKey); if (pfi) { ExFreePool(pfi); } if (pbi) { ExFreePool(pbi); } if (pvpi) { ExFreePool(pvpi); } } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); //regeditTest1(); //regeditTest2(); regeditTest3();//枚举项与值// driver->DriverUnload = Unload; return STATUS_SUCCESS; }