Windows驱动开发入门-注册表管理技术

创建注册表键

ZwCreateKey

创建一个新的注册表项或打开一个现有注册表项。

1
2
3
4
5
6
7
8
9
10
11
12
13
NTSTATUS ZwCreateKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
//KEY_ALL_ACCESS所有访问权限 KEY_READ通用读权限 KEY_WRITE通用写权限
//KEY_QUERY_VALUE读键值 KEY_SET_VALUE取键值 KEY_CREATE_SUB_KEY生成子键 KEY_ENUMERATE_SUB_KEYS枚举子键
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_Reserved_ ULONG TitleIndex,
_In_opt_ PUNICODE_STRING Class,
_In_ ULONG CreateOptions,
//系统重启时注册表键不保留REG_OPTION_VOLATILE 保留REG_OPTION_NON_VOLATILE
_Out_opt_ PULONG Disposition
//指示创建了新注册表键REG_CREATED_NEW_KEY 打开一个存在的注册表键REG_OPENED_EXISTING_KEY
)//NTSTATUS码

ZwOpenKey

打开注册表键,也能被上面那个替代。

1
2
3
4
5
NTSTATUS ZwOpenKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
)

例子

内核中,注册表路径以\\Registry开头,HKEY_LOCAL_MACHINE表示为\Registry\Machine,HKEY_USER表示为\Registry\User,其他根键没有对应路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BOOLEAN MyCreateRegistryKey(UNICODE_STRING ustrRegistry) { //例如传参\\Registry\\Machine\\Software\\DemonGan
HANDLE hRegister = NULL;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
ULONG ulResult = 0;
NTSTATUS status = STATUS_SUCCESS;
// 创建或者打开已存在注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulResult);
if (!NT_SUCCESS(status))
return FALSE;
if (REG_CREATED_NEW_KEY == ulResult)
DbgPrint("The register item is createed!\n");
else if (REG_OPENED_EXISTING_KEY == ulResult)
DbgPrint("The register item has been created, and now is opened!\n");
// 关闭注册表键句柄
ZwClose(hRegister);
return TRUE;
};

ZwOpenKey只能打开但用着方便,这里不讲直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOLEAN MyOpenRegistryKey(UNICODE_STRING ustrRegistry) {
OBJECT_ATTRIBUTES objectAttributes = { 0 };
HANDLE hRegister = NULL;
NTSTATUS status = STATUS_SUCCESS;
// 打开注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
if (!NT_SUCCESS(status))
return FALSE;
DbgPrint("Open register successfully!\n");
// 关闭注册表键句柄
ZwClose(hRegister);
return TRUE;
};

删除注册表键/键值

ZwDeleteKey

删除一个已打开的注册表键。

1
2
3
NTSTATUS ZwDeletekey(
_In_ HANDLE KeyHandle
)

ZwDeleteValueKey

从已打开的注册表键中删除名称匹配的键值。

1
2
3
4
NTSTATUS ZwDeleteValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName
)

例子

删除注册表键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOLEAN MyDeleteRegistryKey(UNICODE_STRING ustrRegistry) {
HANDLE hRegister = NULL;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
NTSTATUS status = STATUS_SUCCESS;
// 打开注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
if (!NT_SUCCESS(status))
return FALSE;
// 删除注册表键
status = ZwDeleteKey(hRegister);
if (!NT_SUCCESS(status)) {
ZwClose(hRegister);
return FALSE;
};
// 关闭注册表键句柄
ZwClose(hRegister);
return TRUE;
};

删除注册表键值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOLEAN MyDeleteRegistryKeyValue(UNICODE_STRING ustrRegistry, UNICODE_STRING ustrKeyValueName) {
HANDLE hRegister = NULL;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
NTSTATUS status = STATUS_SUCCESS;
// 打开注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
if (!NT_SUCCESS(status))
return FALSE;
// 删除注册表键
status = ZwDeleteValueKey(hRegister, &ustrKeyValueName);
if (!NT_SUCCESS(status)) {
ZwClose(hRegister);
return FALSE;
};
// 关闭注册表键句柄
ZwClose(hRegister);
return TRUE;
};

添加/修改注册表键值

ZwSetValueKey

创建或替换注册表键值。

1
2
3
4
5
6
7
8
9
NTSTATUS ZwSetValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_opt_ ULONG TitleIndex,
_In_ ULONG Type,
//要写入的数据类型 二进制REG_BINARY 4字节REG_DWORD NULL结尾Unicode字符串REG_SZ 同上带环境变量扩展REG_EXPAND_SZ如%PATH%等
_In_opt_ PVOID Data,
_In_ ULONG DataSize
)

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOLEAN MySetRegistryKeyValue(UNICODE_STRING ustrRegistry, UNICODE_STRING ustrKeyValueName, ULONG ulKeyValueType, PVOID pKeyValueData, ULONG ulKeyValueDataSize) {
HANDLE hRegister = NULL;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
NTSTATUS status = STATUS_SUCCESS;
// 打开注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
if (!NT_SUCCESS(status))
return FALSE;
// 添加或者修改键值
status = ZwSetValueKey(hRegister, &ustrKeyValueName, 0, ulKeyValueType, pKeyValueData, ulKeyValueDataSize);
if (!NT_SUCCESS(status)) {
ZwClose(hRegister);
return FALSE;
};
// 关闭注册表键句柄
ZwClose(hRegister);
return TRUE;
};

查询注册表键值

ZwQueryValueKey

获取注册表键值。

1
2
3
4
5
6
7
8
NTSTATUS ZwQueryValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_opt_ PVOID KeyValueInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
)

KEY_VALUE_PARTIAL_INFORMATION

1
2
3
4
5
6
typedef struct _KEY_VALUE_PARTIAL_INFORMATION{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
}KEY_VALUE_PARTIAL_INFORMATION,*PKEY_VALUE_PARTIAL_INFORMATION;

例子

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
BOOLEAN MyQueryRegistryKeyValue(UNICODE_STRING ustrRegistry, UNICODE_STRING ustrKeyValueName) {
HANDLE hRegister = NULL;
OBJECT_ATTRIBUTES objectAttributes = { 0 };
NTSTATUS status = STATUS_SUCCESS;
ULONG ulBufferSize = 0;
PKEY_VALUE_PARTIAL_INFORMATION pKeyValuePartialInfo = NULL;
// 打开注册表键
InitializeObjectAttributes(&objectAttributes, &ustrRegistry, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes);
if (!NT_SUCCESS(status))
return FALSE;
// 先获取查询注册表键值所需缓冲区的大小
status = ZwQueryValueKey(hRegister, &ustrKeyValueName, KeyValuePartialInformation, NULL, 0, &ulBufferSize);
if (0 == ulBufferSize) {
ZwClose(hRegister);
return FALSE;
};
// 申请缓冲区
pKeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, ulBufferSize);
// 查询注册表键值并获取查询结果
status = ZwQueryValueKey(hRegister, &ustrKeyValueName, KeyValuePartialInformation, pKeyValuePartialInfo, ulBufferSize, &ulBufferSize);
if (!NT_SUCCESS(status)) {
ExFreePool(pKeyValuePartialInfo);
ZwClose(hRegister);
return FALSE;
};
// 显示查询结果
DbgPrint("KeyValueName=%wZ, KeyValueType=%d, KeyValueData=%S\n", &ustrKeyValueName, pKeyValuePartialInfo->Type, pKeyValuePartialInfo->Data);
// 释放内存, 关闭句柄
ExFreePool(pKeyValuePartialInfo);
ZwClose(hRegister);
return TRUE;
};