内核中注册表操作
内核中的注册表操作和Win32下面是没有什么区别的. 最多来说就是函数的名字稍微换了下. 都是一个套路. 所以说学习新东西啊, 都是建立在旧东西的基础之上.而且内核中好像有一些比Win32更加好用的注册表操作函数. 一句话就可以实现很多功能. 真是舒服. 这些东西的话, 其实没有什么好说的,直接上代码吧, 代码能够说明一切.
内核中对注册表也就是那么个操作套路, 增删改查.遍历撒的. 好像很多都是只是换了个名称, 而且本来他们本来就是一个套路, Win32函数调用的时候进入内核也是调用那么些函数. 所以这些东西不需要多说了!!
/* Windows内核下注册表的操作! 编译方法参见makefile. TAB = 8 HKEY_LOCAL_MACHINE = \Registry\Machine HKEY_USERS = \Registry\User HKEY_CURRENT_CONFIG = \Registry\Machine\SYSTEM\CurrentControlSet\Hardware\Profiles\Current HKEY_CLASSES_ROOT = \Registry\Machine\SOFTWARE\Classes\ */ #include <ntddk.h> #include <ntstrsafe.h> #define REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\JoenRegister" #define REG_SOFTWARE_VALUE_NAME L"SubItem" //=========================================================================== //创建新键值 #pragma code_seg( "INIT" ) NTSTATUS CreateNewKey( ) { HANDLE hKey; HANDLE hKey2; ULONG ulResult; OBJECT_ATTRIBUTES Obj_Attr; NTSTATUS Status; UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME ); UNICODE_STRING UStValueName = RTL_CONSTANT_STRING( REG_SOFTWARE_VALUE_NAME ); InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL ); //创建或带开注册表项目 Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" )); return Status; }else { //判断是被新创建,还是已经被创建 if( ulResult == REG_CREATED_NEW_KEY ) { KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); }else if( ulResult == REG_OPENED_EXISTING_KEY ) { KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); } } //打开一个注册表句柄下的一个子项目 InitializeObjectAttributes( &Obj_Attr, &UStValueName, OBJ_CASE_INSENSITIVE, hKey, NULL ); //创建/打开一个注册表句柄下的另一个句柄 Status = ZwCreateKey( &hKey2,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult); if ( !NT_SUCCESS(Status) ) { KdPrint(( "创建/打开子句柄SubItem失败!\n" )); return Status; }else { //判断是被新创建,还是已经被创建 if( ulResult == REG_CREATED_NEW_KEY ) { KdPrint(("创建子句柄SubItem成功\n")); }else if( ulResult == REG_OPENED_EXISTING_KEY ) { KdPrint(("打开子句柄SubItem成功\n")); } } ZwClose( hKey2 ); ZwClose( hKey ); //---------------------------------------------------------------------------- InitializeObjectAttributes( &Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL ); //只是打开注册表项目, 如果不存在返回失败 Status = ZwOpenKey( &hKey,KEY_ALL_ACCESS, &Obj_Attr ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "打开\\Registry\\Machine\\Software\\JoenRegister失败\n" )); return Status; }else { KdPrint(( "打开\\Registry\\Machine\\Software\\JoenRegister成功\n" )); } ZwClose( hKey ); return Status; } //=========================================================================== //设置键值试验, 设置键值可以覆盖原来的值. #pragma code_seg( "INIT" ) NTSTATUS SetKeyValue() { HANDLE hKey = 0; ULONG ulResult; ULONG ulValue; NTSTATUS Status; CHAR byArr[8] = {0}; OBJECT_ATTRIBUTES Obj_Attr; UNICODE_STRING UStValueKey = RTL_CONSTANT_STRING( L"Reg_Sz" ); UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME ); InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL ); //创建或带开注册表项目 Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" )); return Status; }else { //判断是被新创建,还是已经被创建 if( ulResult == REG_CREATED_NEW_KEY ) { KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); }else if( ulResult == REG_OPENED_EXISTING_KEY ) { KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); } } do { //设置默认键值 Status = ZwSetValueKey(hKey, (PUNICODE_STRING)byArr, 0,REG_SZ, L"Hello",sizeof(L"hello")+2); if ( !NT_SUCCESS(Status) ) { KdPrint(( "设置默认键值失败\n" )); break; } //设置某个键的键值 Status = ZwSetValueKey(hKey, &UStValueKey, 0, REG_SZ, L"String", sizeof(L"String")+2 ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "设置Reg_Sz键值失败\n" )); break; } //设置某个键的键值 DWORD类型 ulValue = 100; RtlInitUnicodeString(&UStValueKey, L"Reg_Dword" ); Status = ZwSetValueKey(hKey, &UStValueKey, 0, REG_DWORD, &ulValue, sizeof(ulValue)); if ( !NT_SUCCESS(Status) ) { KdPrint(( "设置Reg_Sz键值失败\n" )); break; } } while ( FALSE ); if ( hKey ) { ZwClose(hKey); } return Status; } //=========================================================================== //查询键值试验, 这个查询键值ZwQueryValueKey 和那个ZwQuery, 注意区分 #pragma code_seg( "INIT" ) NTSTATUS QueryValueInfo() { HANDLE hKey = 0; ULONG ulResult; ULONG ulSize; NTSTATUS Status; OBJECT_ATTRIBUTES Obj_Attr; UNICODE_STRING UStValueKey = RTL_CONSTANT_STRING( L"Reg_Dword" ); UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME ); PKEY_VALUE_PARTIAL_INFORMATION pKeyPartialInfo = NULL; InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL ); //创建或带开注册表项目 Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" )); return Status; }else { //判断是被新创建,还是已经被创建 if( ulResult == REG_CREATED_NEW_KEY ) { KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); }else if( ulResult == REG_OPENED_EXISTING_KEY ) { KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n")); } } do { //读取REG_DWORD子键, 这里只是尝试着搞一下 Status = ZwQueryValueKey( hKey, &UStValueKey, KeyValuePartialInformation,NULL,0,&ulSize); if ( Status == STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0 ) { KdPrint(("Reg_Dword子键不存在\n")); break; } //分配结构需要的内存 pKeyPartialInfo = ExAllocatePool(PagedPool,ulSize); if ( !pKeyPartialInfo ) { KdPrint(( "pKeyPartialInfo内存分配失败\n" )); break; } //这次才是真正的查询 Status = ZwQueryValueKey(hKey, &UStValueKey,KeyValuePartialInformation, pKeyPartialInfo,ulSize,&ulSize); if ( !NT_SUCCESS(Status) ) { KdPrint(("读取Reg_Dword子键失败\n")); break; } //判断是否为REG_DWORD类型 if (pKeyPartialInfo->Type==REG_DWORD && pKeyPartialInfo->DataLength==sizeof(ULONG)) { KdPrint(("查询子键 Reg_Dword:%d\n", *((PULONG)pKeyPartialInfo->Data)) ); } if ( pKeyPartialInfo ) { ExFreePool( pKeyPartialInfo ); pKeyPartialInfo = NULL; } //--------------------------------------------------------------------------- RtlInitUnicodeString( &UStValueKey, L"Reg_Sz" ); //读取REG_SZ子键 Status = ZwQueryValueKey(hKey,&UStValueKey,KeyValuePartialInformation,NULL,0,&ulSize); if ( Status == STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0 ) { KdPrint(("Reg_Sz子键不存在!\n")); break; } //分配结构需要的内存 pKeyPartialInfo = ExAllocatePool(PagedPool,ulSize); if ( !pKeyPartialInfo ) { KdPrint(( "pKeyPartialInfo内存分配失败\n" )); break; } //这次才是真正的查询 Status = ZwQueryValueKey(hKey, &UStValueKey,KeyValuePartialInformation, pKeyPartialInfo,ulSize,&ulSize); if ( !NT_SUCCESS(Status) ) { KdPrint(("读取Reg_Sz子键失败\n")); break; } //判断是否为REG_SZ类型 if (pKeyPartialInfo->Type==REG_SZ ){ KdPrint(("Reg_Sz值为:%ws\n",pKeyPartialInfo->Data) ); } } while ( FALSE ); //--------------------------------------------------------------------------- if ( hKey ) { ZwClose(hKey); } if ( pKeyPartialInfo ) { ExFreePool( pKeyPartialInfo ); } return Status; } //=========================================================================== //枚举子项中的键值, 键值哈. //pUSzRegPath :要枚举的子项目名称 #pragma code_seg( "INIT" ) VOID EnumerateSubValue( const PUNICODE_STRING pUSzRegPath ) { HANDLE hKey = 0; ULONG ulSize; ULONG i; NTSTATUS Status; UNICODE_STRING UStKeyName; OBJECT_ATTRIBUTES Obj_Attr; PKEY_FULL_INFORMATION pKeyFullInfo = NULL; PKEY_VALUE_BASIC_INFORMATION pKeyValueBasicInfo = NULL; //初始化objectAttributes InitializeObjectAttributes( &Obj_Attr, pUSzRegPath,OBJ_CASE_INSENSITIVE,NULL,NULL); //打开注册表 Status = ZwOpenKey( &hKey, KEY_ALL_ACCESS,&Obj_Attr ); if (!NT_SUCCESS(Status)){ return; } //首次尝试查询子项信息 ZwQueryKey( hKey,KeyFullInformation,NULL,0, &ulSize ); pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize); if ( !pKeyFullInfo ) { return; } //再次查询子项信息 Status = ZwQueryKey( hKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "查询子项信息失败!\n" )); } for ( i=0; i< pKeyFullInfo->Values; i++ ) { //枚举键值信息 ZwEnumerateValueKey( hKey,i, KeyValueBasicInformation, NULL, 0, &ulSize ); pKeyValueBasicInfo =(PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize); if ( !pKeyValueBasicInfo ) { KdPrint(( "内存申请失败!\n" )); break; } Status = ZwEnumerateValueKey(hKey,i,KeyValueBasicInformation,pKeyValueBasicInfo, ulSize,&ulSize); if ( !NT_SUCCESS(Status) ) { KdPrint(( "枚举键值失败!\n" )); } UStKeyName.Length = UStKeyName.MaximumLength =(USHORT)pKeyValueBasicInfo->NameLength; UStKeyName.Buffer = pKeyValueBasicInfo->Name; KdPrint(("\t子项%d名称:%wZ\t",i,&UStKeyName)); if (pKeyValueBasicInfo->Type==REG_SZ ){ KdPrint(( "REG_SZ\n" )); }else if (pKeyValueBasicInfo->Type==REG_MULTI_SZ ){ KdPrint(( "REG_MULTI_SZ\n" )); }else if (pKeyValueBasicInfo->Type==REG_DWORD ){ KdPrint(( "REG_DWORD\n" )); }else if (pKeyValueBasicInfo->Type==REG_BINARY ){ KdPrint(( "REG_BINARY\n" )); } if ( pKeyValueBasicInfo ) { ExFreePool(pKeyValueBasicInfo); pKeyValueBasicInfo = NULL; } } //--------------------------------------------------------------------------- if ( pKeyFullInfo ) { ExFreePool(pKeyFullInfo); } if ( hKey ) { ZwClose(hKey); } } //=========================================================================== //枚举键值和子项测试, 删除只能从最底层开始删除. #pragma code_seg( "INIT" ) NTSTATUS EnumerateKeyValue() { HANDLE hKey = 0; ULONG ulSize; ULONG i; NTSTATUS Status; UNICODE_STRING UStKeyName; UNICODE_STRING UStSubKeyName; OBJECT_ATTRIBUTES Obj_Attr; PKEY_FULL_INFORMATION pKeyFullInfo = NULL; PKEY_BASIC_INFORMATION pKeyBasicInfo = NULL; UNICODE_STRING UStItemName = RTL_CONSTANT_STRING( L"\\Registry\\Machine\\Software\\" ); //初始化objectAttributes InitializeObjectAttributes(&Obj_Attr,&UStItemName,OBJ_CASE_INSENSITIVE,NULL,NULL ); //打开注册表 Status = ZwOpenKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr); if ( NT_SUCCESS( Status )) { KdPrint(( "打开注册表\\Registry\\Machine\\Software\\成功, 准备枚举\n" )); }else { KdPrint(( "打开注册表成功失败\n" )); } do { //第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度 Status = ZwQueryKey(hKey,KeyFullInformation,NULL,0,&ulSize ); pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize); if ( !pKeyFullInfo ) { KdPrint(( "内存分配失败\n" )); break; } //第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据 Status = ZwQueryKey(hKey,KeyFullInformation,pKeyFullInfo,ulSize,&ulSize); if ( !NT_SUCCESS(Status) ) { KdPrint(( "二次查询子键信息失败\n" )); break; } //--------------------------------------------------------------------------- for (i=0; i < pKeyFullInfo->SubKeys; i++ ) { //第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度 ZwEnumerateKey(hKey,i,KeyBasicInformation,NULL,0,&ulSize); pKeyBasicInfo = ExAllocatePool(PagedPool,ulSize); if ( !pKeyBasicInfo ) { break; } //第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据 Status = ZwEnumerateKey( hKey,i,KeyBasicInformation,pKeyBasicInfo,ulSize,&ulSize); if ( !NT_SUCCESS(Status) ) { KdPrint(( "枚举子键的时候遇到错误\n" )); break; } //填写名称信息 UStKeyName.Length = UStKeyName.MaximumLength = (USHORT)pKeyBasicInfo->NameLength; UStKeyName.Buffer = pKeyBasicInfo->Name; KdPrint(("第 %d 项的名称是: %wZ\n",i,&UStKeyName)); //给子字符串分配内存 UStSubKeyName.Buffer = (PWSTR)ExAllocatePool( PagedPool, \ sizeof(L"\\Registry\\Machine\\Software\\") + wcslen(UStKeyName.Buffer)*2+2 ); UStSubKeyName.MaximumLength = sizeof(L"\\Registry\\Machine\\Software\\") + wcslen(UStKeyName.Buffer)*2+2; RtlCopyUnicodeString( &UStSubKeyName, &UStItemName ); RtlUnicodeStringCat( &UStSubKeyName, &UStKeyName); //枚举子键值. EnumerateSubValue( &UStSubKeyName ); if ( pKeyBasicInfo ) { ExFreePool( pKeyBasicInfo ); pKeyBasicInfo = NULL; } RtlFreeUnicodeString( &UStSubKeyName ); } if ( pKeyBasicInfo ) { ExFreePool(pKeyBasicInfo); } } while ( FALSE ); //--------------------------------------------------------------------------- if ( pKeyFullInfo ) { ExFreePool(pKeyFullInfo); } if ( hKey ) { ZwClose(hKey); } return Status; } //=========================================================================== //删除子项试验 #pragma code_seg( "INIT" ) NTSTATUS DeleteKey() { HANDLE hKey = 0; NTSTATUS Status; OBJECT_ATTRIBUTES ObjAttr; UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( L"\\Registry\\Machine\\Software\\JoenRegister\\SubItem"); //初始化objectAttributes InitializeObjectAttributes(&ObjAttr,&UStKeyName,OBJ_CASE_INSENSITIVE,NULL,NULL ); //打开注册表 Status = ZwOpenKey( &hKey, KEY_ALL_ACCESS,&ObjAttr ); if ( !NT_SUCCESS(Status) ){ KdPrint(( "打开注册表失败!\n" )); return Status; } //删除键 Status = ZwDeleteKey( hKey ); if ( NT_SUCCESS(Status) ){ KdPrint(("删除\\Registry\\Machine\\Software\\JoenRegister\\SubItem成功!\n")); }else if( Status == STATUS_ACCESS_DENIED ){ KdPrint(("权限不够\n")); }else if( Status == STATUS_INVALID_HANDLE ){ KdPrint(("句柄无效\n")); }else{ KdPrint(("无法删除\n")); } if ( hKey ) { ZwClose( hKey); } return Status; } //=========================================================================== //Rtl系列函数试验 #pragma code_seg( "INIT" ) NTSTATUS RtlRegister() { ULONG ulValue; NTSTATUS Status; ULONG ulDefaultData=0; ULONG ulQueryValue; PWCHAR SzString = L"Sz_Hello"; RTL_QUERY_REGISTRY_TABLE RtlQueryTab[2] = {0}; //按照绝对路径创建一个键 Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "创建子键失败!\n" )); return Status; }else { KdPrint(( "创建子键成功!\n" )); } //检查某项是否存在 Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "子键不存在!\n" )); return Status; }else { KdPrint(( "子键存在!\n" )); } //写入REG_DWORD的数据 ulValue = 100; Status = RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME, L"DWORD_Value",REG_DWORD, &ulValue, sizeof(ulValue) ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "写入子键失败!\n" )); return Status; }else { KdPrint(( "写入子键成功!\n" )); } //写入一个字符串 Status = RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME, L"SZ_Value",REG_SZ, SzString, wcslen(SzString)*2+2 ); if ( !NT_SUCCESS(Status) ) { KdPrint(( "写入字符串失败!\n" )); return Status; }else { KdPrint(( "写入字符串成功!\n" )); } //查询REG_DWORD的数据 RtlQueryTab[0].Flags = RTL_QUERY_REGISTRY_DIRECT; RtlQueryTab[0].Name = L"DWORD_Value"; RtlQueryTab[0].EntryContext = &ulQueryValue; RtlQueryTab[0].DefaultType = REG_DWORD; RtlQueryTab[0].DefaultData = &ulDefaultData; RtlQueryTab[0].DefaultLength = sizeof(ULONG); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME, RtlQueryTab,NULL,NULL); if ( !NT_SUCCESS(Status) ) { KdPrint(( "查询失败!\n" )); return Status; }else { KdPrint(( "查询成功, 值为%d!\n", ulQueryValue )); } //删除子键 Status = RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME,L"DWORD_Value"); if ( !NT_SUCCESS(Status) ) { KdPrint(( "删除子键失败!\n" )); return Status; }else { KdPrint(( "删除子键成功!\n" )); } return Status; } //=========================================================================== #pragma code_seg( "INIT" ) NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUStrPath ) { CreateNewKey(); //创建新键值试验 SetKeyValue(); //设置键值试验 QueryValueInfo(); //查询键值试验 EnumerateKeyValue(); //枚举键值和项测试 DeleteKey(); //删除子项试验 RtlRegister(); //Rtl系列函数试验 return -2; }
发表评论
Warning: Undefined variable $user_ID in /www/wwwroot/joenchen.com/wp-content/themes/x-agan/comments.php on line 66
您必须登录 才能进行评论。