fix some stoopid stuff

This commit is contained in:
lhodges1 2023-10-07 16:27:22 +11:00
parent 042c614716
commit 9ef6317806
6 changed files with 81 additions and 72 deletions

View file

@ -44,12 +44,17 @@ ObPreOpCallbackRoutine(
LPCSTR protected_process_name;
PCALLBACK_CONFIGURATION configuration = NULL;
/*
* This is to prevent the condition where the thread executing this function is scheduled whilst we
* are cleaning up the callbacks on driver unload. We must hold the driver config lock to ensure the
* pool containing the callback configuration lock is not freed
*/
GetCallbackConfigStructure(&configuration);
if (!configuration)
return OB_PREOP_SUCCESS;
KeAcquireGuardedMutex(&configuration->mutex);
KeAcquireGuardedMutex(&configuration->lock);
GetProtectedProcessId(&protected_process_id);
GetProtectedProcessEProcess(&protected_process);
@ -111,7 +116,7 @@ ObPreOpCallbackRoutine(
end:
KeReleaseGuardedMutex(&configuration->mutex);
KeReleaseGuardedMutex(&configuration->lock);
return OB_PREOP_SUCCESS;
}

View file

@ -52,11 +52,6 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi
#pragma alloc_text(PAGE, TerminateProtectedProcessOnViolation)
#endif
/*
* This structure is strictly for driver related stuff
* that should only be written at driver entry.
*/
#define MAXIMUM_APC_CONTEXTS 10
typedef struct _DRIVER_CONFIG
@ -69,7 +64,7 @@ typedef struct _DRIVER_CONFIG
UNICODE_STRING registry_path;
SYSTEM_INFORMATION system_information;
PVOID apc_contexts[MAXIMUM_APC_CONTEXTS];
PCALLBACK_CONFIGURATION callback_config;
CALLBACK_CONFIGURATION callback_config;
KGUARDED_MUTEX lock;
}DRIVER_CONFIG, * PDRIVER_CONFIG;
@ -107,7 +102,6 @@ EnableCallbackRoutinesOnProcessRun()
NTSTATUS status;
KeAcquireGuardedMutex(&driver_config.lock);
KeAcquireGuardedMutex(&driver_config.callback_config->mutex);
OB_CALLBACK_REGISTRATION callback_registration = { 0 };
OB_OPERATION_REGISTRATION operation_registration = { 0 };
@ -124,7 +118,7 @@ EnableCallbackRoutinesOnProcessRun()
status = ObRegisterCallbacks(
&callback_registration,
&driver_config.callback_config->registration_handle
&driver_config.callback_config.registration_handle
);
if (!NT_SUCCESS(status))
@ -142,7 +136,6 @@ EnableCallbackRoutinesOnProcessRun()
// DEBUG_ERROR( "Failed to launch ps create notif routines with status %x", status );
end:
KeReleaseGuardedMutex(&driver_config.callback_config->mutex);
KeReleaseGuardedMutex(&driver_config.lock);
return status;
}
@ -151,41 +144,26 @@ STATIC
NTSTATUS
AllocateCallbackStructure()
{
KeAcquireGuardedMutex(&driver_config.lock);
driver_config.callback_config =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(CALLBACK_CONFIGURATION), POOL_TAG_CONFIG);
if (!driver_config.callback_config)
{
KeReleaseGuardedMutex(&driver_config.lock);
return STATUS_MEMORY_NOT_ALLOCATED;
}
/*
* This mutex ensures we don't unregister our ObRegisterCallbacks while
* the callback function is running since this might cause some funny stuff
* to happen. Better to be safe then sorry :)
*/
KeInitializeGuardedMutex(&driver_config.callback_config->mutex);
KeReleaseGuardedMutex(&driver_config.lock);
return STATUS_SUCCESS;
KeInitializeGuardedMutex(&driver_config.callback_config.lock);
}
VOID
UnregisterCallbacksOnProcessTermination()
{
KeAcquireGuardedMutex(&driver_config.lock);
KeAcquireGuardedMutex(&driver_config.callback_config->mutex);
KeAcquireGuardedMutex(&driver_config.callback_config.lock);
if (driver_config.callback_config->registration_handle)
if (driver_config.callback_config.registration_handle)
{
ObUnRegisterCallbacks(driver_config.callback_config->registration_handle);
driver_config.callback_config->registration_handle = NULL;
ObUnRegisterCallbacks(driver_config.callback_config.registration_handle);
driver_config.callback_config.registration_handle = NULL;
}
KeReleaseGuardedMutex(&driver_config.callback_config->mutex);
KeReleaseGuardedMutex(&driver_config.lock);
KeReleaseGuardedMutex(&driver_config.callback_config.lock);
}
/*
@ -201,11 +179,7 @@ STATIC
VOID
CleanupDriverCallbacksOnDriverUnload()
{
/* UnRegisterCallbacksOnProcessTermination acquires the driver lock, so must acquire it after */
UnregisterCallbacksOnProcessTermination();
KeAcquireGuardedMutex(&driver_config.lock);
ExFreePoolWithTag(driver_config.callback_config, POOL_TAG_CONFIG);
KeReleaseGuardedMutex(&driver_config.lock);
}
/*
@ -221,7 +195,7 @@ GetCallbackConfigStructure(
return;
*CallbackConfiguration = NULL;
InterlockedExchangePointer(CallbackConfiguration, driver_config.callback_config);
InterlockedExchangePointer(CallbackConfiguration, &driver_config.callback_config);
}
/*
@ -435,7 +409,6 @@ InsertApcContext(
goto end;
}
}
end:
KeReleaseGuardedMutex(&driver_config.lock);
}

View file

@ -29,7 +29,7 @@ typedef struct _SYSTEM_INFORMATION
typedef struct _CALLBACKS_CONFIGURATION
{
PVOID registration_handle;
KGUARDED_MUTEX mutex;
KGUARDED_MUTEX lock;
}CALLBACK_CONFIGURATION, * PCALLBACK_CONFIGURATION;

View file

@ -7,18 +7,29 @@
#define NMI_DELAY 200 * 10000
#define WHITELISTED_MODULE_COUNT 3
#define WHITELISTED_MODULE_COUNT 7
#define MODULE_MAX_STRING_SIZE 256
#define NTOSKRNL 0
#define CLASSPNP 1
#define WDF01000 2
/*
* The modules seen in the array below have been seen to commonly hook other drivers'
* IOCTL dispatch routines. Its possible to see this by using WinObjEx64 and checking which
* module each individual dispatch routine lies in. These modules are then addded to the list
* (in addition to either the driver itself or ntoskrnl) which is seen as a valid region
* for a drivers dispatch routine to lie within.
*/
CHAR WHITELISTED_MODULES[WHITELISTED_MODULE_COUNT][MODULE_MAX_STRING_SIZE] =
{
"ntoskrnl.exe",
"CLASSPNP.SYS",
"Wdf01000.sys",
"HIDCLASS.sys",
"storport.sys",
"dxgkrnl.sys",
"ndis.sys"
};
#define MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE 128

