【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"));
  }
}
相关文章
|
8天前
|
Linux Apache C++
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
该文介绍了如何在Windows环境下为FFmpeg集成SRT协议支持库libsrt。首先,需要安装Perl和Nasm,然后编译OpenSSL。接着,下载libsrt源码并使用CMake配置,生成VS工程并编译生成srt.dll和srt.lib。最后,将编译出的库文件和头文件按照特定目录结构放置,并更新环境变量,重新配置启用libsrt的FFmpeg并进行编译安装。该过程有助于优化直播推流的性能,减少卡顿问题。
41 2
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
|
12天前
|
安全 测试技术 Windows
LabVIEW版本、硬件驱动和Windows版本之间兼容性
LabVIEW版本、硬件驱动和Windows版本之间兼容性
17 2
|
28天前
|
网络安全 C++ Windows
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
|
28天前
|
Windows
【Windows内核驱动函数(1)】IoCreateSymbolicLink()-----创建符号链接函数
【Windows内核驱动函数(1)】IoCreateSymbolicLink()-----创建符号链接函数
|
19天前
|
Java Nacos 微服务
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册
Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册
|
2月前
|
Linux Windows
Windows Server 下文件同步
Windows Server 下文件同步
40 0
|
4天前
|
网络协议 Unix 网络安全
FTP服务器怎么搭建?Windows server搭建FPT服务器
FTP服务器是按照FTP协议提供文件传输服务的计算机。它用于在两台计算机间安全地传输文件,支持用户权限管理和跨平台操作。FTP使用控制连接处理命令,数据连接传输文件,有PORT和PASV模式。要搭建FTP服务器,首先在Windows Server 2008 R2上安装IIS,确保选中FTP服务。接着,创建FTP文件夹作为站点根目录,通过IIS管理器添加FTP站点,配置站点信息、身份验证和权限。测试客户端通过telnet和浏览器访问FTP服务器,确认能成功登录及浏览文件。FTP常用于文件共享和管理,可通过专用工具如FlashFXP上传下载文件。
17 0
FTP服务器怎么搭建?Windows server搭建FPT服务器
|
10天前
|
前端开发 JavaScript 应用服务中间件
windows server + iis 部署若伊前端vue项目
5,配置url重写规则(重写后端请求) 注:如果没有Application Request Routing Cachefourcloudbdueclaim和URL重写,则是第二部的那两个插件没装上 打开iis,点击计算机->点击Application Request Routing Cache -> 打开功能
36 0
|
1月前
|
编解码 安全 网络安全
RealVNC的 VNC server在windows7系统下无法正确运行
在Windows 7上运行旧版VNC Server(如4.1.2)可能存在兼容性问题,但可通过调整配置解决。步骤包括:安装VNC Server,设置兼容性模式(选择Windows XP SP3),启动VNC Server,配置VNC连接参数。若遇到问题,检查防火墙设置,确保系统更新,并考虑升级到新版VNC Server以提高性能和兼容性。
|
2月前
|
开发框架 .NET API
在Windows Server 2008 R2上运行.Net 8应用
在Windows Server 2008 R2上成功运行.Net 8程序,需安装三个补丁:Windows Server 2008 R2 SP1 (KB976932)是基础更新;VC_redist.x64提供MSVC库支持;KB3063858解决.NET运行时加载`kernel.dll`的路径问题。KB3063858可能需要KB2533623。详细信息和下载链接在文中给出。