[SDK:DDK] Implement the Auxiliary Kernel-Mode Library

And uncomment the code in KMDF which uses it
This commit is contained in:
Victor Perevertkin 2021-03-10 16:43:59 +03:00
parent a63213272a
commit 0a26c7c5d2
No known key found for this signature in database
GPG Key ID: C750B7222E9C7830
6 changed files with 452 additions and 129 deletions

View File

@ -0,0 +1,94 @@
/*
* aux_klib.h
*
* Auxiliary Kernel-Mode Library
*
* Contributors:
* Victor Perevertkin <victor.perevertkin@reactos.org>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#pragma once
#ifndef PIMAGE_EXPORT_DIRECTORY
#include <ntimage.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define AUX_KLIB_MODULE_PATH_LEN 0x100
typedef struct _AUX_MODULE_BASIC_INFO {
PVOID ImageBase;
} AUX_MODULE_BASIC_INFO, *PAUX_MODULE_BASIC_INFO;
typedef struct _AUX_MODULE_EXTENDED_INFO {
AUX_MODULE_BASIC_INFO BasicInfo;
ULONG ImageSize;
USHORT FileNameOffset;
CHAR FullPathName[AUX_KLIB_MODULE_PATH_LEN];
} AUX_MODULE_EXTENDED_INFO, *PAUX_MODULE_EXTENDED_INFO;
typedef struct _KBUGCHECK_DATA {
ULONG BugCheckDataSize;
ULONG BugCheckCode;
ULONG_PTR Parameter1;
ULONG_PTR Parameter2;
ULONG_PTR Parameter3;
ULONG_PTR Parameter4;
} KBUGCHECK_DATA, *PKBUGCHECK_DATA;
NTSTATUS
NTAPI
AuxKlibInitialize(VOID);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
AuxKlibQueryModuleInformation(
_Inout_ PULONG InformationLength,
_In_ ULONG SizePerModule,
_Out_writes_bytes_opt_(*InformationLength) PAUX_MODULE_EXTENDED_INFO ModuleInfo);
NTSTATUS
AuxKlibGetBugCheckData(
_Inout_ PKBUGCHECK_DATA BugCheckData);
PIMAGE_EXPORT_DIRECTORY
AuxKlibGetImageExportDirectory(
_In_ PVOID ImageBase);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
AuxKlibEnumerateSystemFirmwareTables (
_In_ ULONG FirmwareTableProviderSignature,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PVOID FirmwareTableBuffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
AuxKlibGetSystemFirmwareTable (
_In_ ULONG FirmwareTableProviderSignature,
_In_ ULONG FirmwareTableID,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PVOID FirmwareTableBuffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,6 @@
add_subdirectory(arbiter)
add_subdirectory(aux_klib)
add_subdirectory(chew)
add_subdirectory(copysup)
add_subdirectory(csq)

View File

@ -0,0 +1,4 @@
add_library(aux_klib aux_klib.c)
target_link_libraries(aux_klib ${PSEH_LIB})
add_importlibs(aux_klib ntoskrnl)

View File

@ -0,0 +1,228 @@
/*
* PROJECT: ReactOS SDK: Auxiliary Kernel-Mode Library
* LICENSE: BSD-2-Clause-Views (https://spdx.org/licenses/BSD-2-Clause-Views)
* PURPOSE: Main source file
* COPYRIGHT: Copyright 2019-2020 Max Korostil <mrmks04@yandex.ru>
* Copyright 2021 Victor Perevertkin <victor.perevertkin@reactos.org>
*/
#include <ntifs.h>
#include <ntintsafe.h>
#include <ndk/ntndk.h>
#include <pseh/pseh2.h>
#include <aux_klib.h>
#define TAG_AUXK 'AuxK'
typedef NTSTATUS (NTAPI *PFN_RTLQUERYMODULEINFORMATION)(PULONG, ULONG, PVOID);
PFN_RTLQUERYMODULEINFORMATION pfnRtlQueryModuleInformation;
LONG gKlibInitialized = 0;
CODE_SEG("PAGE")
NTSTATUS
NTAPI
AuxKlibInitialize(VOID)
{
RTL_OSVERSIONINFOW osVersion;
UNICODE_STRING strRtlQueryModuleInformation = RTL_CONSTANT_STRING(L"RtlQueryModuleInformation");
PAGED_CODE();
if (!gKlibInitialized)
{
RtlGetVersion(&osVersion);
if (osVersion.dwMajorVersion >= 5)
{
pfnRtlQueryModuleInformation = MmGetSystemRoutineAddress(&strRtlQueryModuleInformation);
InterlockedExchange(&gKlibInitialized, 1);
}
else
{
return STATUS_NOT_SUPPORTED;
}
}
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
AuxKlibQueryModuleInformation(
_In_ PULONG InformationLength,
_In_ ULONG SizePerModule,
_Inout_ PAUX_MODULE_EXTENDED_INFO ModuleInfo)
{
NTSTATUS status;
PAGED_CODE();
if (gKlibInitialized != 1)
{
return STATUS_UNSUCCESSFUL;
}
// if we have the function exported from the kernel, use it
if (pfnRtlQueryModuleInformation != NULL)
{
return pfnRtlQueryModuleInformation(InformationLength, SizePerModule, ModuleInfo);
}
if (SizePerModule != sizeof(AUX_MODULE_BASIC_INFO) &&
SizePerModule != sizeof(AUX_MODULE_EXTENDED_INFO))
{
return STATUS_INVALID_PARAMETER_2;
}
if ((ULONG_PTR)ModuleInfo & (TYPE_ALIGNMENT(AUX_MODULE_EXTENDED_INFO) - 1))
{
return STATUS_INVALID_PARAMETER_3;
}
// first call the function with a place for only 1 module
RTL_PROCESS_MODULES processModulesMinimal;
PRTL_PROCESS_MODULES processModules = &processModulesMinimal;
ULONG sysInfoLength = sizeof(processModulesMinimal);
ULONG resultLength;
// loop until we have a large-enough buffer for all modules
do
{
status = ZwQuerySystemInformation(SystemModuleInformation,
processModules,
sysInfoLength,
&resultLength);
if (status == STATUS_INFO_LENGTH_MISMATCH)
{
// free the old buffer if it's not the first one
if (processModules != &processModulesMinimal)
{
ExFreePoolWithTag(processModules, TAG_AUXK);
}
_SEH2_TRY
{
// allocate the new one
processModules = ExAllocatePoolWithQuotaTag(PagedPool, resultLength, TAG_AUXK);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
if (!processModules)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
sysInfoLength = resultLength;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
if (!NT_SUCCESS(status))
{
goto Cleanup;
}
ULONG modulesSize;
status = RtlULongMult(SizePerModule, processModules->NumberOfModules, &modulesSize);
if (!NT_SUCCESS(status))
{
goto Cleanup;
}
if (ModuleInfo == NULL)
{
ASSERT(status == STATUS_SUCCESS);
*InformationLength = modulesSize;
goto Cleanup;
}
if (*InformationLength < modulesSize)
{
status = STATUS_BUFFER_TOO_SMALL;
*InformationLength = modulesSize;
goto Cleanup;
}
// copy the information to the input array
for (UINT32 i = 0; i < processModules->NumberOfModules; i++)
{
ModuleInfo[i].BasicInfo.ImageBase = processModules->Modules[i].ImageBase;
if (SizePerModule == sizeof(AUX_MODULE_EXTENDED_INFO))
{
ModuleInfo[i].ImageSize = processModules->Modules[i].ImageSize;
ModuleInfo[i].FileNameOffset = processModules->Modules[i].OffsetToFileName;
RtlCopyMemory(&ModuleInfo[i].FullPathName,
processModules->Modules[i].FullPathName,
sizeof(processModules->Modules[i].FullPathName));
}
}
Cleanup:
// don't accidentally free the stack buffer
if (processModules != NULL && processModules != &processModulesMinimal)
{
ExFreePoolWithTag(processModules, TAG_AUXK);
}
return status;
}
NTSTATUS
AuxKlibGetBugCheckData(
_Inout_ PKBUGCHECK_DATA BugCheckData)
{
if (BugCheckData->BugCheckDataSize != sizeof(*BugCheckData))
{
return STATUS_INFO_LENGTH_MISMATCH;
}
BugCheckData->BugCheckCode = KiBugCheckData[0];
BugCheckData->Parameter1 = KiBugCheckData[1];
BugCheckData->Parameter2 = KiBugCheckData[2];
BugCheckData->Parameter3 = KiBugCheckData[3];
BugCheckData->Parameter4 = KiBugCheckData[4];
return STATUS_SUCCESS;
}
PIMAGE_EXPORT_DIRECTORY
AuxKlibGetImageExportDirectory(
_In_ PVOID ImageBase)
{
ULONG size;
return RtlImageDirectoryEntryToData(ImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
CODE_SEG("PAGE")
NTSTATUS
NTAPI
AuxKlibEnumerateSystemFirmwareTables (
_In_ ULONG FirmwareTableProviderSignature,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PVOID FirmwareTableBuffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength)
{
return STATUS_NOT_IMPLEMENTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
CODE_SEG("PAGE")
NTSTATUS
NTAPI
AuxKlibGetSystemFirmwareTable (
_In_ ULONG FirmwareTableProviderSignature,
_In_ ULONG FirmwareTableID,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PVOID FirmwareTableBuffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength)
{
return STATUS_NOT_IMPLEMENTED;
}

View File

@ -208,7 +208,7 @@ target_include_directories(wdf01000
shared/irphandlers/pnp/km # pnpprivkm.hpp
)
target_link_libraries(wdf01000 ntoskrnl_vista ${PSEH_LIB})
target_link_libraries(wdf01000 aux_klib ntoskrnl_vista ${PSEH_LIB})
if(GCC)
target_compile_options(wdf01000

View File

@ -25,7 +25,7 @@ Revision History:
#include "fxldr.h"
#include "fxbugcheck.h"
// #include <aux_klib.h>
#include <aux_klib.h>
//
// Disable warnings of features used by the standard headers
@ -125,104 +125,102 @@ FxpGetImageBase(
__out PULONG ImageSize
)
{
// NTSTATUS status = STATUS_UNSUCCESSFUL;
// ULONG modulesSize = 0;
// AUX_MODULE_EXTENDED_INFO* modules = NULL;
// AUX_MODULE_EXTENDED_INFO* module;
// PVOID addressInImage = NULL;
// ULONG numberOfModules;
// ULONG i;
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG modulesSize = 0;
AUX_MODULE_EXTENDED_INFO* modules = NULL;
AUX_MODULE_EXTENDED_INFO* module;
PVOID addressInImage = NULL;
ULONG numberOfModules;
ULONG i;
// //
// // Basic validation.
// //
// if (NULL == DriverObject || NULL == ImageBase || NULL == ImageSize) {
// status = STATUS_INVALID_PARAMETER;
// goto exit;
// }
//
// Basic validation.
//
if (NULL == DriverObject || NULL == ImageBase || NULL == ImageSize) {
status = STATUS_INVALID_PARAMETER;
goto exit;
}
// //
// // Get the address of a well known entry in the Image.
// //
// addressInImage = (PVOID) DriverObject->DriverStart;
// ASSERT(addressInImage != NULL);
//
// Get the address of a well known entry in the Image.
//
addressInImage = (PVOID) DriverObject->DriverStart;
ASSERT(addressInImage != NULL);
// //
// // Initialize the AUX Kernel Library.
// //
// status = AuxKlibInitialize();
// if (!NT_SUCCESS(status)) {
// goto exit;
// }
//
// Initialize the AUX Kernel Library.
//
status = AuxKlibInitialize();
if (!NT_SUCCESS(status)) {
goto exit;
}
// //
// // Get size of area needed for loaded modules.
// //
// status = AuxKlibQueryModuleInformation(&modulesSize,
// sizeof(AUX_MODULE_EXTENDED_INFO),
// NULL);
//
// Get size of area needed for loaded modules.
//
status = AuxKlibQueryModuleInformation(&modulesSize,
sizeof(AUX_MODULE_EXTENDED_INFO),
NULL);
// if (!NT_SUCCESS(status) || (0 == modulesSize)) {
// goto exit;
// }
if (!NT_SUCCESS(status) || (0 == modulesSize)) {
goto exit;
}
// numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO);
numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO);
// //
// // Allocate returned-sized memory for the modules area.
// //
// modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool,
// modulesSize,
// '30LW');
// if (NULL == modules) {
// status = STATUS_INSUFFICIENT_RESOURCES;
// goto exit;
// }
//
// Allocate returned-sized memory for the modules area.
//
modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool,
modulesSize,
'30LW');
if (NULL == modules) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
// //
// // Request the modules array be filled with module information.
// //
// status = AuxKlibQueryModuleInformation(&modulesSize,
// sizeof(AUX_MODULE_EXTENDED_INFO),
// modules);
//
// Request the modules array be filled with module information.
//
status = AuxKlibQueryModuleInformation(&modulesSize,
sizeof(AUX_MODULE_EXTENDED_INFO),
modules);
// if (!NT_SUCCESS(status)) {
// goto exit;
// }
if (!NT_SUCCESS(status)) {
goto exit;
}
// //
// // Traverse list, searching for the well known address in Image for which the
// // module's Image Base Address is in its range.
// //
// module = modules;
//
// Traverse list, searching for the well known address in Image for which the
// module's Image Base Address is in its range.
//
module = modules;
// for (i=0; i < numberOfModules; i++) {
for (i=0; i < numberOfModules; i++) {
// if (addressInImage >= module->BasicInfo.ImageBase &&
// addressInImage < WDF_PTR_ADD_OFFSET(module->BasicInfo.ImageBase,
// module->ImageSize)) {
if (addressInImage >= module->BasicInfo.ImageBase &&
addressInImage < WDF_PTR_ADD_OFFSET(module->BasicInfo.ImageBase,
module->ImageSize)) {
// *ImageBase = module->BasicInfo.ImageBase;
// *ImageSize = module->ImageSize;
*ImageBase = module->BasicInfo.ImageBase;
*ImageSize = module->ImageSize;
// status = STATUS_SUCCESS;
// goto exit;
// }
// module++;
// }
status = STATUS_SUCCESS;
goto exit;
}
module++;
}
// status = STATUS_NOT_FOUND;
status = STATUS_NOT_FOUND;
// exit:
exit:
// if (modules != NULL) {
// ExFreePool(modules);
// modules = NULL;
// }
if (modules != NULL) {
ExFreePool(modules);
modules = NULL;
}
// return status;
ROSWDFNOTIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
return status;
}
_Must_inspect_result_
@ -248,61 +246,59 @@ Return Value:
--*/
{
// PVOID codeAddr = NULL;
// BOOLEAN found = FALSE;
// KBUGCHECK_DATA bugCheckData = {0};
PVOID codeAddr = NULL;
BOOLEAN found = FALSE;
KBUGCHECK_DATA bugCheckData = {0};
// if (FxDriverGlobals->FxForceLogsInMiniDump) {
// return TRUE;
// }
if (FxDriverGlobals->FxForceLogsInMiniDump) {
return TRUE;
}
// //
// // Retrieve the bugcheck parameters.
// //
// bugCheckData.BugCheckDataSize = sizeof(KBUGCHECK_DATA);
// AuxKlibGetBugCheckData(&bugCheckData);
//
// Retrieve the bugcheck parameters.
//
bugCheckData.BugCheckDataSize = sizeof(KBUGCHECK_DATA);
AuxKlibGetBugCheckData(&bugCheckData);
// //
// // Check whether the code address that caused the bugcheck is from this wdf
// // driver.
// //
// switch (bugCheckData.BugCheckCode) {
//
// Check whether the code address that caused the bugcheck is from this wdf
// driver.
//
switch (bugCheckData.BugCheckCode) {
// case KERNEL_APC_PENDING_DURING_EXIT: // 0x20
// codeAddr = (PVOID)bugCheckData.Parameter1;
// found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
// break;
case KERNEL_APC_PENDING_DURING_EXIT: // 0x20
codeAddr = (PVOID)bugCheckData.Parameter1;
found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
break;
// case KMODE_EXCEPTION_NOT_HANDLED: // 0x1E
// case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED: // 0x7E
// case KERNEL_MODE_EXCEPTION_NOT_HANDLED: // 0x8E
// codeAddr = (PVOID)bugCheckData.Parameter2;
// found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
// break;
case KMODE_EXCEPTION_NOT_HANDLED: // 0x1E
case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED: // 0x7E
case KERNEL_MODE_EXCEPTION_NOT_HANDLED: // 0x8E
codeAddr = (PVOID)bugCheckData.Parameter2;
found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
break;
// case PAGE_FAULT_IN_NONPAGED_AREA: // 0x50
// codeAddr = (PVOID)bugCheckData.Parameter3;
// found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
// break;
case PAGE_FAULT_IN_NONPAGED_AREA: // 0x50
codeAddr = (PVOID)bugCheckData.Parameter3;
found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
break;
// case IRQL_NOT_LESS_OR_EQUAL: // 0xA
// case DRIVER_IRQL_NOT_LESS_OR_EQUAL: // 0xD1
// codeAddr = (PVOID)bugCheckData.Parameter4;
// found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
// break;
// }
case IRQL_NOT_LESS_OR_EQUAL: // 0xA
case DRIVER_IRQL_NOT_LESS_OR_EQUAL: // 0xD1
codeAddr = (PVOID)bugCheckData.Parameter4;
found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
break;
}
// //
// // If the code address was found in the wdf driver, then set the flag in the
// // driver globals to indicate that the IFR data has to be written to the
// // mini-dump.
// //
// if (found) {
// FxDriverGlobals->FxForceLogsInMiniDump = TRUE;
// }
// return found;
ROSWDFNOTIMPLEMENTED;
return FALSE;
//
// If the code address was found in the wdf driver, then set the flag in the
// driver globals to indicate that the IFR data has to be written to the
// mini-dump.
//
if (found) {
FxDriverGlobals->FxForceLogsInMiniDump = TRUE;
}
return found;
}
VOID