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

  • 相关阅读:
    461. Hamming Distance
    342. Power of Four
    326. Power of Three
    368. Largest Divisible Subset java solutions
    95. Unique Binary Search Trees II java solutions
    303. Range Sum Query
    160. Intersection of Two Linked Lists java solutions
    88. Merge Sorted Array java solutions
    67. Add Binary java solutions
    14. Longest Common Prefix java solutions
  • 原文地址:https://www.cnblogs.com/mydomain/p/1864013.html
Copyright © 2011-2022 走看看