直接上代碼
.h文件
#pragma once
#include<wdm.h>
#define TAG 0x44434241 // 動態內存的標誌
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath); // 入口
#ifdef __cplusplus
}
#endif // __cplusplus
void driverUnload(PDRIVER_OBJECT pDriver); // 驅動卸載回調
void keyDemo(PUNICODE_STRING pRegPath); // 註冊表鍵值查詢操作演示
.cpp文件
#include "driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath)
{
pDriver->DriverUnload = driverUnload; // 綁定卸載回調
DbgPrint("path = %wZ", pRegPath); // 打印所在註冊表路徑
keyDemo(pRegPath); // 註冊表鍵值演示
return STATUS_SUCCESS;
}
// 驅動對象卸載回調
void driverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("++++驅動卸載++++");
}
// 鍵值查詢演示
void keyDemo(PUNICODE_STRING pRegPath)
{
HANDLE rHandle = NULL; // 定義一個句柄
OBJECT_ATTRIBUTES oAttributes; // 定義一個用於對象結構
// 初始化該對象的宏
InitializeObjectAttributes(&oAttributes, pRegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
auto isOpen = ZwOpenKey(&rHandle, KEY_ALL_ACCESS, &oAttributes); // 打開鍵值
if (!NT_SUCCESS(isOpen))
{
DbgPrint("打開鍵值失敗");
return;
}
else
{
DbgPrint("打開鍵值成功");
}
UNICODE_STRING valueName; // 定義寬字節字符串結構
RtlInitUnicodeString(&valueName, L"ImagePath"); // 初始化寬字節字符串。這是要打開的鍵值
ULONG length; // 接受長度的變量
ZwQueryValueKey(rHandle, &valueName, KeyValuePartialInformation, nullptr, 0, &length); // 首先查詢實際只是要求出實際需要的字節數
PKEY_VALUE_PARTIAL_INFORMATION keyInfo = // 分配動態內存
reinterpret_cast<PKEY_VALUE_PARTIAL_INFORMATION>(ExAllocatePoolWithTag(PagedPool, length, TAG));
if (keyInfo == nullptr)
{
DbgPrint("動態內存分配失敗");
ZwClose(rHandle);
return;
}
// 再次查詢獲取信息
auto isQuery = ZwQueryValueKey(rHandle, &valueName, KeyValuePartialInformation, keyInfo, length, &length);
if (!NT_SUCCESS(isQuery))
{
DbgPrint("查詢鍵值失敗");
}
else
{
DbgPrint("%ls", reinterpret_cast<wchar_t*>(keyInfo->Data)); // 將獲取到的鍵值打印控制檯
}
ExFreePoolWithTag(keyInfo, TAG); // 釋放動態內存
ZwClose(rHandle); // 關閉句柄
}