zoukankan      html  css  js  c++  java
  • 22、Windows内核函数(3)Windows驱动开发详解笔记,注册表操作

    注册表项相当于文件夹,注册表子项子文件夹(类似目录)。 

    1、创建关闭 

    ZwCreateKey  

    示例代码

    代码
    1 VOID CreateRegTest()
    2 {
    3 //创建或打开某注册表项目
    4 UNICODE_STRING RegUnicodeString;
    5 HANDLE hRegister;
    6
    7 //初始化UNICODE_STRING字符串
    8 RtlInitUnicodeString( &RegUnicodeString,
    9 MY_REG_SOFTWARE_KEY_NAME);
    10
    11 OBJECT_ATTRIBUTES objectAttributes;
    12 //初始化objectAttributes
    13 InitializeObjectAttributes(&objectAttributes,
    14 &RegUnicodeString,
    15 OBJ_CASE_INSENSITIVE,//对大小写敏感
    16 NULL,
    17 NULL );
    18 ULONG ulResult;
    19 //创建或带开注册表项目
    20 NTSTATUS ntStatus = ZwCreateKey( &hRegister,
    21 KEY_ALL_ACCESS,
    22 &objectAttributes,
    23 0,
    24 NULL,
    25 REG_OPTION_NON_VOLATILE,
    26 &ulResult);
    27
    28 if (NT_SUCCESS(ntStatus))
    29 {
    30 //判断是被新创建,还是已经被创建
    31 if(ulResult==REG_CREATED_NEW_KEY)
    32 {
    33 KdPrint(("The register item is created\n"));
    34 }else if(ulResult==REG_OPENED_EXISTING_KEY)
    35 {
    36 KdPrint(("The register item has been created,and now is opened\n"));
    37 }
    38 }
    39
    40 //(2)创建或打开某注册表项目的子项
    41 UNICODE_STRING subRegUnicodeString;
    42 HANDLE hSubRegister;
    43
    44 //初始化UNICODE_STRING字符串
    45 RtlInitUnicodeString( &subRegUnicodeString,
    46 L"SubItem");
    47
    48 OBJECT_ATTRIBUTES subObjectAttributes;
    49 //初始化subObjectAttributes
    50 InitializeObjectAttributes(&subObjectAttributes,
    51 &subRegUnicodeString,
    52 OBJ_CASE_INSENSITIVE,//对大小写敏感
    53 hRegister,
    54 NULL );
    55 //创建或带开注册表项目
    56 ntStatus = ZwCreateKey( &hSubRegister,
    57 KEY_ALL_ACCESS,
    58 &subObjectAttributes,
    59 0,
    60 NULL,
    61 REG_OPTION_NON_VOLATILE,
    62 &ulResult);
    63
    64 if (NT_SUCCESS(ntStatus))
    65 {
    66 //判断是被新创建,还是已经被创建
    67 if(ulResult==REG_CREATED_NEW_KEY)
    68 {
    69 KdPrint(("The sub register item is created\n"));
    70 }else if(ulResult==REG_OPENED_EXISTING_KEY)
    71 {
    72 KdPrint(("The sub register item has been created,and now is opened\n"));
    73 }
    74 }
    75
    76 //关闭注册表句柄
    77 ZwClose(hRegister);
    78 ZwClose(hSubRegister);
    79 }
    80
    2、打开 

    ZwOpenKey  

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

    ZwSetValueKey  

    示例代码

    代码
    1 VOID SetRegTest()
    2 {
    3 UNICODE_STRING RegUnicodeString;
    4 HANDLE hRegister;
    5
    6 //初始化UNICODE_STRING字符串
    7 RtlInitUnicodeString( &RegUnicodeString,
    8 MY_REG_SOFTWARE_KEY_NAME);
    9
    10 OBJECT_ATTRIBUTES objectAttributes;
    11 //初始化objectAttributes
    12 InitializeObjectAttributes(&objectAttributes,
    13 &RegUnicodeString,
    14 OBJ_CASE_INSENSITIVE,//对大小写敏感
    15 NULL,
    16 NULL );
    17 //打开注册表
    18 NTSTATUS ntStatus = ZwOpenKey( &hRegister,
    19 KEY_ALL_ACCESS,
    20 &objectAttributes);
    21
    22 if (NT_SUCCESS(ntStatus))
    23 {
    24 KdPrint(("Open register successfully\n"));
    25 }
    26
    27 UNICODE_STRING ValueName;
    28 //初始化ValueName
    29 RtlInitUnicodeString( &ValueName, L"REG_DWORD value");
    30
    31 //设置REG_DWORD子键
    32 ULONG ulValue = 1000;
    33 ZwSetValueKey(hRegister,
    34 &ValueName,
    35 0,
    36 REG_DWORD,
    37 &ulValue,
    38 sizeof(ulValue));
    39
    40 //初始化ValueName
    41 RtlInitUnicodeString( &ValueName, L"REG_SZ value");
    42 WCHAR* strValue = L"hello world";
    43
    44 //设置REG_SZ子键
    45 ZwSetValueKey(hRegister,
    46 &ValueName,
    47 0,
    48 REG_SZ,
    49 strValue,
    50 wcslen(strValue)*2+2);
    51
    52
    53 //初始化ValueName
    54 RtlInitUnicodeString( &ValueName, L"REG_BINARY value");
    55
    56 UCHAR buffer[10];
    57 RtlFillMemory(buffer,sizeof(buffer),0xFF);
    58
    59 //设置REG_MULTI_SZ子键
    60 ZwSetValueKey(hRegister,
    61 &ValueName,
    62 0,
    63 REG_BINARY,
    64 buffer,
    65 sizeof(buffer));
    66
    67 //关闭注册表句柄
    68 ZwClose(hRegister);
    69 }
    70
    4、查询 

    ZwQueryValueKey  

    来查询注册表项。 

    1)用ZwQueryValueKey 获取数据结构的长度。

    2)分配如此长度的内存。

    3)再次调用ZwQueryValueKey 查询。

    4)回收内存。

    示例代码

    代码
    1 VOID QueryRegTest()
    2 {
    3 UNICODE_STRING RegUnicodeString;
    4 HANDLE hRegister;
    5
    6 //初始化UNICODE_STRING字符串
    7 RtlInitUnicodeString( &RegUnicodeString,
    8 MY_REG_SOFTWARE_KEY_NAME);
    9
    10 OBJECT_ATTRIBUTES objectAttributes;
    11 //初始化objectAttributes
    12 InitializeObjectAttributes(&objectAttributes,
    13 &RegUnicodeString,
    14 OBJ_CASE_INSENSITIVE,//对大小写敏感
    15 NULL,
    16 NULL );
    17 //打开注册表
    18 NTSTATUS ntStatus = ZwOpenKey( &hRegister,
    19 KEY_ALL_ACCESS,
    20 &objectAttributes);
    21
    22 if (NT_SUCCESS(ntStatus))
    23 {
    24 KdPrint(("Open register successfully\n"));
    25 }
    26
    27 UNICODE_STRING ValueName;
    28 //初始化ValueName
    29 RtlInitUnicodeString( &ValueName, L"REG_DWORD value");
    30
    31 //读取REG_DWORD子键
    32 ULONG ulSize;
    33 ntStatus = ZwQueryValueKey(hRegister,
    34 &ValueName,
    35 KeyValuePartialInformation ,
    36 NULL,
    37 0,
    38 &ulSize);
    39
    40 if (ntStatus==STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0)
    41 {
    42 ZwClose(hRegister);
    43 KdPrint(("The item is not exist\n"));
    44 return;
    45 }
    46 PKEY_VALUE_PARTIAL_INFORMATION pvpi =
    47 (PKEY_VALUE_PARTIAL_INFORMATION)
    48 ExAllocatePool(PagedPool,ulSize);
    49
    50 ntStatus = ZwQueryValueKey(hRegister,
    51 &ValueName,
    52 KeyValuePartialInformation ,
    53 pvpi,
    54 ulSize,
    55 &ulSize);
    56 if (!NT_SUCCESS(ntStatus))
    57 {
    58 ZwClose(hRegister);
    59 KdPrint(("Read regsiter error\n"));
    60 return;
    61 }
    62 //判断是否为REG_DWORD类型
    63 if (pvpi->Type==REG_DWORD && pvpi->DataLength==sizeof(ULONG))
    64 {
    65 PULONG pulValue = (PULONG) pvpi->Data;
    66 KdPrint(("The value:%d\n",*pulValue));
    67 }
    68
    69 ExFreePool(pvpi);
    70
    71 //初始化ValueName
    72 RtlInitUnicodeString( &ValueName, L"REG_SZ value");
    73 //读取REG_SZ子键
    74 ntStatus = ZwQueryValueKey(hRegister,
    75 &ValueName,
    76 KeyValuePartialInformation ,
    77 NULL,
    78 0,
    79 &ulSize);
    80
    81 if (ntStatus==STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0)
    82 {
    83 ZwClose(hRegister);
    84 KdPrint(("The item is not exist\n"));
    85 return;
    86 }
    87 pvpi =
    88 (PKEY_VALUE_PARTIAL_INFORMATION)
    89 ExAllocatePool(PagedPool,ulSize);
    90
    91 ntStatus = ZwQueryValueKey(hRegister,
    92 &ValueName,
    93 KeyValuePartialInformation ,
    94 pvpi,
    95 ulSize,
    96 &ulSize);
    97 if (!NT_SUCCESS(ntStatus))
    98 {
    99 ZwClose(hRegister);
    100 KdPrint(("Read regsiter error\n"));
    101 return;
    102 }
    103 //判断是否为REG_SZ类型
    104 if (pvpi->Type==REG_SZ)
    105 {
    106 KdPrint(("The value:%S\n",pvpi->Data));
    107 }
    108
    109 ZwClose(hRegister);
    110 }
    5、枚举子项

    ZwQueryKeyZwEnumerateKey 来枚举子项。

     ZwQueryKey获取某注册表项究竟有多少个子项,而ZwEnumerateKey 针对第几个子项获取该子项的具体信息。

    我们发现,凡是调用有长度的函数,一般都是两次调用,第一次调用来获得具体查询(使用该函数)需要的内存需要多大长度,第二次调用时来查询具体信息。

    示例代码

     

    代码
    1 VOID EnumerateSubItemRegTest()
    2 {
    3 UNICODE_STRING RegUnicodeString;
    4 HANDLE hRegister;
    5
    6 //初始化UNICODE_STRING字符串
    7 RtlInitUnicodeString( &RegUnicodeString,
    8 MY_REG_SOFTWARE_KEY_NAME);
    9
    10 OBJECT_ATTRIBUTES objectAttributes;
    11 //初始化objectAttributes
    12 InitializeObjectAttributes(&objectAttributes,
    13 &RegUnicodeString,
    14 OBJ_CASE_INSENSITIVE,//对大小写敏感
    15 NULL,
    16 NULL );
    17 //打开注册表
    18 NTSTATUS ntStatus = ZwOpenKey( &hRegister,
    19 KEY_ALL_ACCESS,
    20 &objectAttributes);
    21
    22 if (NT_SUCCESS(ntStatus))
    23 {
    24 KdPrint(("Open register successfully\n"));
    25 }
    26
    27 ULONG ulSize;
    28 //第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
    29 ZwQueryKey(hRegister,
    30 KeyFullInformation,
    31 NULL,
    32 0,
    33 &ulSize);
    34
    35 PKEY_FULL_INFORMATION pfi =
    36 (PKEY_FULL_INFORMATION)
    37 ExAllocatePool(PagedPool,ulSize);
    38
    39 //第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
    40 ZwQueryKey(hRegister,
    41 KeyFullInformation,
    42 pfi,
    43 ulSize,
    44 &ulSize);
    45
    46 for (ULONG i=0;i<pfi->SubKeys;i++)
    47 {
    48 //第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
    49 ZwEnumerateKey(hRegister,
    50 i,
    51 KeyBasicInformation,
    52 NULL,
    53 0,
    54 &ulSize);
    55
    56 PKEY_BASIC_INFORMATION pbi =
    57 (PKEY_BASIC_INFORMATION)
    58 ExAllocatePool(PagedPool,ulSize);
    59
    60 //第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
    61 ZwEnumerateKey(hRegister,
    62 i,
    63 KeyBasicInformation,
    64 pbi,
    65 ulSize,
    66 &ulSize);
    67
    68 UNICODE_STRING uniKeyName;
    69 uniKeyName.Length =
    70 uniKeyName.MaximumLength =
    71 (USHORT)pbi->NameLength;
    72
    73 uniKeyName.Buffer = pbi->Name;
    74
    75 KdPrint(("The %d sub item name:%wZ\n",i,&uniKeyName));
    76
    77 ExFreePool(pbi);
    78 }
    79
    80 ExFreePool(pfi);
    81 ZwClose(hRegister);
    82 }
    83
    6、枚举子键

    通过ZwQueryKeyZwEnumerateValueKey来枚举子键。

    7、删除子项

    ZwDeleteKey 

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

    8、其它

    DDK中定义了一些运行时函数来简化上面的操作。

    RtlCreateRegistryKey  创建注册表

    RtlCheckRegistryKey  checks for the existence of a given named key in the registry

    RtlWriteRegistryValue  写注册表

    RtlDeleteRegistryValue  删除注册表

    示例代码

    代码
    1 void RtlRegTest()
    2 {
    3 //创建子项目
    4 NTSTATUS ntStatus =
    5 RtlCreateRegistryKey(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan");
    6 if (NT_SUCCESS(ntStatus))
    7 {
    8 KdPrint(("Create the item successfully\n"));
    9 }
    10
    11 //检查某项是否存在
    12 ntStatus =
    13 RtlCheckRegistryKey(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan");
    14 if (NT_SUCCESS(ntStatus))
    15 {
    16 KdPrint(("The item is exist\n"));
    17 }
    18
    19 //写入REG_DWORD的数据
    20 ULONG value1 = 100;
    21 ntStatus =
    22 RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
    23 L"HelloDDK\\Zhangfan",
    24 L"DWORD_Value",
    25 REG_DWORD,
    26 &value1,
    27 sizeof(value1));
    28 if (NT_SUCCESS(ntStatus))
    29 {
    30 KdPrint(("Write the DWORD value succuessfully\n"));
    31 }
    32
    33 PWCHAR szString = L"Hello DDK";
    34 ntStatus =
    35 RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
    36 L"HelloDDK\\Zhangfan",
    37 L"SZ_Value",
    38 REG_SZ,
    39 szString,
    40 wcslen(szString)*2+2);
    41
    42 if (NT_SUCCESS(ntStatus))
    43 {
    44 KdPrint(("Write the REG_SZ value succuessfully\n"));
    45 }
    46
    47 RTL_QUERY_REGISTRY_TABLE paramTable[2];
    48 RtlZeroMemory(paramTable, sizeof(paramTable));
    49
    50 ULONG defaultData=0;
    51 ULONG uQueryValue;
    52 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
    53 paramTable[0].Name = L"DWORD_Value";
    54 paramTable[0].EntryContext = &uQueryValue;
    55 paramTable[0].DefaultType = REG_DWORD;
    56 paramTable[0].DefaultData = &defaultData;
    57 paramTable[0].DefaultLength = sizeof(ULONG);
    58
    59 //查询REG_DWORD的数据
    60 ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
    61 L"HelloDDK\\Zhangfan",
    62 paramTable,
    63 NULL,
    64 NULL);
    65 if (NT_SUCCESS(ntStatus))
    66 {
    67 KdPrint(("Query the item successfully\n"));
    68 KdPrint(("The item is :%d\n",uQueryValue));
    69 }
    70
    71 //删除子键
    72 ntStatus = RtlDeleteRegistryValue(RTL_REGISTRY_SERVICES,
    73 L"HelloDDK\\Zhangfan",
    74 L"DWORD_Value");
    75 if (NT_SUCCESS(ntStatus))
    76 {
    77 KdPrint(("delete the value successfully\n"));
    78 }
    79 }
    参考:

    1Windows驱动开发详解

    2MSDN

  • 相关阅读:
    C# WinForm TextBox 作为密码输入框时,如何禁止密码查看器获取密码 ?
    .net 程序运行在不同框架版本下的支持配置(主要是.net4.0 与 .net2.0的兼容)
    比较C#的静态常量(const)和动态常量(static和readonly)
    Linux 本地yum源 、阿里yum源、163yum源的配置安装
    Mysql 单机数据库迁移几种方式
    sed中使用变量及变量中存在特殊字符‘/’处理
    Linux下安装zookeeper、配置zookeeper开机自启动
    MySQL 不同场景下的迁移方案(转载)
    配置YUM源出现Errno 14 Could not open/read repomd.xml 或者 "Couldn't open file /mnt/cdrom/repodata/repomd.xml" 错误的解决办法
    Docker安装Rabbitmq并实现挂载宿主机数据目录
  • 原文地址:https://www.cnblogs.com/mydomain/p/1864013.html
Copyright © 2011-2022 走看看