Windows驱动开发之注册表操作
2016-07-06 22:44
495 查看
转载请注明来源:
enjoy5512的博客 : http://blog.csdn.net/enjoy5512
GitHub : https://github.com/whu-enjoy
代码中测试了ZwOpenKey的使用方式
先初始化OBJECT_ATTRIBUTES结构体,然后打开注册表键
2)分配如此长度的内存。
3)再次调用ZwQueryValueKey 查询。
4)回收内存
找到一篇很不错的博客:
http://www.cnblogs.com/mydomain/archive/2
010/10/29/1864013.html
enjoy5512的博客 : http://blog.csdn.net/enjoy5512
GitHub : https://github.com/whu-enjoy
1. 在驱动中操作注册表
注册表项相当于文件夹,注册表子项子文件夹(类似目录)1.1 打开注册表键
ZwCreateKey/ZwOpenKey代码中测试了ZwOpenKey的使用方式
先初始化OBJECT_ATTRIBUTES结构体,然后打开注册表键
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 ); Parameters KeyHandle [out] Pointer to a HANDLE variable that receives a handle to the key. DesiredAccess [in] Specifies an ACCESS_MASK value that determines the requested access to the object. In addition to the access rights that are defined for all types of objects (see ACCESS_MASK), the caller can specify one or more of the following access rights, which are specific to object directories:
DesiredAccess flag | Allows caller to do this |
---|---|
KEY_QUERY_VALUE | Read key values. |
KEY_SET_VALUE | Write key values. |
KEY_CREATE_SUB_KEY | Create subkeys for the key. |
KEY_ENUMERATE_SUB_KEYS | Read the key’s subkeys. |
KEY_CREATE_LINK | Create a symbolic link to the key. This flag is not used by device and intermediate drivers. |
KEY_NOTIFY | Ask to receive notification when the name, value, or attributes of the key change. For more information, see ZwNotifyChangeKey. |
The caller can also specify one of the following constants, which combines several ACCESS_MASK flags.
Constant Consists of these | ACCESS_MASK flags |
---|---|
KEY_READ | STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY |
KEY_WRITE | STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUBKEY |
KEY_EXECUTE | Same as KEY_READ. |
KEY_ALL_ACCESS | STANDARD_RIGHTS_ALL, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK |
ObjectAttributes [in] Pointer to an OBJECT_ATTRIBUTES structure that specifies the object name and other attributes. Use InitializeObjectAttributes to initialize this structure. If the caller is not running in a system thread context, it must set the OBJ_KERNEL_HANDLE attribute when it calls InitializeObjectAttributes. TitleIndex Device and intermediate drivers set this parameter to zero. Class [in, optional] Pointer to a Unicode string that contains the key's object class. This information is used by the configuration manager. CreateOptions [in] Specifies the options to apply when creating or opening a key, specified as a compatible combination of the following flags.
CreateOptions flag | Description |
---|---|
REG_OPTION_VOLATILE | Key is not preserved when the system is rebooted. |
REG_OPTION_NON_VOLATILE | Key is preserved when the system is rebooted. |
REG_OPTION_CREATE_LINK | The newly created key is a symbolic link. This flag is not used by device and intermediate drivers. |
REG_OPTION_BACKUP_RESTORE | Key should be created or opened with special privileges that allow backup and restore operations. This flag is not used by device and intermediate drivers. |
Disposition [out, optional] Pointer to a variable that receives a value indicating whether a new key was created or an existing one opened.
Disposition value | Description |
---|---|
REG_CREATED_NEW_KEY | A new key was created. |
REG_OPENED_EXISTING_KEY | An existing key was opened. |
Return value ZwCreateKey returns STATUS_SUCCESS on success, or the appropriate NTSTATUS error code on failure.
NTSTATUS ZwOpenKey( _Out_ PHANDLE KeyHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes ); Parameters KeyHandle [out] Pointer to the HANDLE variable that receives the handle to the key. DesiredAccess [in] Specifies an ACCESS_MASK value that determines the requested access to the object. For more information, see the DesiredAccess parameter of ZwCreateKey. ObjectAttributes [in] Pointer to an OBJECT_ATTRIBUTES structure that specifies the object name and other attributes. Use InitializeObjectAttributes to initialize this structure. If the caller is not running in a system thread context, it must set the OBJ_KERNEL_HANDLE attribute when it calls InitializeObjectAttributes. Return value ZwOpenKey returns STATUS_SUCCESS if the given key was opened. Otherwise, it can return an error status, including the following: STATUS_INVALID_HANDLE STATUS_ACCESS_DENIED
1.2 读注册表键值
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 ); Parameters KeyHandle [in] Handle to the key to read value entries from. This handle is created by a successful call to ZwCreateKey or ZwOpenKey. ValueName [in] Pointer to the name of the value entry to obtain data for. KeyValueInformationClass [in] A KEY_VALUE_INFORMATION_CLASS value that determines the type of information returned in the KeyValueInformation buffer. KeyValueInformation [out, optional] Pointer to a caller-allocated buffer that receives the requested information. Length [in] Specifies the size, in bytes, of the KeyValueInformation buffer. ResultLength [out] Pointer to a variable that receives the size, in bytes, of the key information. If the ZwQueryValueKey routine returns STATUS_SUCCESS, callers can use the value of this variable to determine the amount of data returned. If the routine returns STATUS_BUFFER_OVERFLOW or STATUS_BUFFER_TOO_SMALL, callers can use the value of this variable to determine the size of buffer required to hold the key information. Return value ZwQueryValueKey returns STATUS_SUCCESS on success, or the appropriate error code on failure. Possible error code values include:
Return code | Description |
---|---|
STATUS_OBJECT_NAME_NOT_FOUND | The registry value was not available. |
STATUS_BUFFER_OVERFLOW | The buffer supplied is too small, and only partial data has been written to the buffer. *ResultLength is set to the minimum size required to hold the requested information. |
STATUS_BUFFER_TOO_SMALL | The buffer supplied is too small, and no data has been written to the buffer. *ResultLength is set to the minimum size required to hold the requested information. |
STATUS_INVALID_PARAMETER | The KeyInformationClass parameter is not a valid KEY_VALUE_INFORMATION_CLASS value.Warning If you specify KeyValueBasicInformation for KeyValueInformationClass, Windows 98 and Windows Me return STATUS_SUCCESS even if the registry key or value name does not exist. |
1.3 写注册表键值
调用ZwSetValueKeyNTSTATUS ZwSetValueKey( _In_ HANDLE KeyHandle, _In_ PUNICODE_STRING ValueName, _In_opt_ ULONG TitleIndex, _In_ ULONG Type, _In_opt_ PVOID Data, _In_ ULONG DataSize ); Parameters KeyHandle [in] Handle to the registry key to write a value entry for. This handle is created by a successful call to ZwCreateKey or ZwOpenKey. ValueName [in] Pointer to the name of the value entry for which the data is to be written. This parameter can be a NULL pointer if the value entry has no name. If a name string is specified and the given name is not unique relative to its containing key, the data for an existing value entry is replaced. TitleIndex [in, optional] This parameter is reserved. Device and intermediate drivers should set this parameter to zero. Type [in] One of the following system-defined types of data to write.
Type Value | Meaning |
---|---|
REG_BINARY | Binary data in any form. |
REG_DWORD | A 4-byte numerical value. |
REG_DWORD_LITTLE_ENDIAN | A 4-byte numerical value with the least significant byte at the lowest address. Identical to REG_DWORD. |
REG_DWORD_BIG_ENDIAN | A 4-byte numerical value with the least significant byte at the highest address. |
REG_EXPAND_SZ | A null-terminated Unicode string that contains unexpanded references to environment variables, such as “%PATH%”. |
REG_LINK | A Unicode string that names a symbolic link. This type is irrelevant to device and intermediate drivers. |
REG_MULTI_SZ | An array of null-terminated strings, terminated by another zero. |
REG_NONE | Data with no particular type. |
REG_SZ | A null-terminated Unicode string. |
REG_RESOURCE_LIST | A device driver’s list of hardware resources, used by the driver or one of the physical devices it controls, in the \ResourceMap tree |
REG_RESOURCE_REQUIREMENTS_LIST | A device driver’s list of possible hardware resources it or one of the physical devices it controls can use, from which the system writes a subset into the \ResourceMap tree |
REG_FULL_RESOURCE_DESCRIPTOR | A list of hardware resources that a physical device is using, detected and written into the \HardwareDescription tree by the system |
Note Device drivers should not attempt to call ZwSetValueKey to explicitly write value entries in a subkey of the \Registry...\ResourceMap key. Only the system can write value entries to the \Registry...\HardwareDescription tree. Data [in, optional] Pointer to a caller-allocated buffer that contains the data for the value entry. DataSize [in] Specifies the size, in bytes, of the Data buffer. If Type is REG_XXX_SZ, this value must include space for any terminating zeros. Return value ZwSetValueKey returns an NTSTATUS value. Possible return values include: STATUS_SUCCESS STATUS_ACCESS_DENIED STATUS_INVALID_HANDLE
2. 示例代码
//程序说明开始 //================================================================================== // 功能 : 注册表操作函数 // 参数 : // (入口) // (出口) 无 // 返回 : NTSTATUS // 主要思路 : // 调用举例 : // 日期 : 2016年7月6日 16:26:31 - 2016年7月6日 18:13:48 //================================================================================== //程序说明结束 NTSTATUS RegistryOption() { HANDLE KeyHandle = NULL; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING KeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SourceKeyName = RTL_CONSTANT_STRING(L"SystemRoot"); UNICODE_STRING TargetKeyName = RTL_CONSTANT_STRING(L"test"); PKEY_VALUE_PARTIAL_INFORMATION AcKeyInfo = NULL; KEY_VALUE_PARTIAL_INFORMATION KeyInfo; ULONG Length = 0; //初始化OBJECT_ATTRIBUTES结构体 InitializeObjectAttributes( &ObjectAttributes, &KeyPath, OBJ_CASE_INSENSITIVE, NULL, NULL); //打开注册表键 Status = ZwOpenKey(&KeyHandle, KEY_READ|KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DbgPrint("Open the Key Handle Faild!! -- %#X\n", Status); return Status; } //第一次读取注册表键值探测数据大小 Status = ZwQueryValueKey( KeyHandle, &SourceKeyName, KeyValuePartialInformation, &KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION), &Length); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) { DbgPrint("读取SystemRoot键值失败!! - %#X\n", Status); ZwClose(KeyHandle); return Status; } //根据上面探测的注册表键值大小动态分配内存 AcKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, Length, "tag2"); if (NULL == AcKeyInfo) { DbgPrint("在分配保存Key键值的内存空间时失败!!"); ZwClose(KeyHandle); Status = STATUS_INSUFFICIENT_RESOURCES; return Status; } //再次读取注册表键值 Status = ZwQueryValueKey( KeyHandle, &SourceKeyName, KeyValuePartialInformation, AcKeyInfo, Length, &Length); if (!NT_SUCCESS(Status)) { DbgPrint("读取SystemRoot键值失败!! - %#X\n", Status); ZwClose(KeyHandle); ExFreePool(AcKeyInfo); return Status; } //写入注册表值 Status = ZwSetValueKey( KeyHandle, &TargetKeyName, 0, AcKeyInfo->Type, AcKeyInfo->Data, AcKeyInfo->DataLength); if (!NT_SUCCESS(Status)) { DbgPrint("写入test键值失败!! - %#X ", Status); ZwClose(KeyHandle); ExFreePool(AcKeyInfo); return Status; } //释放内存与句柄 ZwClose(KeyHandle); ExFreePool(AcKeyInfo); return Status; }
找到一篇很不错的博客:
http://www.cnblogs.com/mydomain/archive/2
010/10/29/1864013.html
相关文章推荐
- 用注册表文件实现解开被锁定的.reg与inf文件
- 注册表导出管理员密码文件
- 修改注册表实现在桌面上显示Windows版本
- 用注册表清除3389登陆记录的方法
- 常见的注册表修改大全第1/3页
- vbscript 注册表脚本书写
- vbscript Registry 注册表操作实现代码(读写删除)
- vbs 注册表操作代码(添加删除)
- 杀毒除根 巧用注册表防止病毒重新生成
- vbs删除注册表项的代码
- 批处理操作注册表完全攻略(读取注册表/写入注册表等)
- 写给电脑初学者的一些建议(注册表篇)
- CMD下读取/修改/删除注册表项的方法
- C#实现读取注册表监控当前操作系统已安装软件变化的方法
- PowerShell使用Remove-Item命令删除文件、注册表项介绍
- C#通过windows注册表获取软件清单的方法
- 读取注册表根据Office版本获取数据库连接字段
- C#操作注册表的方法详解
- 在DOS方式下对注册表进行操作的代码
- 用vbs操作注册表实例代码