Joe1sn's Cabinet

windows内核驱动 4-内核注册表

使用内核注册表实现开机启动驱动等

内核注册表

驱动创建描述符SYM_NAME后,会出现在注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services

启动项的名字为驱动的文件名,例如hevd_2

image-20240318124522823

  • Start:2-开机自启动、3-手动启动、4-禁用,数字越小启动越早

image-20240318124919612

打开注册表ZwCreateKeyZwOpenKey

移动驱动启动位置并修改注册表

ZwCreateKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
NTSTATUS status = STATUS_SUCCESS;
HANDLE hRegKey = NULL;
OBJECT_ATTRIBUTES RegAttribute = { 0 };
ULONG KeyOp = 0;

InitializeObjectAttributes(&RegAttribute, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateKey(&hRegKey, KEY_ALL_ACCESS, &RegAttribute, 0, NULL, REG_OPTION_NON_VOLATILE, &KeyOp);
if (NT_SUCCESS(status)) {
if (KeyOp == REG_CREATED_NEW_KEY) {
DbgPrint("Create New key\n");
}
else if (KeyOp == REG_OPENED_EXISTING_KEY) {
DbgPrint("Registry key opened\n");
}
else
{
DbgPrint("Error\n");
}
}

ZwOpenKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
NTSTATUS KernelReg(PUNICODE_STRING RegistryPath) {
NTSTATUS status = STATUS_SUCCESS;
HANDLE hRegKey = NULL;
OBJECT_ATTRIBUTES RegAttribute = { 0 };
ULONG KeyOp = 0;

PVOID KeyInfo = ExAllocatePool2(POOL_FLAG_NON_PAGED, 0x1000, 'kcaH');
if (KeyInfo == NULL) {
DbgPrint("Allocate Mem Failed\n");
return status;
}
RtlZeroMemory(KeyInfo, 0x1000);
UNICODE_STRING regKeyName = { 0 };
RtlInitUnicodeString(&regKeyName, L"ImagePath");

InitializeObjectAttributes(&RegAttribute, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
//status = ZwOpenKey(&hRegKey, KEY_ALL_ACCESS, &RegAttribute, 0, NULL, REG_OPTION_NON_VOLATILE, &KeyOp);
status = ZwOpenKey(&hRegKey, KEY_ALL_ACCESS, &RegAttribute);
if (!NT_SUCCESS(status)) {
DbgPrint("Open Reg Key Failed\n");
return status;
}

status = ZwQueryValueKey(hRegKey, &regKeyName, KeyValuePartialInformation, KeyInfo, 0x1000 - 1, &KeyOp);
if (!NT_SUCCESS(status)) {
DbgPrint("Read Reg Key Failed\n");
ZwClose(hRegKey);
ExFreePool(KeyInfo);
return status;
}
PKEY_VALUE_PARTIAL_INFORMATION tempinfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo;
PWCHAR tempName = (PWCHAR)(tempinfo->Data);
DbgPrint("reg: %wZ, key: %wZ, Value: %ws\n", RegistryPath,regKeyName, tempName);

ZwClose(hRegKey);
ExFreePool(KeyInfo);
return status;
}

image-20240318134033598

再加上ZwSetValue和之前的文件复制,就能实现这个功能了,但是需要更多的技巧来提升启动时的运行位置更早。

也可以使用微软封装函数RtlWriteRegistryValue