/*
* KProcessHacker
*
* Copyright (C) 2010-2016 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see .
*/
#include
#define _DYNDATA_PRIVATE
#include
#define C_2sTo4(x) ((unsigned int)(signed short)(x))
NTSTATUS KphpLoadDynamicConfiguration(
__in PVOID Buffer,
__in ULONG Length
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KphDynamicDataInitialization)
#pragma alloc_text(PAGE, KphReadDynamicDataParameters)
#pragma alloc_text(PAGE, KphpLoadDynamicConfiguration)
#endif
NTSTATUS KphDynamicDataInitialization(
VOID
)
{
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
// Get Windows version information.
KphDynOsVersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
status = RtlGetVersion((PRTL_OSVERSIONINFOW)&KphDynOsVersionInfo);
return status;
}
NTSTATUS KphReadDynamicDataParameters(
__in_opt HANDLE KeyHandle
)
{
NTSTATUS status;
UNICODE_STRING valueName;
PKEY_VALUE_PARTIAL_INFORMATION info;
ULONG resultLength;
PAGED_CODE();
if (!KeyHandle)
return STATUS_UNSUCCESSFUL;
RtlInitUnicodeString(&valueName, L"DynamicConfiguration");
status = ZwQueryValueKey(
KeyHandle,
&valueName,
KeyValuePartialInformation,
NULL,
0,
&resultLength
);
if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL)
{
// Unexpected status; fail now.
return STATUS_UNSUCCESSFUL;
}
info = ExAllocatePoolWithTag(PagedPool, resultLength, 'ThpK');
if (!info)
return STATUS_INSUFFICIENT_RESOURCES;
status = ZwQueryValueKey(
KeyHandle,
&valueName,
KeyValuePartialInformation,
info,
resultLength,
&resultLength
);
if (NT_SUCCESS(status))
{
if (info->Type == REG_BINARY)
status = KphpLoadDynamicConfiguration(info->Data, info->DataLength);
else
status = STATUS_OBJECT_TYPE_MISMATCH;
if (!NT_SUCCESS(status))
dprintf("Unable to load dynamic configuration: 0x%x\n", status);
}
ExFreePoolWithTag(info, 'ThpK');
return status;
}
NTSTATUS KphpLoadDynamicConfiguration(
__in PVOID Buffer,
__in ULONG Length
)
{
PKPH_DYN_CONFIGURATION config;
ULONG i;
PKPH_DYN_PACKAGE package;
PAGED_CODE();
config = Buffer;
if (Length < FIELD_OFFSET(KPH_DYN_CONFIGURATION, Packages))
return STATUS_INVALID_PARAMETER;
if (config->Version != KPH_DYN_CONFIGURATION_VERSION)
return STATUS_INVALID_PARAMETER;
if (config->NumberOfPackages > KPH_DYN_MAXIMUM_PACKAGES)
return STATUS_INVALID_PARAMETER;
if (Length < FIELD_OFFSET(KPH_DYN_CONFIGURATION, Packages) + config->NumberOfPackages * sizeof(KPH_DYN_PACKAGE))
return STATUS_INVALID_PARAMETER;
dprintf("Loading dynamic configuration with %u package(s)\n", config->NumberOfPackages);
for (i = 0; i < config->NumberOfPackages; i++)
{
package = &config->Packages[i];
if (package->MajorVersion == KphDynOsVersionInfo.dwMajorVersion &&
package->MinorVersion == KphDynOsVersionInfo.dwMinorVersion &&
(package->ServicePackMajor == (USHORT)-1 || package->ServicePackMajor == KphDynOsVersionInfo.wServicePackMajor) &&
(package->BuildNumber == (USHORT)-1 || package->BuildNumber == KphDynOsVersionInfo.dwBuildNumber))
{
dprintf("Found matching package at index %u for Windows %u.%u\n", i, package->MajorVersion, package->MinorVersion);
KphDynNtVersion = package->ResultingNtVersion;
KphDynEgeGuid = C_2sTo4(package->StructData.EgeGuid);
KphDynEpObjectTable = C_2sTo4(package->StructData.EpObjectTable);
KphDynEreGuidEntry = C_2sTo4(package->StructData.EreGuidEntry);
KphDynHtHandleContentionEvent = C_2sTo4(package->StructData.HtHandleContentionEvent);
KphDynOtName = C_2sTo4(package->StructData.OtName);
KphDynOtIndex = C_2sTo4(package->StructData.OtIndex);
KphDynObDecodeShift = C_2sTo4(package->StructData.ObDecodeShift);
KphDynObAttributesShift = C_2sTo4(package->StructData.ObAttributesShift);
return STATUS_SUCCESS;
}
}
return STATUS_NOT_FOUND;
}