【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)

简介: 【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)

1、创建注册表项和子项

VOID RegCreateText()
{
  HANDLE hKey;
  HANDLE hSubkey;
  NTSTATUS status;
  OBJECT_ATTRIBUTES oa;
  ULONG ulRet;
  UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey");
  UNICODE_STRING SubPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey\\SubKey");
  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))
  {
    if (ulRet == REG_CREATED_NEW_KEY)
    {
      KdPrint(("项不存在创建成功\n"));
    }
    else
    {
      KdPrint(("项存在,打开它\n"));
    }
  }
  else
  {
    KdPrint(("创建注册表项失败\n"));
  }

  InitializeObjectAttributes(&oa, &SubPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
  status = ZwCreateKey(&hSubkey, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &ulRet);
  if (NT_SUCCESS(status))
  {
    if (ulRet == REG_CREATED_NEW_KEY)
    {
      KdPrint(("子项不存在创建成功\n"));
    }
    else if(ulRet == REG_OPENED_EXISTING_KEY)
    {
      KdPrint(("子项存在,打开它\n"));
    }
  }
  else
  {
    KdPrint(("创建注册表子项是失败\n"));
  }
  ZwClose(hKey);
  ZwClose(hSubkey);
}


2、打开注册表、修改注册表并读取注册表的信息

VOID RegTest()
{
  HANDLE hKey;
  NTSTATUS status;
  OBJECT_ATTRIBUTES oa;
  UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\MyKey");
  UNICODE_STRING ValueName;
  DWORD Value = -1;
  CHAR buffer[] = "hello world" ;
  PKEY_VALUE_PARTIAL_INFORMATION pvpi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 1024);
  ULONG Length;
  InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
  status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &oa);
  if (NT_SUCCESS(status))
  {
    KdPrint(("打开成功\n"));
  }
  else
  {
    KdPrint(("打开失败\n"));
  }
  //修改注册表
  RtlInitUnicodeString(&ValueName, L"字符串");
  ZwSetValueKey(hKey, &ValueName, 0, REG_SZ, L"你好", wcslen(L"你好") * sizeof(WCHAR));
  
  RtlInitUnicodeString(&ValueName, L"整数");
  ZwSetValueKey(hKey, &ValueName, 0, REG_DWORD, &Value, sizeof(DWORD));

  RtlInitUnicodeString(&ValueName, L"二进制");
  ZwSetValueKey(hKey, &ValueName, 0, REG_BINARY, buffer, strlen(buffer));

  //读取字符串
  RtlZeroMemory(pvpi, 1024);
  RtlInitUnicodeString(&ValueName, L"字符串");
  ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
  if (pvpi->Type == REG_SZ)
  {
    KdPrint(("%ls\n", pvpi->Data));
  }

  //读取整数
  RtlZeroMemory(pvpi, 1024);
  RtlInitUnicodeString(&ValueName, L"整数");
  ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
  if (pvpi->Type == REG_DWORD)
  {
    KdPrint(("%d\n", *(PULONG)pvpi->Data));
  }

  //读取二进制
  RtlZeroMemory(pvpi, 1024);
  RtlInitUnicodeString(&ValueName, L"二进制");
  ZwQueryValueKey(hKey, &ValueName, KeyValuePartialInformation, pvpi, 1024, &Length);
  if (pvpi->Type == REG_BINARY)
  {
    KdPrint(("%s\n", pvpi->Data));
  }
}


3、枚举注册表子项

VOID RegEnumTest()
{
  HANDLE hkey;
  NTSTATUS status;
  ULONG Length;
  ULONG Index;

  OBJECT_ATTRIBUTES oa; //对象属性
  //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
  UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
  InitializeObjectAttributes(&oa, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);  //初始化对象属性信息
  
  PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024);   //分配内存
  PKEY_BASIC_INFORMATION pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 1024); //分配内存
  PKEY_VALUE_FULL_INFORMATION pvpi = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, 1024);

  status = ZwOpenKey(&hkey, KEY_ALL_ACCESS, &oa);   //打开注册表
  if (!NT_SUCCESS(status))
  {
    KdPrint(("打开注册表失败\n"));
    return;
  }
  status = ZwQueryKey(hkey, KeyFullInformation, pfi, 1024, &Length);  //查询注册表
  if (NT_SUCCESS(status))
  {
    KdPrint(("***********************************\n"));
    for (Index = 0; Index < pfi->SubKeys; Index++)  //遍历所有子项
    {
      RtlZeroMemory(pbi, 1024);
      ZwEnumerateKey(hkey, Index, KeyBasicInformation, pbi, 1024, &Length); //枚举出注册表子项的基本信息
      if (NT_SUCCESS(status))
      {
        KdPrint(("%ls\n", pbi->Name));  //输出子项的名称
      }
    }
    KdPrint(("***********************************\n"));
    for (Index = 0; Index < pfi->Values; Index++) //遍历所有子项的值
    {
      RtlZeroMemory(pvpi, 1024);
      status = ZwEnumerateValueKey(hkey, Index, KeyValueFullInformation, pvpi, 1024, &Length);  //枚举出注册表子项的值
      if (NT_SUCCESS(status))
      {
        switch (pvpi->Type)
        {
        case REG_DWORD:
          KdPrint(("%ls:%d\n", pvpi->Name, *(PULONG)((PCHAR)pvpi + pvpi->DataOffset)));
          break;
        case REG_SZ:
        case REG_MULTI_SZ:
        case REG_EXPAND_SZ:
          KdPrint(("%ls:%ls\n", pvpi->Name, (PCHAR)pvpi + pvpi->DataOffset));
          break;
        default:
          break;
        }
      }
    }
  }
  ZwClose(hkey);
  if (pfi != NULL)
  {
    ExFreePool(pfi);
  }
  if (pbi != NULL)
  {
    ExFreePool(pbi);
  }
  if (pvpi != NULL)
  {
    ExFreePool(pvpi);
  }
}