View file

@ -44,8 +44,12 @@ CHAR EXECUTIVE_OBJECT_POOL_TAGS[EXECUTIVE_OBJECT_COUNT][POOL_TAG_LENGTH] =
"\x4C\x69\x6E\x6B" /* Symbolic links */
};
PVOID process_buffer = NULL;
ULONG process_count = NULL;
typedef struct _PROCESS_SCAN_CONTEXT
{
ULONG process_count;
PVOID process_buffer;
}PROCESS_SCAN_CONTEXT, * PPROCESS_SCAN_CONTEXT;
PKDDEBUGGER_DATA64
GetGlobalDebuggerData()
@ -211,7 +215,7 @@ ScanPageForKernelObjectAllocation(
_In_ UINT64 PageBase,
_In_ ULONG PageSize,
_In_ ULONG ObjectIndex,
_In_ PVOID AddressBuffer
_In_ PPROCESS_SCAN_CONTEXT Context
)
{
INT length = 0;
@ -270,9 +274,9 @@ ScanPageForKernelObjectAllocation(
DEBUG_LOG("Process: %llx", (UINT64)process);
address_list = (PUINT64)AddressBuffer;
address_list = (PUINT64)Context->process_buffer;
for (INT i = 0; i < process_count; i++)
for (INT i = 0; i < Context->process_count; i++)
{
if (address_list[i] == NULL)
{
@ -326,7 +330,7 @@ VOID
EnumerateKernelLargePages(
_In_ UINT64 PageBase,
_In_ ULONG PageSize,
_In_ PVOID AddressBuffer,
_In_ PPROCESS_SCAN_CONTEXT Context,
_In_ ULONG ObjectIndex
)
{
@ -339,7 +343,7 @@ EnumerateKernelLargePages(
PageBase + (page_index * PAGE_SIZE),
PAGE_SIZE,
ObjectIndex,
AddressBuffer
Context
);
}
}
@ -369,7 +373,9 @@ EnumerateKernelLargePages(
*/
STATIC
VOID
WalkKernelPageTables(PVOID AddressBuffer)
WalkKernelPageTables(
_In_ PPROCESS_SCAN_CONTEXT Context
)
{
CR3 cr3;
PML4E pml4_base;
@ -452,7 +458,7 @@ WalkKernelPageTables(PVOID AddressBuffer)
EnumerateKernelLargePages(
base_1gb_virtual_page,
LARGE_PAGE_1GB_ENTRIES,
AddressBuffer,
Context,
INDEX_PROCESS_POOL_TAG
);
@ -494,7 +500,7 @@ WalkKernelPageTables(PVOID AddressBuffer)
EnumerateKernelLargePages(
base_2mb_virtual_page,
LARGE_PAGE_2MB_ENTRIES,
AddressBuffer,
Context,
INDEX_PROCESS_POOL_TAG
);
@ -537,7 +543,7 @@ WalkKernelPageTables(PVOID AddressBuffer)
base_virtual_page,
PAGE_BASE_SIZE,
INDEX_PROCESS_POOL_TAG,
AddressBuffer
Context
);
}
}
@ -549,27 +555,40 @@ WalkKernelPageTables(PVOID AddressBuffer)
STATIC
VOID
IncrementProcessCounter()
IncrementProcessCounter(
_In_ PEPROCESS Process,
_In_opt_ PVOID Context
)
{
process_count++;
PPROCESS_SCAN_CONTEXT context = (PPROCESS_SCAN_CONTEXT)Context;
if (!context)
return;
context->process_count++;
}
STATIC
VOID
CheckIfProcessAllocationIsInProcessList(
_In_ PEPROCESS Process
_In_ PEPROCESS Process,
_In_opt_ PVOID Context
)
{
PUINT64 allocation_address;
PPROCESS_SCAN_CONTEXT context = (PPROCESS_SCAN_CONTEXT)Context;
for (INT i = 0; i < process_count; i++)
if (!context)
return;
for (INT i = 0; i < context->process_count; i++)
{
allocation_address = (PUINT64)process_buffer;
allocation_address = (PUINT64)context->process_buffer;
if ((UINT64)Process >= allocation_address[i] - PROCESS_OBJECT_ALLOCATION_MARGIN &&
(UINT64)Process <= allocation_address[i] + PROCESS_OBJECT_ALLOCATION_MARGIN)
{
RtlZeroMemory((UINT64)process_buffer + i * sizeof(UINT64), sizeof(UINT64));
RtlZeroMemory((UINT64)context->process_buffer + i * sizeof(UINT64), sizeof(UINT64));
}
}
}
@ -580,34 +599,36 @@ FindUnlinkedProcesses(
)
{
PUINT64 allocation_address;
PROCESS_SCAN_CONTEXT context = { 0 };
PINVALID_PROCESS_ALLOCATION_REPORT report_buffer = NULL;
EnumerateProcessListWithCallbackFunction(
IncrementProcessCounter,
NULL
&context
);
if (process_count == NULL)
if (context.process_count == NULL)
{
DEBUG_ERROR("Faield to get process count ");
DEBUG_ERROR("Failed to get process count");
return STATUS_ABANDONED;
}
process_buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, process_count * 2 * sizeof(UINT64), PROCESS_ADDRESS_LIST_TAG);
context.process_buffer =
ExAllocatePool2(POOL_FLAG_NON_PAGED, context.process_count * 2 * sizeof(UINT64), PROCESS_ADDRESS_LIST_TAG);
if (!process_buffer)
if (!context.process_buffer)
return STATUS_ABANDONED;
WalkKernelPageTables(process_buffer);
WalkKernelPageTables(&context);
EnumerateProcessListWithCallbackFunction(
CheckIfProcessAllocationIsInProcessList,
NULL
);
allocation_address = (PUINT64)process_buffer;
allocation_address = (PUINT64)context.process_buffer;
for (INT i = 0; i < process_count; i++)
for (INT i = 0; i < context.process_count; i++)
{
if (allocation_address[i] == NULL)
continue;
@ -619,7 +640,8 @@ FindUnlinkedProcesses(
*/
DEBUG_ERROR("INVALID POOL proc OMGGG");
report_buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(INVALID_PROCESS_ALLOCATION_REPORT), REPORT_POOL_TAG);
report_buffer =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(INVALID_PROCESS_ALLOCATION_REPORT), REPORT_POOL_TAG);
if (!report_buffer)
goto end;
@ -637,12 +659,8 @@ FindUnlinkedProcesses(
end:
if (process_buffer)
ExFreePoolWithTag(process_buffer, PROCESS_ADDRESS_LIST_TAG);
/* todo: make use of the new context variable in the enum proc func */
process_count = NULL;
process_buffer = NULL;
if (context.process_buffer)
ExFreePoolWithTag(context.process_buffer, PROCESS_ADDRESS_LIST_TAG);
return STATUS_SUCCESS;
}

View file

@ -26,4 +26,6 @@ GetPsActiveProcessHead(
PKDDEBUGGER_DATA64
GetGlobalDebuggerData();
#endif