4.2注冊表操作 - 打開和讀取

注冊表在應用中和內核中有區別.在驅動中全部使用路徑來表示,而不是一般應用程序編程中需要提供的根子健句柄.

應用中 HKEY_LOCAL_MACHINE 驅動中 \Registry\Machine

應用中 HKEY_USERS 驅動中 \Registry\User

應用中 HKEY_CLASSES_ROOT 驅動中沒有對應的路徑

應用中 HKEY_CURRENT_USER 驅動中也沒簡單的有對應路徑,但是可以求得

打開注冊表鍵使用函數 ZwOpenKey 新建或者打開 ZwCreateKey

打開注冊表使用以下函數,不直接接受一個字符串,而是 OBJECT_ATTRIBUTES 指針(需要初始化,參考創建文件部分):

ZwOpenKey(

//OBJECT_ATTRIBUTES結構的指針

_Out_ PHANDLE KeyHandle,

//設置權限,可以組合 KEY_QUERY_VALUE 讀取鍵下的值 KEY_SET_VALUE 設置鍵下的值

//KEY_CREATE_SUB_KEY 生成子健 KEY_ENUMERATE_SUB_KEYS 枚舉子健

//實際可以使用 KEY_READ KEY_WRITE 和 KEY_ALL_ACCESS 這些組合宏

_In_ ACCESS_MASK DesiredAccess,

_In_ POBJECT_ATTRIBUTES ObjectAttributes

);

注冊表鍵值的讀取使用 ZwQueryValueKey ,注意注冊表鍵值的類型和長度.

返回值:如果實際需要的長度比用戶設置的要大,返回 STATUS_BUFFER_OVERFLOW 或者 STATUS_BUFFER_TOO_SMALL

如果成功讀出全部數據,返回 STATUS_SUCCESS 其他情況,返回錯誤碼

ZwQueryValueKey(

//打開的注冊表鍵的句柄

_In_ HANDLE KeyHandle,

//要讀取的值的名字

_In_ PUNICODE_STRING ValueName,

//需要查詢的信息類型

//KeyValueBasicInformation 獲得基礎信息,包涵值名和類型

//KeyValueFullInformation 獲得完整信息,包含值名,類型和值

//KeyValuePartialInformation 獲得局部信息,包含類型和值 <-- 這個最常用

_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,

//當上面的變量是獲取局部信息時,KEY_VALUE_PARTIAL_INFORMATION 結構的指針返回到這里

//這個結構有4個參數,2=數據類型 3=數據長度 4=可變長度的數據

_Out_writes_bytes_opt_(Length) PVOID KeyValueInformation,

//用戶傳入的輸入空間 KeyValueInformation 的長度

_In_ ULONG Length,

//返回實際需要的長度

_Out_ PULONG ResultLength

);

因為不知道返回的值有多長,所以我們應該先獲取長度,然后不足時在動態分配內存進行讀取.

注冊表打開和讀取的完全實例:

#include

VOID DriverUnload(PDRIVER_OBJECT driver){

}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path){

//注冊表鍵句柄

HANDLE mykey = NULL;

//函數執行的返回結果

NTSTATUS status;

//靜態定義要獲取的注冊表路徑

UNICODE_STRING mykeypath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");

//注冊表對象屬性,包涵注冊表路徑名稱

OBJECT_ATTRIBUTES myobjattr = { 0 };

//初始化 OBJECT_ATTRIBUTES

InitializeObjectAttributes(&myobjattr, &mykeypath,OBJ_CASE_INSENSITIVE,NULL,NULL);

//打開注冊表Key

status = ZwOpenKey(&mykey, KEY_READ, &myobjattr);

if (!NT_SUCCESS(status)){

DbgPrint("misaka: open regeditkey failed\r\n");

}

//要讀取的值的名字

UNICODE_STRING mykeyname = RTL_CONSTANT_STRING(L"ProductName");

//用來測試大小的 和 實際使用的keyinfo指針

KEY_VALUE_PARTIAL_INFORMATION keyinfo;

PKEY_VALUE_PARTIAL_INFORMATION ackeyinfo;

ULONG aclength;

//讀取注冊表鍵的值

status = ZwQueryValueKey(mykey, &mykeyname, KeyValuePartialInformation, &keyinfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION),&aclength);

if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL){

DbgPrint("misaka: read regeditkeyvalue failed\r\n");

}

//分配需要的空間, ZwQueryValueKey 的第4個參數可以獲得需要的長度

ackeyinfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, aclength, 2333);

if (ackeyinfo == NULL){

status = STATUS_INSUFFICIENT_RESOURCES;//錯誤處理

}

status = ZwQueryValueKey(mykey, &mykeyname, KeyValuePartialInformation, ackeyinfo,aclength,&aclength);

if (status == STATUS_SUCCESS){

UNICODE_STRING str = { 0 };

RtlInitUnicodeString(&str, (PCWSTR)ackeyinfo->Data);

DbgPrint("misaka: read regeditkeyvalue successfully ,data is: %wZ\r\n", str);

}else{

DbgPrint("misaka: read regeditkeyvalue failed\r\n");

}

driver->DriverUnload = DriverUnload;

return STATUS_SUCCESS;

}

輸出:

misaka: read regeditkeyvalue successfully ,data is: Windows 7 Ultimate

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容