、代码实现效果图


(1)注册表的创建、打开、修改、读取


(2)注册表子项的枚举


补充:

也可使用微软封装的RTL函数来进行注册表的相关操作。

//微软封装的RTL函数
VOID RtlTest()
{ 
  NTSTATUS status;
  status = RtlCreateRegistryKey(RTL_REGISTRY_SERVICES, L"MyService");
  if (NT_SUCCESS(status))
  {
    KdPrint(("Rtl创建子项成功\n"));
  }
  status = RtlCheckRegistryKey(RTL_REGISTRY_SERVICES, L"MyService");
  if (NT_SUCCESS(status))
  {
    KdPrint(("注册表子项存在\n"));
  }
  status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, L"MyService", L"字符串", REG_SZ, L"你好世界", 8);
  if (NT_SUCCESS(status))
  {
    KdPrint(("写入成功\n"));
  }

  status = RtlDeleteRegistryValue(RTL_REGISTRY_SERVICES, L"MyService", L"字符串");
  if (NT_SUCCESS(status))
  {
    KdPrint(("删除成功\n"));
  }
}
相关文章
|
2月前
|
安全 固态存储 文件存储
Windows 7纯净版重装教程|附微软原版镜像下载+驱动安装避坑技巧
本文详细介绍如何安全、高效地重装电脑系统,解决蓝屏、崩溃等问题。基于10年经验,涵盖从官方镜像获取、启动盘制作、数据备份到系统部署的全流程,并针对老旧机型优化。提供驱动一键安装工具和系统激活指南,确保无后门风险。文中还列出常见问题解决方案及操作禁忌,帮助用户顺利完成系统重装,让电脑重获新生。建议收藏并转发给有需要的朋友,欢迎留言咨询疑难问题。
|
2月前
|
算法 关系型数据库 测试技术
WHQL微软驱动签名方案,让驱动程序在Windows系统流畅运行
WHQL认证(Windows徽标认证)是微软设立的严格测试标准,旨在确保驱动程序的兼容性、稳定性和互通性。本文介绍了三种WHQL微软驱动签名方案:单系统签名、多系统签名和硬件兼容性测试方案,分别满足不同开发商的需求。通过WHQL认证,不仅能消除Windows安装警告,提升用户体验,还能获得“Designed for Windows”徽标授权,入列全球Windows Catalog及HCL产品表,提升品牌权威性和采购优先权。此外,访问微软OCA可获取错误反馈,助力产品质量改进。选择合适的签名方案,让驱动在Windows系统中流畅运行!
|
7月前
|
Ubuntu Linux Python
如何利用wsl-Ubuntu里conda用来给Windows的PyCharm开发
如何在WSL(Windows Subsystem for Linux)的Ubuntu环境中使用conda虚拟环境来为Windows上的PyCharm开发设置Python解释器。
728 1
|
7月前
|
监控 关系型数据库 MySQL
PowerShell 脚本编写 :自动化Windows 开发工作流程
PowerShell 脚本编写 :自动化Windows 开发工作流程
305 0
|
7月前
|
并行计算 开发工具 异构计算
在Windows平台使用源码编译和安装PyTorch3D指定版本
【10月更文挑战第6天】在 Windows 平台上,编译和安装指定版本的 PyTorch3D 需要先安装 Python、Visual Studio Build Tools 和 CUDA(如有需要),然后通过 Git 获取源码。建议创建虚拟环境以隔离依赖,并使用 `pip` 安装所需库。最后,在源码目录下运行 `python setup.py install` 进行编译和安装。完成后即可在 Python 中导入 PyTorch3D 使用。
712 0
|
8月前
|
存储 安全 程序员
Windows任务管理器开发原理与实现
Windows任务管理器开发原理与实现
|
10月前
|
Linux Apache C++
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
该文介绍了如何在Windows环境下为FFmpeg集成SRT协议支持库libsrt。首先,需要安装Perl和Nasm,然后编译OpenSSL。接着,下载libsrt源码并使用CMake配置,生成VS工程并编译生成srt.dll和srt.lib。最后,将编译出的库文件和头文件按照特定目录结构放置,并更新环境变量,重新配置启用libsrt的FFmpeg并进行编译安装。该过程有助于优化直播推流的性能,减少卡顿问题。
232 2
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
|
9月前
|
存储 数据可视化 Python
【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】
【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】
442 1
|
9月前
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
458 0
|
9月前
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
958 0

热门文章

最新文章