168 lines
4.9 KiB
C
168 lines
4.9 KiB
C
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <kph.h>
|
|
#define _DYNDATA_PRIVATE
|
|
#include <dyndata.h>
|
|
|
|
#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;
|
|
}
|