我需要从注册表(最好)或文件读取设置。驱动程序是一个内核驱动程序,它设置为启动类型为SYSTEM
,因此所有服务和WinAPI都不一定可用。
我试图使用RtlQueryRegistryValues
函数从注册表中读取单个字符串值,但是无论我做什么,我似乎都会得到相同的0xC0000034
错误代码,这些代码被转换成STATUS_OBJECT_NAME_NOT_FOUND
。
根据MSDN上可用的文档,当路径参数不匹配有效键或设置了特定标志且不满足该标志的特定条件时,STATUS_OBJECT_NAME_NOT_FOUND
将从RtlQueryRegistryValues
返回。据我所知,注册表项实际上存在于我的测试机器中,而且我没有使用RTL_QUERY_REGISTRY_REQUIRED
标志。
我试图读取的注册表值位于HKEY_LOCAL_MACHINE/SOFTWARE/company/ProjectName
下面,我试图同时读取默认值和名为parameter
的REG_SZ值。对RtlQueryRegistryValues
的调用是在DriverEntry(.)期间执行的加载驱动程序的阶段。
我不知道我做错了什么,而且由于我对内核驱动程序并不熟悉,而且调试过程非常繁琐,所以我不确定我是否只是错误地引用了注册表值,或者在系统启动的这一阶段是否可以使用注册表。
mydriver.c
NTSTATUS DriverEntry(...) {
NTSTATUS regStatus = 0;
UNICODE_STRING data;
RTL_QUERY_REGISTRY_TABLE query[2];
WCHAR* regPath = L"\\Registry\\Machine\\SOFTWARE\\Company\\ProjectName";
RtlZeroMemory(query, sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
data.Buffer = NULL;
data.MaximumLength = 0;
data.Length = 0;
// query[0].Name = L"Parameter";
query[0].Name = L""; // L"" refers to the default value
query[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
query[0].EntryContext = &data;
regStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, regPath, query, NULL, NULL);
DebugPrint("regStatus: %lx\n", regStatus);
DebugPrint("data: %wZ\n", &data);
}
发布于 2014-05-15 13:58:48
我不是100%确定,但我怀疑软件子树的注册表单元没有加载。你为什么要访问它?驱动程序配置参数的适当位置是它自己的注册表项(\Registry\Machine\System\CurrentControlSet\Services\<DriverName>\
),它的路径甚至被传递给您的DriverEntry
函数,因此您不需要硬编码它。
另见:设备和驱动程序的注册表树和键。
发布于 2020-08-28 20:26:13
您可以使用传入DriverEntry
的DriverEntry
,如下所示:
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
// ...
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING valueName = RTL_CONSTANT_STRING(L"<YOUR_VALUE_NAME>");
HANDLE hRegistryKey;
PKEY_VALUE_FULL_INFORMATION pKeyInfo = nullptr;
// Create object attributes for registry key querying
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
InitializeObjectAttributes(&ObjectAttributes, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
do {
ntStatus = ZwOpenKey(&hRegistryKey, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(ntStatus)) {
KdPrint((DRIVER_PREFIX "Registry key open failed (0x%08X)\n", ntStatus));
break;
}
ULONG ulKeyInfoSize;
ULONG ulKeyInfoSizeNeeded = GetKeyInfoSize(hRegistryKey, &valueName);
if (ulKeyInfoSizeNeeded == 0) {
KdPrint((DRIVER_PREFIX "Value not found\n"));
break;
}
ulKeyInfoSize = ulKeyInfoSizeNeeded;
pKeyInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, ulKeyInfoSize, DRIVER_TAG);
if (pKeyInfo == nullptr) {
KdPrint((DRIVER_PREFIX "Could not allocate memory for KeyValueInfo\n"));
break;
}
RtlZeroMemory(pKeyInfo, ulKeyInfoSize);
ntStatus = ZwQueryValueKey(hRegistryKey, &valueName, KeyValueFullInformation, pKeyInfo, ulKeyInfoSize, &ulKeyInfoSizeNeeded);
if (!NT_SUCCESS(ntStatus) || ulKeyInfoSize != ulKeyInfoSizeNeeded) {
KdPrint((DRIVER_PREFIX "Registry value querying failed (0x%08X)\n", ntStatus));
break;
}
// your data
ULONG someLong = *(ULONG*)((ULONG_PTR)pKeyInfo + pKeyInfo->DataOffset);
} while (false);
// cleanup
if (hRegistryKey) {
ZwClose(hRegistryKey);
}
if (pKeyInfo) {
ExFreePoolWithTag(pKeyInfo, DRIVER_TAG);
}
if (!NT_SUCCESS(ntStatus)) {
// Here you can set a default data if something failed it the way
}
// ...
}
ULONG GetKeyInfoSize(HANDLE hRegistryKey, PUNICODE_STRING pValueName) {
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG ulKeyInfoSizeNeeded;
ntStatus = ZwQueryValueKey(hRegistryKey, pValueName, KeyValueFullInformation, 0, 0, &ulKeyInfoSizeNeeded);
if (ntStatus == STATUS_BUFFER_TOO_SMALL || ntStatus == STATUS_BUFFER_OVERFLOW) {
// Expected don't worry - when ZwQueryValueKey fails with one of the above statuses, it returns the size needed
return ulKeyInfoSizeNeeded;
}
else {
KdPrint((DRIVER_PREFIX "Could not get key info size (0x%08X)\n", ntStatus));
}
return 0;
}
在我的例子中,我正在阅读一个ULONG
,但它可能是任何东西,它的想法是,您想要读取的地址位于address pKeyInfo + pKeyInfo->DataOffset
。
发布于 2022-08-15 12:39:51
看起来问题就在RTL_QUERY_REGISTRY_DIRECT
上。
根据文献资料,它还需要设置RTL_QUERY_REGISTRY_TYPECHECK
标志。
反过来,RTL_QUERY_REGISTRY_TYPECHECK
标志需要设置DefaultType
和DefaultSize
(of PKEY_VALUE_FULL_INFORMATION
)。至少这是我所发现的,这不是根据文档。
https://stackoverflow.com/questions/23675956
复制相似问题