mirror-ac/driver/driver.c

1239 lines
29 KiB
C
Raw Normal View History

2023-08-17 10:45:50 +02:00
#include "driver.h"
#include "common.h"
#include "ioctl.h"
2023-08-20 16:12:04 +02:00
#include "callbacks.h"
2023-08-21 14:40:40 +02:00
#include "hv.h"
2023-08-28 11:17:38 +02:00
#include "pool.h"
2023-08-29 19:36:58 +02:00
#include "thread.h"
2023-08-31 12:33:26 +02:00
#include "modules.h"
2023-08-22 19:32:25 +02:00
#include "integrity.h"
2023-10-08 06:24:54 +02:00
STATIC
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject);
2023-10-10 15:52:42 +02:00
_Function_class_(DRIVER_INITIALIZE)
_IRQL_requires_same_
2023-10-08 06:24:54 +02:00
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath);
STATIC
NTSTATUS RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext);
2023-10-06 13:08:30 +02:00
2023-10-09 18:27:04 +02:00
STATIC
VOID
DrvUnloadUnregisterObCallbacks();
STATIC
VOID
DrvUnloadFreeConfigStrings();
STATIC
VOID
DrvUnloadFreeSymbolicLink();
STATIC
VOID
DrvUnloadFreeGlobalReportQueue();
STATIC
VOID
DrvUnloadFreeThreadList();
2023-10-10 19:49:17 +02:00
STATIC
VOID
DrvUnloadFreeProcessList();
2023-10-09 18:27:04 +02:00
STATIC
NTSTATUS
DrvLoadEnableNotifyRoutines();
STATIC
NTSTATUS
DrvLoadInitialiseObCbConfig();
STATIC
VOID
DrvLoadInitialiseReportQueue(
2023-10-09 20:19:51 +02:00
_Out_ PBOOLEAN Flag
2023-10-09 18:27:04 +02:00
);
STATIC
VOID
DrvLoadInitialiseProcessConfig();
STATIC
NTSTATUS
DrvLoadInitialiseDriverConfig(
_In_ PUNICODE_STRING RegistryPath
);
2023-10-06 13:08:30 +02:00
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, GetProtectedProcessEProcess)
#pragma alloc_text(PAGE, GetProtectedProcessId)
#pragma alloc_text(PAGE, GetDriverName)
#pragma alloc_text(PAGE, GetDriverPath)
#pragma alloc_text(PAGE, GetDriverRegistryPath)
#pragma alloc_text(PAGE, GetDriverDeviceName)
#pragma alloc_text(PAGE, GetDriverSymbolicLink)
#pragma alloc_text(PAGE, GetDriverConfigSystemInformation)
#pragma alloc_text(PAGE, RegistryPathQueryCallbackRoutine)
#pragma alloc_text(PAGE, TerminateProtectedProcessOnViolation)
2023-10-09 18:27:04 +02:00
#pragma alloc_text(PAGE, ProcCloseDisableObCallbacks)
#pragma alloc_text(PAGE, ProcCloseClearProcessConfiguration)
#pragma alloc_text(PAGE, ProcLoadEnableObCallbacks)
#pragma alloc_text(PAGE, ProcLoadInitialiseProcessConfig)
#pragma alloc_text(PAGE, DrvUnloadUnregisterObCallbacks)
#pragma alloc_text(PAGE, DrvUnloadFreeConfigStrings)
#pragma alloc_text(PAGE, DrvUnloadFreeSymbolicLink)
#pragma alloc_text(PAGE, DrvUnloadFreeGlobalReportQueue)
#pragma alloc_text(PAGE, DrvUnloadFreeThreadList)
#pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
2023-10-10 19:49:17 +02:00
#pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
2023-10-09 18:27:04 +02:00
#pragma alloc_text(PAGE, DrvLoadInitialiseObCbConfig)
#pragma alloc_text(PAGE, DrvLoadInitialiseReportQueue)
#pragma alloc_text(PAGE, DrvLoadInitialiseProcessConfig)
#pragma alloc_text(PAGE, DrvLoadInitialiseDriverConfig)
2023-10-10 15:52:42 +02:00
#pragma alloc_text(PAGE, ReadProcessInitialisedConfigFlag)
2023-10-06 13:08:30 +02:00
#endif
2023-09-27 15:10:12 +02:00
#define MAXIMUM_APC_CONTEXTS 10
typedef struct _DRIVER_CONFIG
{
UNICODE_STRING unicode_driver_name;
ANSI_STRING ansi_driver_name;
UNICODE_STRING device_name;
UNICODE_STRING device_symbolic_link;
UNICODE_STRING driver_path;
UNICODE_STRING registry_path;
SYSTEM_INFORMATION system_information;
2023-10-05 08:27:17 +02:00
PVOID apc_contexts[MAXIMUM_APC_CONTEXTS];
2023-10-09 09:34:30 +02:00
volatile BOOLEAN unload_in_progress;
2023-09-27 15:10:12 +02:00
KGUARDED_MUTEX lock;
}DRIVER_CONFIG, * PDRIVER_CONFIG;
/*
* This structure can change at anytime based on whether
* the target process to protect is open / closed / changes etc.
*/
typedef struct _PROCESS_CONFIG
{
BOOLEAN initialised;
LONG um_handle;
LONG km_handle;
2023-10-09 18:27:04 +02:00
PEPROCESS process;
OB_CALLBACKS_CONFIG ob_cb_config;
2023-09-27 15:10:12 +02:00
KGUARDED_MUTEX lock;
}PROCESS_CONFIG, * PPROCESS_CONFIG;
2023-09-01 14:30:32 +02:00
DRIVER_CONFIG driver_config = { 0 };
PROCESS_CONFIG process_config = { 0 };
2023-08-20 17:04:53 +02:00
2023-10-06 10:30:14 +02:00
#define POOL_TAG_CONFIG 'conf'
2023-10-06 13:08:30 +02:00
/*
2023-10-09 18:27:04 +02:00
* Regular routines
2023-10-06 13:08:30 +02:00
*/
2023-10-06 10:30:14 +02:00
2023-10-09 18:27:04 +02:00
VOID
TerminateProtectedProcessOnViolation()
2023-10-08 16:07:49 +02:00
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-08 16:07:49 +02:00
NTSTATUS status;
2023-10-09 18:27:04 +02:00
ULONG process_id = 0;
2023-10-08 16:07:49 +02:00
2023-10-09 18:27:04 +02:00
GetProtectedProcessId(&process_id);
2023-10-08 16:07:49 +02:00
2023-10-09 18:27:04 +02:00
if (!process_id)
2023-10-08 16:07:49 +02:00
{
2023-10-09 18:27:04 +02:00
DEBUG_ERROR("Failed to terminate process as process id is null");
return;
2023-10-08 16:07:49 +02:00
}
2023-10-06 10:30:14 +02:00
/*
2023-10-09 18:27:04 +02:00
* Make sure we pass a km handle to ZwTerminateProcess and NOT a usermode handle.
2023-10-06 10:30:14 +02:00
*/
2023-10-09 18:27:04 +02:00
status = ZwTerminateProcess(process_id, STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION);
2023-10-06 10:30:14 +02:00
2023-10-09 18:27:04 +02:00
if (!NT_SUCCESS(status))
2023-10-06 10:30:14 +02:00
{
2023-10-09 18:27:04 +02:00
/*
* We don't want to clear the process config if ZwTerminateProcess fails
* so we can try again.
*/
DEBUG_ERROR("ZwTerminateProcess failed with status %x", status);
return;
2023-10-06 10:30:14 +02:00
}
2023-10-09 18:27:04 +02:00
/* this wont be needed when procloadstuff is implemented */
ProcCloseClearProcessConfiguration();
2023-10-06 10:30:14 +02:00
}
2023-10-06 13:08:30 +02:00
STATIC
2023-10-09 18:27:04 +02:00
NTSTATUS
RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
2023-10-06 10:30:14 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
UNICODE_STRING value_name;
UNICODE_STRING image_path = RTL_CONSTANT_STRING(L"ImagePath");
UNICODE_STRING display_name = RTL_CONSTANT_STRING(L"DisplayName");
UNICODE_STRING value;
PVOID temp_buffer;
2023-10-06 13:08:30 +02:00
2023-10-09 18:27:04 +02:00
RtlInitUnicodeString(&value_name, ValueName);
2023-10-06 10:30:14 +02:00
2023-10-09 18:27:04 +02:00
if (RtlCompareUnicodeString(&value_name, &image_path, FALSE) == FALSE)
{
temp_buffer = ExAllocatePool2(POOL_FLAG_PAGED, ValueLength, POOL_TAG_STRINGS);
2023-09-26 15:48:21 +02:00
2023-10-09 18:27:04 +02:00
if (!temp_buffer)
return STATUS_MEMORY_NOT_ALLOCATED;
2023-09-29 05:56:44 +02:00
2023-10-09 18:27:04 +02:00
RtlCopyMemory(
temp_buffer,
ValueData,
ValueLength
);
2023-09-25 17:41:38 +02:00
2023-10-09 18:27:04 +02:00
driver_config.driver_path.Buffer = (PWCH)temp_buffer;
driver_config.driver_path.Length = ValueLength;
driver_config.driver_path.MaximumLength = ValueLength + 1;
}
if (RtlCompareUnicodeString(&value_name, &display_name, FALSE) == FALSE)
2023-09-25 17:41:38 +02:00
{
2023-10-09 18:27:04 +02:00
temp_buffer = ExAllocatePool2(POOL_FLAG_PAGED, ValueLength, POOL_TAG_STRINGS);
2023-09-26 12:00:45 +02:00
2023-10-09 18:27:04 +02:00
if (!temp_buffer)
return STATUS_MEMORY_NOT_ALLOCATED;
2023-09-29 05:56:44 +02:00
2023-10-09 18:27:04 +02:00
RtlCopyMemory(
temp_buffer,
ValueData,
ValueLength
);
2023-09-29 05:56:44 +02:00
2023-10-09 18:27:04 +02:00
driver_config.unicode_driver_name.Buffer = (PWCH)temp_buffer;
driver_config.unicode_driver_name.Length = ValueLength;
driver_config.unicode_driver_name.MaximumLength = ValueLength + 1;
2023-09-25 17:41:38 +02:00
}
2023-10-09 18:27:04 +02:00
return STATUS_SUCCESS;
2023-09-25 17:41:38 +02:00
}
2023-10-09 18:27:04 +02:00
/*
*
*
* APC related routines
*
*/
2023-09-26 15:32:06 +02:00
/*
2023-09-27 06:22:14 +02:00
* No need to hold the lock here as the thread freeing the APCs will
2023-09-26 15:32:06 +02:00
* already hold the configuration lock. We also dont want to release and
* reclaim the lock before calling this function since we need to ensure
2023-09-26 15:48:21 +02:00
* we hold the lock during the entire decrement and free process.
2023-09-26 15:32:06 +02:00
*/
STATIC
2023-09-26 12:00:45 +02:00
BOOLEAN
FreeApcContextStructure(
_Inout_ PAPC_CONTEXT_HEADER Context
2023-09-25 17:41:38 +02:00
)
{
2023-09-26 12:00:45 +02:00
BOOLEAN result = FALSE;
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
DEBUG_LOG("All APCs executed, freeing context structure");
2023-09-25 17:41:38 +02:00
2023-10-05 08:27:17 +02:00
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
2023-09-25 17:41:38 +02:00
{
2023-09-26 12:00:45 +02:00
PUINT64 entry = driver_config.apc_contexts;
2023-09-25 17:41:38 +02:00
2023-10-05 08:27:17 +02:00
if (entry[index] == Context)
2023-09-25 17:41:38 +02:00
{
2023-10-05 08:27:17 +02:00
if (Context->count != 0)
2023-09-26 12:00:45 +02:00
goto unlock;
2023-10-05 08:27:17 +02:00
ExFreePoolWithTag(Context, POOL_TAG_APC);
entry[index] = NULL;
2023-09-26 12:00:45 +02:00
result = TRUE;
goto unlock;
2023-09-25 17:41:38 +02:00
}
}
2023-09-26 12:00:45 +02:00
unlock:
return result;
2023-09-25 17:41:38 +02:00
}
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-09-26 15:32:06 +02:00
VOID
IncrementApcCount(
_In_ LONG ContextId
)
{
PAPC_CONTEXT_HEADER header = NULL;
2023-10-05 08:27:17 +02:00
GetApcContext(&header, ContextId);
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
if (!header)
2023-09-26 15:32:06 +02:00
return;
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-09-26 15:32:06 +02:00
header->count += 1;
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-26 15:32:06 +02:00
}
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-09-26 15:32:06 +02:00
VOID
FreeApcAndDecrementApcCount(
2023-10-07 17:37:47 +02:00
_Inout_ PRKAPC Apc,
2023-09-26 15:32:06 +02:00
_In_ LONG ContextId
)
{
PAPC_CONTEXT_HEADER context = NULL;
2023-10-09 09:34:30 +02:00
2023-10-05 08:27:17 +02:00
ExFreePoolWithTag(Apc, POOL_TAG_APC);
GetApcContext(&context, ContextId);
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
if (!context)
2023-09-26 15:32:06 +02:00
goto end;
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-09-26 15:32:06 +02:00
context->count -= 1;
2023-09-27 06:22:14 +02:00
end:
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-27 06:22:14 +02:00
}
/*
2023-10-05 08:27:17 +02:00
* The reason we use a query model rather then checking the count of queued APCs
* after each APC free and decrement is that the lock will be recursively acquired by
2023-09-27 07:27:06 +02:00
* freeing threads (i.e executing APCs) rather then APC allocation threads. The reason for this
2023-10-05 08:27:17 +02:00
* being that freeing threads are executing at a higher IRQL then the APC allocation
2023-09-27 07:16:36 +02:00
* thread, hence they are granted higher priority by the scheduler when determining
2023-09-27 07:27:06 +02:00
* which thread will accquire the lock next:
2023-10-05 08:27:17 +02:00
*
2023-09-27 07:27:06 +02:00
* [+] Freeing thread -> ApcKernelRoutine IRQL: 1 (APC_LEVEL)
* [+] Allocation thread -> ValidateThreadViaKernelApcCallback IRQL: 0 (PASSIVE_LEVEL)
2023-09-27 07:16:36 +02:00
*
2023-10-05 08:27:17 +02:00
* As a result, once an APC is executed and reaches the freeing stage, it will acquire the
2023-09-27 07:27:06 +02:00
* lock and decrement it. Then, if atleast 1 APC execution thread is waiting on the lock,
2023-10-05 08:27:17 +02:00
* it will be prioritised due to its higher IRQL and the cycle will continue. Eventually,
2023-09-27 07:27:06 +02:00
* the count will reach 0 due to recursive acquisition by the executing APC threads and then
* the function will free the APC context structure. This will then cause a bug check the next
* time a thread accesses the context structure and hence not good :c.
2023-10-05 08:27:17 +02:00
*
2023-09-27 07:16:36 +02:00
* So to combat this, we add in a flag specifying whether or not an allocation of APCs is
* in progress, and even if the count is 0 we will not free the context structure until
* the count is 0 and allocation_in_progress is 0. We can then call this function alongside
* other query callbacks via IOCTL to constantly monitor the status of open APC contexts.
2023-09-27 06:22:14 +02:00
*/
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-09-27 06:22:14 +02:00
NTSTATUS
QueryActiveApcContextsForCompletion()
{
2023-10-05 08:27:17 +02:00
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
2023-09-26 15:32:06 +02:00
{
2023-09-27 06:22:14 +02:00
PAPC_CONTEXT_HEADER entry = NULL;
2023-10-05 08:27:17 +02:00
GetApcContextByIndex(&entry, index);
2023-09-26 15:32:06 +02:00
2023-09-27 06:22:14 +02:00
/* acquire mutex after we get the context to prevent thread deadlock */
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
if (entry == NULL)
2023-09-27 06:22:14 +02:00
{
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-27 06:22:14 +02:00
continue;
}
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
DEBUG_LOG("APC Context Id: %lx", entry->context_id);
DEBUG_LOG("Active APC Count: %i", entry->count);
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
if (entry->count > 0 || entry->allocation_in_progress == TRUE)
2023-09-27 06:22:14 +02:00
{
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-27 06:22:14 +02:00
continue;
}
2023-09-26 15:32:06 +02:00
2023-10-05 08:27:17 +02:00
switch (entry->context_id)
2023-09-27 06:22:14 +02:00
{
case APC_CONTEXT_ID_STACKWALK:
2023-10-05 08:27:17 +02:00
FreeApcStackwalkApcContextInformation(entry);
FreeApcContextStructure(entry);
2023-09-27 06:22:14 +02:00
break;
}
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-26 15:32:06 +02:00
2023-09-27 06:22:14 +02:00
}
return STATUS_SUCCESS;
}
2023-09-26 15:32:06 +02:00
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 09:34:30 +02:00
NTSTATUS
2023-09-26 12:00:45 +02:00
InsertApcContext(
2023-09-25 17:41:38 +02:00
_In_ PVOID Context
)
{
2023-10-09 09:34:30 +02:00
NTSTATUS status = STATUS_SUCCESS;
2023-09-25 17:41:38 +02:00
2023-10-09 18:27:04 +02:00
/*
2023-10-09 09:34:30 +02:00
* prevents the race condition where the driver is unloaded whilst a new apc operation
* is attempted to start, ensuring that even if it holds
*/
if (InterlockedExchange(&driver_config.unload_in_progress, driver_config.unload_in_progress))
{
status = STATUS_ABANDONED;
goto end;
}
2023-10-11 18:05:29 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
PAPC_CONTEXT_HEADER header = Context;
2023-10-05 08:27:17 +02:00
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
2023-09-26 12:00:45 +02:00
{
PUINT64 entry = driver_config.apc_contexts;
2023-09-25 17:41:38 +02:00
2023-10-05 08:27:17 +02:00
if (entry[index] == NULL)
2023-09-26 12:00:45 +02:00
{
2023-10-05 08:27:17 +02:00
entry[index] = Context;
2023-09-25 17:41:38 +02:00
goto end;
2023-09-26 12:00:45 +02:00
}
2023-09-25 17:41:38 +02:00
}
end:
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-10-09 09:34:30 +02:00
return status;
2023-09-25 17:41:38 +02:00
}
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetApcContext(
2023-09-25 17:41:38 +02:00
_Inout_ PVOID* Context,
_In_ LONG ContextIdentifier
)
{
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-09-25 17:41:38 +02:00
2023-10-05 08:27:17 +02:00
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
2023-09-25 17:41:38 +02:00
{
2023-10-05 08:27:17 +02:00
PAPC_CONTEXT_HEADER header = driver_config.apc_contexts[index];
2023-09-26 12:00:45 +02:00
2023-10-05 08:27:17 +02:00
if (header == NULL)
2023-09-26 12:00:45 +02:00
continue;
2023-09-25 17:41:38 +02:00
2023-10-05 08:27:17 +02:00
if (header->context_id == ContextIdentifier)
2023-09-25 17:41:38 +02:00
{
*Context = header;
2023-09-26 12:00:45 +02:00
goto unlock;
2023-09-25 17:41:38 +02:00
}
}
2023-09-26 12:00:45 +02:00
unlock:
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-26 12:00:45 +02:00
}
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-09-26 12:00:45 +02:00
VOID
GetApcContextByIndex(
_Inout_ PVOID* Context,
_In_ INT Index
)
{
2023-10-06 13:08:30 +02:00
if (!Context)
return;
*Context = NULL;
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-10-08 06:24:54 +02:00
*Context = driver_config.apc_contexts[Index];
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-25 17:41:38 +02:00
}
2023-10-09 18:27:04 +02:00
/*
*
* Config getters
*
*/
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-10-09 18:27:04 +02:00
GetCallbackConfigStructure(
_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration
2023-08-24 17:10:40 +02:00
)
{
2023-10-09 18:27:04 +02:00
if (!CallbackConfiguration)
2023-09-11 11:23:29 +02:00
return;
2023-10-09 18:27:04 +02:00
*CallbackConfiguration = NULL;
2023-10-05 08:27:17 +02:00
KeAcquireGuardedMutex(&process_config.lock);
2023-10-09 18:27:04 +02:00
*CallbackConfiguration = &process_config.ob_cb_config;
2023-10-05 08:27:17 +02:00
KeReleaseGuardedMutex(&process_config.lock);
2023-09-01 14:30:32 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverName(
2023-09-11 11:23:29 +02:00
_Out_ LPCSTR* DriverName
2023-08-20 16:12:04 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
if (DriverName == NULL)
2023-09-11 11:23:29 +02:00
return;
2023-10-06 13:08:30 +02:00
*DriverName = NULL;
2023-10-08 06:24:54 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
*DriverName = driver_config.ansi_driver_name.Buffer;
KeReleaseGuardedMutex(&driver_config.lock);
2023-08-20 16:12:04 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverPath(
2023-09-11 11:23:29 +02:00
_Out_ PUNICODE_STRING DriverPath
2023-08-20 16:12:04 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DriverPath, sizeof(UNICODE_STRING));
RtlInitUnicodeString(DriverPath, driver_config.driver_path.Buffer);
KeReleaseGuardedMutex(&driver_config.lock);
2023-08-20 16:12:04 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverRegistryPath(
2023-09-11 11:23:29 +02:00
_Out_ PUNICODE_STRING RegistryPath
2023-09-01 14:30:32 +02:00
)
2023-08-20 16:12:04 +02:00
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(RegistryPath, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(RegistryPath, &driver_config.registry_path);
KeReleaseGuardedMutex(&driver_config.lock);
2023-08-20 16:12:04 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverDeviceName(
2023-09-11 11:23:29 +02:00
_Out_ PUNICODE_STRING DeviceName
2023-09-01 14:30:32 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceName, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceName, &driver_config.device_name);
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-01 14:30:32 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverSymbolicLink(
2023-09-11 11:23:29 +02:00
_Out_ PUNICODE_STRING DeviceSymbolicLink
2023-09-01 14:30:32 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceSymbolicLink, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceSymbolicLink, &driver_config.device_symbolic_link);
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-01 14:30:32 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-05 08:27:17 +02:00
VOID
2023-09-26 12:00:45 +02:00
GetDriverConfigSystemInformation(
2023-09-11 11:23:29 +02:00
_Out_ PSYSTEM_INFORMATION* SystemInformation
2023-09-07 19:49:36 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
if (SystemInformation == NULL)
2023-09-11 11:23:29 +02:00
return;
2023-10-06 13:08:30 +02:00
*SystemInformation = NULL;
2023-10-08 06:24:54 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
*SystemInformation = &driver_config.system_information;
KeReleaseGuardedMutex(&driver_config.lock);
2023-09-07 19:49:36 +02:00
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
VOID
ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
2023-09-01 18:45:06 +02:00
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
if (Flag == NULL)
return;
2023-09-03 19:33:27 +02:00
2023-10-09 18:27:04 +02:00
KeAcquireGuardedMutex(&process_config.lock);
*Flag = process_config.initialised;
KeReleaseGuardedMutex(&process_config.lock);
}
2023-09-01 18:45:06 +02:00
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
VOID
GetProtectedProcessEProcess(
_Out_ PEPROCESS* Process
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
if (Process == NULL)
return;
*Process = NULL;
KeAcquireGuardedMutex(&process_config.lock);
*Process = process_config.process;
KeReleaseGuardedMutex(&process_config.lock);
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
VOID
GetProtectedProcessId(
_Out_ PLONG ProcessId
)
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
KeAcquireGuardedMutex(&process_config.lock);
RtlZeroMemory(ProcessId, sizeof(LONG));
*ProcessId = process_config.km_handle;
KeReleaseGuardedMutex(&process_config.lock);
}
/*
*
* Routines run at process close
*
*/
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
VOID
ProcCloseDisableObCallbacks()
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
KeAcquireGuardedMutex(&process_config.ob_cb_config.lock);
if (process_config.ob_cb_config.registration_handle)
2023-09-01 18:45:06 +02:00
{
2023-10-09 18:27:04 +02:00
ObUnRegisterCallbacks(process_config.ob_cb_config.registration_handle);
process_config.ob_cb_config.registration_handle = NULL;
}
2023-10-09 18:27:04 +02:00
KeReleaseGuardedMutex(&process_config.ob_cb_config.lock);
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
VOID
ProcCloseClearProcessConfiguration()
{
2023-10-09 20:19:51 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
DEBUG_LOG("Process closed, clearing driver process_configuration");
KeAcquireGuardedMutex(&process_config.lock);
process_config.km_handle = NULL;
process_config.um_handle = NULL;
process_config.process = NULL;
process_config.initialised = FALSE;
KeReleaseGuardedMutex(&process_config.lock);
}
2023-10-09 18:27:04 +02:00
/*
*
* Routines run at process load
*
*/
/*
* The CALLBACKS_CONFIGURATION structure was being paged out, aswell as enabling a race condition
* to occur by being encapsulated in the callbacks.c file, so to solve both these problems I have moved
* them here. This way, we can make use of both locks (which is very ugly and I am pretty sure means
* I have made a mistake implementation wise but alas) ensuring we get rid of any race conditions
* aswell as the sturcture being paged out as we allocate in a non-paged pool meaning theres no
* chance our mutex will cause an IRQL bug check due to being paged out during acquisition.
*/
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
NTSTATUS
ProcLoadEnableObCallbacks()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
NTSTATUS status;
KeAcquireGuardedMutex(&process_config.lock);
OB_CALLBACK_REGISTRATION callback_registration = { 0 };
OB_OPERATION_REGISTRATION operation_registration = { 0 };
PCREATE_PROCESS_NOTIFY_ROUTINE_EX notify_routine = { 0 };
operation_registration.ObjectType = PsProcessType;
operation_registration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
operation_registration.PreOperation = ObPreOpCallbackRoutine;
operation_registration.PostOperation = ObPostOpCallbackRoutine;
callback_registration.Version = OB_FLT_REGISTRATION_VERSION;
callback_registration.OperationRegistration = &operation_registration;
callback_registration.OperationRegistrationCount = 1;
callback_registration.RegistrationContext = NULL;
status = ObRegisterCallbacks(
&callback_registration,
&process_config.ob_cb_config.registration_handle
);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to launch obregisters with status %x", status);
goto end;
2023-09-01 18:45:06 +02:00
}
2023-10-09 18:27:04 +02:00
//status = PsSetCreateProcessNotifyRoutine(
// ProcessCreateNotifyRoutine,
// FALSE
//);
//if ( !NT_SUCCESS( status ) )
// DEBUG_ERROR( "Failed to launch ps create notif routines with status %x", status );
end:
KeReleaseGuardedMutex(&process_config.lock);
return status;
}
2023-10-10 15:52:42 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
NTSTATUS
ProcLoadInitialiseProcessConfig(
_In_ PIRP Irp
)
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
NTSTATUS status;
PEPROCESS eprocess;
PDRIVER_INITIATION_INFORMATION information;
information = (PDRIVER_INITIATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
status = PsLookupProcessByProcessId(information->protected_process_id, &eprocess);
if (!NT_SUCCESS(status))
return status;
KeAcquireGuardedMutex(&process_config.lock);
process_config.process = eprocess;
process_config.um_handle = information->protected_process_id;
process_config.km_handle = PsGetProcessId(eprocess);
process_config.initialised = TRUE;
KeReleaseGuardedMutex(&process_config.lock);
return status;
}
/*
*
* Routines run at driver unload
*
*/
/*
* The question is, What happens if we attempt to register our callbacks after we
* unregister them but before we free the pool? Hm.. No Good.
*
* Okay to solve this well acquire the driver lock aswell, we could also just
* store the structure in the .data section but i ceebs atm.
*
* This definitely doesn't seem optimal, but it works ...
*/
STATIC
VOID
DrvUnloadUnregisterObCallbacks()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
ProcCloseDisableObCallbacks();
}
/*
* The driver config structure holds an array of pointers to APC context structures. These
* APC context structures are unique to each APC operation that this driver will perform. For
* example, a single context will manage all APCs that are used to stackwalk, whilst another
* context will be used to manage all APCs used to query a threads memory for example.
*
* Due to the nature of APCs, its important to keep a total or count of the number of APCs we
* have allocated and queued to threads. This information is stored in the APC_CONTEXT_HEADER which
* all APC context structures will contain as the first entry in their structure. It holds the ContextId
* which is a unique identifier for the type of APC operation it is managing aswell as the number of
* currently queued APCs.
*
* When an APC is allocated a queued, we increment this count. When an APC is completed and freed, we
* decrement this counter and free the APC itself. If all APCs have been freed and the counter is 0,the
* following objects will be freed:
*
* 1. Any additional allocations used by the APC stored in the context structure
* 2. The APC context structure for the given APC operation
* 3. The APC context entry in driver_config->apc_contexts will be zero'd.
*
* It's important to remember that the driver can unload when pending APC's have not been freed due to the
* limitations windows places on APCs, however I am in the process of finding a solution for this.
*/
2023-10-11 08:35:20 +02:00
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
2023-10-09 18:27:04 +02:00
STATIC
BOOLEAN
DrvUnloadFreeAllApcContextStructures()
{
BOOLEAN flag = TRUE;
2023-10-11 08:35:20 +02:00
KeAcquireGuardedMutex(&driver_config.lock);
2023-10-09 18:27:04 +02:00
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
2023-09-01 18:45:06 +02:00
{
2023-10-09 18:27:04 +02:00
PUINT64 entry = driver_config.apc_contexts;
2023-09-01 18:45:06 +02:00
2023-10-09 18:27:04 +02:00
if (entry[index] != NULL)
{
PAPC_CONTEXT_HEADER context = entry[index];
2023-09-01 18:45:06 +02:00
2023-10-09 18:27:04 +02:00
if (context->count > 0)
{
flag = FALSE;
goto unlock;
}
2023-10-09 18:27:04 +02:00
ExFreePoolWithTag(entry, POOL_TAG_APC);
}
2023-09-01 18:45:06 +02:00
}
2023-10-09 18:27:04 +02:00
unlock:
2023-10-11 08:35:20 +02:00
KeReleaseGuardedMutex(&driver_config.lock);
2023-10-09 18:27:04 +02:00
return flag;
2023-09-01 18:45:06 +02:00
}
2023-09-26 12:00:45 +02:00
STATIC
2023-10-05 08:27:17 +02:00
VOID
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings()
2023-09-01 18:45:06 +02:00
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-05 08:27:17 +02:00
if (driver_config.unicode_driver_name.Buffer)
ExFreePoolWithTag(driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS);
2023-09-01 18:45:06 +02:00
2023-10-05 08:27:17 +02:00
if (driver_config.driver_path.Buffer)
ExFreePoolWithTag(driver_config.driver_path.Buffer, POOL_TAG_STRINGS);
2023-09-01 18:45:06 +02:00
2023-10-05 08:27:17 +02:00
if (driver_config.ansi_driver_name.Buffer)
RtlFreeAnsiString(&driver_config.ansi_driver_name);
2023-09-01 18:45:06 +02:00
}
2023-10-09 18:27:04 +02:00
STATIC
VOID
DrvUnloadFreeSymbolicLink()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
}
STATIC
VOID
DrvUnloadFreeGlobalReportQueue()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
FreeGlobalReportQueueObjects();
}
STATIC
VOID
DrvUnloadFreeThreadList()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
CleanupThreadListOnDriverUnload();
}
2023-10-10 19:49:17 +02:00
STATIC
VOID
DrvUnloadFreeProcessList()
{
PAGED_CODE();
CleanupProcessListOnDriverUnload();
}
2023-10-09 18:27:04 +02:00
STATIC
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
{
InterlockedExchange(&driver_config.unload_in_progress, TRUE);
DEBUG_LOG("Unloading driver...");
2023-10-11 18:05:29 +02:00
/*
* This blocks the thread dispatching the unload action, which I don't think is ideal.
* This is the issue with using
*/
2023-10-09 18:27:04 +02:00
while (DrvUnloadFreeAllApcContextStructures() == FALSE)
YieldProcessor();
DrvUnloadUnregisterObCallbacks();
DrvUnloadFreeThreadList();
2023-10-10 19:49:17 +02:00
DrvUnloadFreeProcessList();
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
DrvUnloadFreeGlobalReportQueue();
DrvUnloadFreeSymbolicLink();
IoDeleteDevice(DriverObject->DeviceObject);
DEBUG_LOG("Driver unloaded");
}
/*
*
* Routines that are run at driver load
*
*/
2023-09-26 12:00:45 +02:00
STATIC
2023-10-05 08:27:17 +02:00
NTSTATUS
2023-10-09 18:27:04 +02:00
DrvLoadEnableNotifyRoutines()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
NTSTATUS status;
status = InitialiseThreadList();
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("InitialiseThreadList failed with status %x", status);
return status;
}
2023-10-10 19:49:17 +02:00
status = InitialiseProcessList();
if (!NT_SUCCESS(status))
{
DrvUnloadFreeThreadList();
DEBUG_ERROR("InitialiseProcessList failed with status %x", status);
return status;
}
2023-10-09 18:27:04 +02:00
status = PsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
2023-10-11 08:35:20 +02:00
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("PsSetCreateThreadNotifyRoutine failed with status %x", status);
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
return status;
}
status = PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, FALSE);
2023-10-09 18:27:04 +02:00
if (!NT_SUCCESS(status))
2023-10-10 19:49:17 +02:00
{
2023-10-09 18:27:04 +02:00
DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", status);
2023-10-11 08:35:20 +02:00
PsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
2023-10-10 19:49:17 +02:00
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
return status;
}
2023-10-09 18:27:04 +02:00
return status;
}
STATIC
NTSTATUS
DrvLoadInitialiseObCbConfig()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
/*
* 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(&process_config.ob_cb_config.lock);
}
STATIC
VOID
DrvLoadInitialiseReportQueue(
2023-10-09 20:19:51 +02:00
_Out_ PBOOLEAN Flag
2023-10-09 18:27:04 +02:00
)
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
InitialiseGlobalReportQueue(Flag);
}
STATIC
VOID
DrvLoadInitialiseProcessConfig()
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-10-09 18:27:04 +02:00
KeInitializeGuardedMutex(&process_config.lock);
}
STATIC
NTSTATUS
DrvLoadInitialiseDriverConfig(
2023-09-01 14:30:32 +02:00
_In_ PUNICODE_STRING RegistryPath
)
{
2023-10-10 15:52:42 +02:00
PAGED_CODE();
2023-09-01 18:45:06 +02:00
NTSTATUS status;
2023-09-02 10:54:04 +02:00
2023-09-03 19:33:27 +02:00
/* 3rd page acts as a null terminator for the callback routine */
2023-10-05 08:27:17 +02:00
RTL_QUERY_REGISTRY_TABLE query_table[3] = { 0 };
KeInitializeGuardedMutex(&driver_config.lock);
2023-10-09 09:34:30 +02:00
driver_config.unload_in_progress = FALSE;
2023-10-05 08:27:17 +02:00
RtlInitUnicodeString(&driver_config.device_name, L"\\Device\\DonnaAC");
RtlInitUnicodeString(&driver_config.device_symbolic_link, L"\\??\\DonnaAC");
RtlCopyUnicodeString(&driver_config.registry_path, RegistryPath);
query_table[0].Flags = RTL_QUERY_REGISTRY_NOEXPAND;
query_table[0].Name = L"ImagePath";
query_table[0].DefaultType = REG_MULTI_SZ;
query_table[0].DefaultLength = 0;
query_table[0].DefaultData = NULL;
query_table[0].EntryContext = NULL;
query_table[0].QueryRoutine = RegistryPathQueryCallbackRoutine;
query_table[1].Flags = RTL_QUERY_REGISTRY_NOEXPAND;
query_table[1].Name = L"DisplayName";
query_table[1].DefaultType = REG_SZ;
query_table[1].DefaultLength = 0;
query_table[1].DefaultData = NULL;
query_table[1].EntryContext = NULL;
query_table[1].QueryRoutine = RegistryPathQueryCallbackRoutine;
2023-09-01 18:45:06 +02:00
status = RtlxQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
RegistryPath->Buffer,
&query_table,
NULL,
NULL
);
2023-09-01 13:46:31 +02:00
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-01 13:46:31 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("RtlxQueryRegistryValues failed with status %x", status);
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-09-01 18:45:06 +02:00
return status;
2023-09-01 13:46:31 +02:00
}
2023-09-01 18:45:06 +02:00
status = RtlUnicodeStringToAnsiString(
&driver_config.ansi_driver_name,
&driver_config.unicode_driver_name,
TRUE
);
2023-09-01 13:46:31 +02:00
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-01 13:46:31 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("Failed to convert unicode string to ansi string");
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-09-01 18:45:06 +02:00
return status;
2023-09-01 13:46:31 +02:00
}
2023-10-05 08:27:17 +02:00
status = ParseSMBIOSTable(
2023-09-04 17:00:36 +02:00
&driver_config.system_information.motherboard_serial,
sizeof(driver_config.system_information.motherboard_serial)
2023-09-04 15:36:26 +02:00
);
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-04 15:36:26 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("ParseSMBIOSTable failed with status %x", status);
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-09-04 15:36:26 +02:00
return status;
}
2023-09-06 17:33:08 +02:00
status = GetHardDiskDriveSerialNumber(
&driver_config.system_information.drive_0_serial,
2023-10-05 08:27:17 +02:00
sizeof(driver_config.system_information.drive_0_serial)
2023-09-06 17:33:08 +02:00
);
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-06 17:33:08 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("GetHardDiskDriverSerialNumber failed with status %x", status);
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-09-06 17:33:08 +02:00
return status;
}
2023-10-09 18:27:04 +02:00
status = DrvLoadInitialiseObCbConfig();
2023-10-06 10:30:14 +02:00
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("AllocateCallbackStructure failed with status %x", status);
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-10-06 10:30:14 +02:00
return status;
}
2023-10-05 08:27:17 +02:00
DEBUG_LOG("Motherboard serial: %s", driver_config.system_information.motherboard_serial);
DEBUG_LOG("Drive 0 serial: %s", driver_config.system_information.drive_0_serial);
2023-09-04 15:36:26 +02:00
2023-09-01 18:45:06 +02:00
return status;
2023-09-01 13:46:31 +02:00
}
2023-10-10 15:52:42 +02:00
_Function_class_(DRIVER_INITIALIZE)
_IRQL_requires_same_
2023-10-05 08:27:17 +02:00
NTSTATUS
2023-09-26 12:00:45 +02:00
DriverEntry(
2023-08-17 10:45:50 +02:00
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
2023-08-21 11:45:00 +02:00
BOOLEAN flag = FALSE;
2023-08-17 10:45:50 +02:00
NTSTATUS status;
2023-08-24 15:12:49 +02:00
2023-10-11 18:05:29 +02:00
DEBUG_LOG("Beginning driver entry lolz");
2023-10-09 18:27:04 +02:00
status = DrvLoadInitialiseDriverConfig(RegistryPath);
2023-09-01 18:45:06 +02:00
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-05 11:16:32 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("InitialiseDriverConfigOnDriverEntry failed with status %x", status);
2023-09-05 11:16:32 +02:00
return status;
}
2023-08-30 13:15:57 +02:00
2023-10-09 18:27:04 +02:00
DrvLoadInitialiseProcessConfig();
2023-09-03 19:33:27 +02:00
2023-08-17 10:45:50 +02:00
status = IoCreateDevice(
DriverObject,
NULL,
2023-09-01 14:30:32 +02:00
&driver_config.device_name,
2023-08-17 10:45:50 +02:00
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DriverObject->DeviceObject
);
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-09-01 18:45:06 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("IoCreateDevice failed with status %x", status);
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-08-17 10:45:50 +02:00
return STATUS_FAILED_DRIVER_ENTRY;
2023-09-01 18:45:06 +02:00
}
2023-08-17 10:45:50 +02:00
status = IoCreateSymbolicLink(
2023-09-01 14:30:32 +02:00
&driver_config.device_symbolic_link,
&driver_config.device_name
2023-08-17 10:45:50 +02:00
);
2023-10-05 08:27:17 +02:00
if (!NT_SUCCESS(status))
2023-08-17 10:45:50 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("failed to create symbolic link");
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-10-05 08:27:17 +02:00
IoDeleteDevice(DriverObject->DeviceObject);
2023-08-17 10:45:50 +02:00
return STATUS_FAILED_DRIVER_ENTRY;
}
2023-10-05 08:27:17 +02:00
DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
2023-08-17 10:45:50 +02:00
DriverObject->DriverUnload = DriverUnload;
2023-10-09 18:27:04 +02:00
DrvLoadInitialiseReportQueue(&flag);
2023-08-20 16:12:04 +02:00
2023-10-05 08:27:17 +02:00
if (!flag)
2023-08-20 16:12:04 +02:00
{
2023-10-05 08:27:17 +02:00
DEBUG_ERROR("failed to init report queue");
2023-10-09 18:27:04 +02:00
DrvUnloadFreeConfigStrings();
2023-10-05 08:27:17 +02:00
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
IoDeleteDevice(DriverObject->DeviceObject);
2023-08-20 16:12:04 +02:00
return STATUS_FAILED_DRIVER_ENTRY;
2023-09-28 15:56:07 +02:00
}
2023-09-24 13:13:20 +02:00
2023-10-09 18:27:04 +02:00
status = DrvLoadEnableNotifyRoutines();
2023-10-08 16:07:49 +02:00
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to init callback routines on driver entry");
2023-10-09 18:27:04 +02:00
DrvUnloadFreeGlobalReportQueue();
DrvUnloadFreeConfigStrings();
2023-10-08 16:07:49 +02:00
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
IoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}
2023-10-05 08:27:17 +02:00
DEBUG_LOG("DonnaAC Driver Entry Complete");
2023-08-17 10:45:50 +02:00
2023-08-30 13:15:57 +02:00
return STATUS_SUCCESS;
2023-08-17 10:45:50 +02:00
}