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

  • 相关阅读:
    leetcode 268. Missing Number
    DBSCAN
    python二维数组初始化
    leetcode 661. Image Smoother
    leetcode 599. Minimum Index Sum of Two Lists
    Python中的sort() key含义
    leetcode 447. Number of Boomerangs
    leetcode 697. Degree of an Array
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月3日)
    北京Uber优步司机奖励政策(1月2日)
  • 原文地址:https://www.cnblogs.com/mydomain/p/1864013.html
Copyright © 2011-2022 走看看