Windows驱动开发(5) - 内核模式下的注册表操作

Windows驱动开发(5) - 内核模式下的注册表操作

1、创建关闭注册表

1.1 创建注册表

NTSTATUS ZwCreateKey(
  _Out_      PHANDLE            KeyHandle,
  _In_       ACCESS_MASK        DesiredAccess,
  _In_       POBJECT_ATTRIBUTES ObjectAttributes,
  _Reserved_ ULONG              TitleIndex,
  _In_opt_   PUNICODE_STRING    Class,
  _In_       ULONG              CreateOptions,
  _Out_opt_  PULONG             Disposition
);

参数
- KeyHandle:[out] :获得的注册表句柄。
- DesiredAccess:[in] :访问权限,一般设置为KEY_ALL_ACCESS
- KEY_QUERY_VALUE:读键值
- KEY_SET_VALUE:写键值
- KEY_CREATE_SUB_KEY:创建键的子健
- KEY_ENUMERATE_SUB_KEYS:读键的子健
- KEY_CREATE_LINK:创建符号链接
- KEY_NOTIFY:
还可以指定下面的几个常量,它包含了一个或多个ACCESS_MASK标志。
- KEY_READ
- KEY_WRITE
- KEY_EXECUTE
- KEY_ALL_ACCESS
- ObjectAttributes:[in] :OBJECT_ATTRIBUTES 数据结构,指示打开的状态。
- TitleIndex:[in] :很少用到,一般设置为0。
- Class:[in] :很少用到,一般设置为NULL。
- CreateOptions:[in] :创建时的选项,一般设置为REG_OPTION_NON_VOLATILE。
- Disposition:[out] :返回是创建成功,还是打开成功。返回值是REG_CREATED_NEW_KEY,REG_OPENEND_EXISTING_KEY。

返回值
返回是否创建成功。

1.2 关闭注册表

NTSTATUS ZwClose(
  _In_  HANDLE Handle
);
  • Handle:注册表句柄

2、打开注册表

NTSTATUS ZwOpenKey( _Out_ PHANDLE KeyHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes );
  • KeyHandle:返回被打开的句柄
  • DesiredAccess:访问权限,一般设置为KEY_ALL_ACCESS
  • ObjectAttributes:OBJECT_ATTRIBUTES 数据结构,指示打开的状态
  • 返回值:返回是否创建成功。

3、添加、修改注册表键值

NTSTATUS ZwSetValueKey(
  _In_     HANDLE          KeyHandle,
  _In_     PUNICODE_STRING ValueName,
  _In_opt_ ULONG           TitleIndex,
  _In_     ULONG           Type,
  _In_opt_ PVOID           Data,
  _In_     ULONG           DataSize
);
  • KeyHandle:注册表句柄
  • ValueName:要新建或修改的键名
  • TitleIndex:很少用,一般设为0
  • Type:键值类型
    • REG_BINARY:二进制
    • REG_SZ:宽字符串
    • REG_EXPAND_SZ:扩展宽字符串
    • REG_MULTI_SZ:多个字符串
    • REG_DWORD:4字节整型
    • REG_QWORD:8字节存储
  • Data:对应Type类型的键值数据指针
  • DataSize:记录键值数据的大小
  • 返回值:返回新建或修改的结果

4、查询注册表

1)用ZwQueryValueKey 获取数据结构的长度。
2)分配如此长度的内存。
3)再次调用ZwQueryValueKey 查询。
4)回收内存。

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
);
  • KeyHandle:注册表句柄
  • ValueName:要查询的键名
  • KeyValueInformationClass:根据KeyValueInformation的不同选择不同的查询类别
    • KeyValueBasicInformation
    • KeyValueFullInformation
    • KeyValuePartialInformation
  • KeyValueInformation:查询数据指针
  • Length:要查数据的长度
  • ResultLength:实际查询数据的长度
  • 返回值:表示查询数据是否成功

5、枚举子项

  用ZwQueryKey与ZwEnumerateKey 来枚举子项。
  ZwQueryKey获取某注册表项究竟有多少个子项,而ZwEnumerateKey 针对第几个子项获取该子项的具体信息。
  我们发现,凡是调用有长度的函数,一般都是两次调用,第一次调用来获得具体查询(使用该函数)需要的内存需要多大长度,第二次调用时来查询具体信息。

NTSTATUS ZwQueryKey(
  _In_       HANDLE KeyHandle,
  _In_       KEY_INFORMATION_CLASS KeyInformationClass,
  _Out_opt_  PVOID KeyInformation,
  _In_       ULONG Length,
  _Out_      PULONG ResultLength
);
  • KeyHandle:注册表项的句柄
  • KeyInformationClass:查询的类别,一般选择KeyFullInformation
  • KeyInformation:查询的数据指针。
  • Length:数据长度
  • ResultLength:返回的数据长度
  • 返回值:指示查询是否成功
NTSTATUS ZwEnumerateKey(
  _In_      HANDLE                KeyHandle,
  _In_      ULONG                 Index,
  _In_      KEY_INFORMATION_CLASS KeyInformationClass,
  _Out_opt_ PVOID                 KeyInformation,
  _In_      ULONG                 Length,
  _Out_     PULONG                ResultLength
);
  • KeyHandle:注册表项的句柄
  • Index:很少用到,一般为0
  • KeyInformationClass:查询的类别,一般选择KeyFullInformation
  • KeyInformation:查询的数据指针。
  • Length:子项信息的长度
  • ResultLength:返回的子项信息的长度
  • 返回值:指示枚举是否成功

6、枚举子健

通过ZwQueryKey与ZwEnumerateValueKey来枚举子键。

NTSTATUS ZwEnumerateValueKey(
  _In_      HANDLE                      KeyHandle,
  _In_      ULONG                       Index,
  _In_      KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
  _Out_opt_ PVOID                       KeyValueInformation,
  _In_      ULONG                       Length,
  _Out_     PULONG                      ResultLength
);

7、删除子健

只能删除没有子项的项目。

NTSTATUS ZwDeleteKey( _In_ HANDLE KeyHandle );

8、其他

DDK中定义了一些运行时函数来简化上面的操作。
- RtlCreateRegistryKey:创建注册表
- RtlCheckRegistryKey:检查注册表中的一个给定的名称键是否存在
- RtlWriteRegistryValue:写注册表
- RtlDeleteRegistryValue“删除注册表

你可能感兴趣的:(windows,内核,注册表,驱动开发)