significant refactor to mdouel vaerification + expoert stuff kinda wip

This commit is contained in:
lhodges1 2024-01-07 15:13:41 +11:00
parent 52f00b9a1a
commit f29f4aad5f
21 changed files with 1907 additions and 547 deletions

View file

@ -5,6 +5,8 @@
#include "queue.h"
#include "pool.h"
#include "thread.h"
#include "modules.h"
#include "imports.h"
/*
* Interlocked intrinsics are only atomic with respect to other InterlockedXxx functions,
@ -33,6 +35,17 @@ typedef struct _PROCESS_LIST
PPROCESS_LIST process_list = NULL;
typedef struct _DRIVER_LIST
{
SINGLE_LIST_ENTRY start;
volatile ULONG count;
volatile BOOLEAN active;
KGUARDED_MUTEX lock;
} DRIVER_LIST, *PDRIVER_LIST;
PDRIVER_LIST driver_list = NULL;
STATIC
BOOLEAN
EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
@ -56,29 +69,29 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
VOID
CleanupProcessListFreeCallback(_In_ PPROCESS_LIST_ENTRY ProcessListEntry)
{
ObDereferenceObject(ProcessListEntry->parent);
ObDereferenceObject(ProcessListEntry->process);
ImpObDereferenceObject(ProcessListEntry->parent);
ImpObDereferenceObject(ProcessListEntry->process);
}
VOID
CleanupThreadListFreeCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry)
{
ObDereferenceObject(ThreadListEntry->thread);
ObDereferenceObject(ThreadListEntry->owning_process);
ImpObDereferenceObject(ThreadListEntry->thread);
ImpObDereferenceObject(ThreadListEntry->owning_process);
}
VOID
CleanupProcessListOnDriverUnload()
{
InterlockedExchange(&process_list->active, FALSE);
PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, TRUE);
ImpPsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, TRUE);
for (;;)
{
if (!ListFreeFirstEntry(
&process_list->start, &process_list->lock, CleanupProcessListFreeCallback))
{
ExFreePoolWithTag(process_list, POOL_TAG_THREAD_LIST);
ImpExFreePoolWithTag(process_list, POOL_TAG_THREAD_LIST);
return;
}
}
@ -88,14 +101,30 @@ VOID
CleanupThreadListOnDriverUnload()
{
InterlockedExchange(&thread_list->active, FALSE);
PsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
ImpPsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
for (;;)
{
if (!ListFreeFirstEntry(
&thread_list->start, &thread_list->lock, CleanupThreadListFreeCallback))
{
ExFreePoolWithTag(thread_list, POOL_TAG_THREAD_LIST);
ImpExFreePoolWithTag(thread_list, POOL_TAG_THREAD_LIST);
return;
}
}
}
VOID
CleanupDriverListOnDriverUnload()
{
InterlockedExchange(&driver_list->active, FALSE);
PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
for (;;)
{
if (!ListFreeFirstEntry(&driver_list->start, &driver_list->lock, NULL))
{
ImpExFreePoolWithTag(driver_list, POOL_TAG_THREAD_LIST);
return;
}
}
@ -107,7 +136,7 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
EnumerateThreadListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context)
{
KeAcquireGuardedMutex(&thread_list->lock);
ImpKeAcquireGuardedMutex(&thread_list->lock);
if (!CallbackRoutine)
goto unlock;
@ -122,7 +151,7 @@ EnumerateThreadListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOI
}
unlock:
KeReleaseGuardedMutex(&thread_list->lock);
ImpKeReleaseGuardedMutex(&thread_list->lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -131,7 +160,7 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context)
{
KeAcquireGuardedMutex(&process_list->lock);
ImpKeAcquireGuardedMutex(&process_list->lock);
if (!CallbackRoutine)
goto unlock;
@ -146,7 +175,153 @@ EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVO
}
unlock:
KeReleaseGuardedMutex(&process_list->lock);
ImpKeReleaseGuardedMutex(&process_list->lock);
}
NTSTATUS
InitialiseDriverList()
{
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
SYSTEM_MODULES modules = {0};
PDRIVER_LIST_ENTRY entry = NULL;
PRTL_MODULE_EXTENDED_INFO module_entry = NULL;
driver_list =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(DRIVER_LIST), POOL_TAG_THREAD_LIST);
if (!driver_list)
return STATUS_MEMORY_NOT_ALLOCATED;
InterlockedExchange(&driver_list->active, TRUE);
ListInit(&driver_list->start, &driver_list->lock);
status = GetSystemModuleInformation(&modules);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("GetSystemModuleInformation failed with status %x", status);
return status;
}
/* skip hal.dll and ntosknrl.exe */
for (INT index = 2; index < modules.module_count; index++)
{
entry = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(DRIVER_LIST_ENTRY), POOL_TAG_THREAD_LIST);
if (!entry)
{
status = STATUS_MEMORY_NOT_ALLOCATED;
goto end;
}
module_entry = &((PRTL_MODULE_EXTENDED_INFO)modules.address)[index];
entry->hashed = TRUE;
entry->ImageBase = module_entry->ImageBase;
entry->ImageSize = module_entry->ImageSize;
RtlCopyMemory(
entry->path, module_entry->FullPathName, sizeof(module_entry->FullPathName));
status = HashModule(module_entry, entry->text_hash);
if (status == STATUS_INVALID_IMAGE_WIN_32)
{
DEBUG_ERROR("32 bit module not hashed, will hash later. %x", status);
entry->hashed = FALSE;
}
else if (!NT_SUCCESS(status))
{
DEBUG_ERROR("HashModule failed with status %x", status);
entry->hashed = FALSE;
}
ListInsert(&driver_list->start, entry, &driver_list->lock);
}
end:
if (modules.address)
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return STATUS_SUCCESS;
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
FindDriverEntryByBaseAddress(_In_ PVOID ImageBase, _Out_ PDRIVER_LIST_ENTRY* Entry)
{
*Entry = NULL;
ImpKeAcquireGuardedMutex(&driver_list->lock);
PDRIVER_LIST_ENTRY entry = (PDRIVER_LIST_ENTRY)driver_list->start.Next;
while (entry)
{
if (entry->ImageBase == ImageBase)
{
*Entry = entry;
goto unlock;
}
entry = entry->list.Next;
}
unlock:
ImpKeReleaseGuardedMutex(&driver_list->lock);
}
VOID
ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDRIVER_LIST_ENTRY entry = NULL;
RTL_MODULE_EXTENDED_INFO module = {0};
if (InterlockedExchange(&driver_list->active, driver_list->active) == FALSE)
return;
if (ImageInfo->SystemModeImage == TRUE)
{
FindDriverEntryByBaseAddress(ImageInfo->ImageBase, &entry);
if (entry)
return;
DEBUG_VERBOSE("New system image: %wZ", FullImageName);
entry = ExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(DRIVER_LIST_ENTRY), POOL_TAG_THREAD_LIST);
if (!entry)
return;
entry->hashed = TRUE;
entry->ImageBase = ImageInfo->ImageBase;
entry->ImageSize = ImageInfo->ImageSize;
module.ImageBase = ImageInfo->ImageBase;
module.ImageSize = ImageInfo->ImageSize;
status = HashModule(&module, &entry->text_hash);
if (status == STATUS_INVALID_IMAGE_WIN_32)
{
DEBUG_ERROR("32 bit module not hashed, will hash later. %x", status);
entry->hashed = FALSE;
}
else if (!NT_SUCCESS(status))
{
DEBUG_ERROR("HashModule failed with status %x", status);
entry->hashed = FALSE;
}
ListInsert(&driver_list->start, entry, &driver_list->lock);
}
}
NTSTATUS
@ -155,7 +330,7 @@ InitialiseProcessList()
PAGED_CODE();
process_list =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(PROCESS_LIST), POOL_TAG_THREAD_LIST);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(PROCESS_LIST), POOL_TAG_THREAD_LIST);
if (!process_list)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -172,7 +347,7 @@ InitialiseThreadList()
PAGED_CODE();
thread_list =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(THREAD_LIST), POOL_TAG_THREAD_LIST);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(THREAD_LIST), POOL_TAG_THREAD_LIST);
if (!thread_list)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -190,7 +365,7 @@ VOID
FindProcessListEntryByProcess(_In_ PKPROCESS Process, _Inout_ PPROCESS_LIST_ENTRY* Entry)
{
*Entry = NULL;
KeAcquireGuardedMutex(&process_list->lock);
ImpKeAcquireGuardedMutex(&process_list->lock);
PPROCESS_LIST_ENTRY entry = (PPROCESS_LIST_ENTRY)process_list->start.Next;
@ -205,7 +380,7 @@ FindProcessListEntryByProcess(_In_ PKPROCESS Process, _Inout_ PPROCESS_LIST_ENTR
entry = entry->list.Next;
}
unlock:
KeReleaseGuardedMutex(&process_list->lock);
ImpKeReleaseGuardedMutex(&process_list->lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -215,7 +390,7 @@ VOID
FindThreadListEntryByThreadAddress(_In_ PKTHREAD Thread, _Inout_ PTHREAD_LIST_ENTRY* Entry)
{
*Entry = NULL;
KeAcquireGuardedMutex(&thread_list->lock);
ImpKeAcquireGuardedMutex(&thread_list->lock);
PTHREAD_LIST_ENTRY entry = (PTHREAD_LIST_ENTRY)thread_list->start.Next;
@ -230,7 +405,7 @@ FindThreadListEntryByThreadAddress(_In_ PKTHREAD Thread, _Inout_ PTHREAD_LIST_EN
entry = entry->list.Next;
}
unlock:
KeReleaseGuardedMutex(&thread_list->lock);
ImpKeReleaseGuardedMutex(&thread_list->lock);
}
VOID
@ -243,22 +418,22 @@ ProcessCreateNotifyRoutine(_In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOO
if (InterlockedExchange(&process_list->active, process_list->active) == FALSE)
return;
PsLookupProcessByProcessId(ParentId, &parent);
PsLookupProcessByProcessId(ProcessId, &process);
ImpPsLookupProcessByProcessId(ParentId, &parent);
ImpPsLookupProcessByProcessId(ProcessId, &process);
if (!parent || !process)
return;
if (Create)
{
entry = ExAllocatePool2(
entry = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(PROCESS_LIST_ENTRY), POOL_TAG_THREAD_LIST);
if (!entry)
return;
ObReferenceObject(parent);
ObReferenceObject(process);
ImpObfReferenceObject(parent);
ImpObfReferenceObject(process);
entry->parent = parent;
entry->process = process;
@ -272,8 +447,8 @@ ProcessCreateNotifyRoutine(_In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOO
if (!entry)
return;
ObDereferenceObject(entry->parent);
ObDereferenceObject(entry->process);
ImpObDereferenceObject(entry->parent);
ImpObDereferenceObject(entry->process);
ListRemoveEntry(&process_list->start, entry, &process_list->lock);
}
@ -290,22 +465,22 @@ ThreadCreateNotifyRoutine(_In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ BOOL
if (InterlockedExchange(&thread_list->active, thread_list->active) == FALSE)
return;
PsLookupThreadByThreadId(ThreadId, &thread);
PsLookupProcessByProcessId(ProcessId, &process);
ImpPsLookupThreadByThreadId(ThreadId, &thread);
ImpPsLookupProcessByProcessId(ProcessId, &process);
if (!thread || !process)
return;
if (Create)
{
entry = ExAllocatePool2(
entry = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(THREAD_LIST_ENTRY), POOL_TAG_THREAD_LIST);
if (!entry)
return;
ObReferenceObject(thread);
ObReferenceObject(process);
ImpObfReferenceObject(thread);
ImpObfReferenceObject(process);
entry->thread = thread;
entry->owning_process = process;
@ -321,8 +496,8 @@ ThreadCreateNotifyRoutine(_In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ BOOL
if (!entry)
return;
ObDereferenceObject(entry->thread);
ObDereferenceObject(entry->owning_process);
ImpObDereferenceObject(entry->thread);
ImpObDereferenceObject(entry->owning_process);
ListRemoveEntry(&thread_list->start, entry, &thread_list->lock);
}
@ -359,7 +534,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
PEPROCESS process_creator = PsGetCurrentProcess();
PEPROCESS protected_process = NULL;
PEPROCESS target_process = (PEPROCESS)OperationInformation->Object;
HANDLE process_creator_id = PsGetProcessId(process_creator);
HANDLE process_creator_id = ImpPsGetProcessId(process_creator);
LONG protected_process_id = 0;
LPCSTR process_creator_name = NULL;
LPCSTR target_process_name = NULL;
@ -376,16 +551,16 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
if (!configuration)
return OB_PREOP_SUCCESS;
KeAcquireGuardedMutex(&configuration->lock);
ImpKeAcquireGuardedMutex(&configuration->lock);
GetProtectedProcessId(&protected_process_id);
GetProtectedProcessEProcess(&protected_process);
if (!protected_process_id || !protected_process)
goto end;
process_creator_name = PsGetProcessImageFileName(process_creator);
target_process_name = PsGetProcessImageFileName(target_process);
protected_process_name = PsGetProcessImageFileName(protected_process);
process_creator_name = ImpPsGetProcessImageFileName(process_creator);
target_process_name = ImpPsGetProcessImageFileName(target_process);
protected_process_name = ImpPsGetProcessImageFileName(protected_process);
if (!protected_process_name || !target_process_name)
goto end;
@ -430,9 +605,9 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
// DEBUG_LOG("handle stripped from: %s", process_creator_name);
POPEN_HANDLE_FAILURE_REPORT report =
ExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(OPEN_HANDLE_FAILURE_REPORT),
REPORT_POOL_TAG);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(OPEN_HANDLE_FAILURE_REPORT),
REPORT_POOL_TAG);
if (!report)
goto end;
@ -440,7 +615,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
report->is_kernel_handle = OperationInformation->KernelHandle;
report->process_id = process_creator_id;
report->thread_id = PsGetCurrentThreadId();
report->thread_id = ImpPsGetCurrentThreadId();
report->access =
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
@ -454,7 +629,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
end:
KeReleaseGuardedMutex(&configuration->lock);
ImpKeReleaseGuardedMutex(&configuration->lock);
return OB_PREOP_SUCCESS;
}
@ -469,7 +644,7 @@ ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY Ha
old_value = InterlockedOr((PLONG)&HandleTableEntry->VolatileLowValue, 1);
/* Unblock any waiters */
ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
ImpExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
}
STATIC
@ -495,17 +670,17 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
/* Object header is the first 30 bytes of the object */
object = (uintptr_t)object_header + OBJECT_HEADER_SIZE;
object_type = ObGetObjectType(object);
object_type = ImpObGetObjectType(object);
/* TODO: check for threads aswell */
if (!RtlCompareUnicodeString(&object_type->Name, &OBJECT_TYPE_PROCESS, TRUE))
if (!ImpRtlCompareUnicodeString(&object_type->Name, &OBJECT_TYPE_PROCESS, TRUE))
{
process = (PEPROCESS)object;
process_name = PsGetProcessImageFileName(process);
process_name = ImpPsGetProcessImageFileName(process);
GetProtectedProcessEProcess(&protected_process);
protected_process_name = PsGetProcessImageFileName(protected_process);
protected_process_name = ImpPsGetProcessImageFileName(protected_process);
if (strcmp(process_name, protected_process_name))
goto end;
@ -596,7 +771,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
DEBUG_VERBOSE("Stripped PROCESS_VM_WRITE");
}
POPEN_HANDLE_FAILURE_REPORT report = ExAllocatePool2(
POPEN_HANDLE_FAILURE_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(OPEN_HANDLE_FAILURE_REPORT), REPORT_POOL_TAG);
if (!report)
@ -612,7 +787,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
*/
report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
report->is_kernel_handle = 0;
report->process_id = PsGetProcessId(process);
report->process_id = ImpPsGetProcessId(process);
report->thread_id = 0;
report->access = handle_access_mask;
@ -630,7 +805,7 @@ end:
NTSTATUS
EnumerateProcessHandles(_In_ PPROCESS_LIST_ENTRY ProcessListEntry, _In_opt_ PVOID Context)
{
/* Handles are stored in paged memory */
/* Handles are stored in pageable memory */
PAGED_CODE();
UNREFERENCED_PARAMETER(Context);
@ -647,13 +822,13 @@ EnumerateProcessHandles(_In_ PPROCESS_LIST_ENTRY ProcessListEntry, _In_opt_ PVOI
if (!handle_table)
return STATUS_INVALID_ADDRESS;
if (!MmIsAddressValid(handle_table))
if (!ImpMmIsAddressValid(handle_table))
return STATUS_INVALID_ADDRESS;
#pragma warning(push)
#pragma warning(suppress : 6387)
BOOLEAN result = ExEnumHandleTable(handle_table, EnumHandleCallback, NULL, NULL);
BOOLEAN result = ImpExEnumHandleTable(handle_table, EnumHandleCallback, NULL, NULL);
#pragma warning(pop)

View file

@ -62,6 +62,20 @@ typedef struct _PROCESS_LIST_ENTRY
} PROCESS_LIST_ENTRY, *PPROCESS_LIST_ENTRY;
typedef struct _DRIVER_LIST_ENTRY
{
SINGLE_LIST_ENTRY list;
PVOID ImageBase;
ULONG ImageSize;
BOOLEAN hashed;
CHAR path[0x100];
CHAR text_hash[32];
} DRIVER_LIST_ENTRY, *PDRIVER_LIST_ENTRY;
NTSTATUS
InitialiseDriverList();
VOID NTAPI
ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry);
@ -130,7 +144,21 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
FindDriverEntryByBaseAddress(_In_ PVOID ImageBase, _Out_ PDRIVER_LIST_ENTRY* Entry);
VOID
CleanupProcessListOnDriverUnload();
VOID
CleanupDriverListOnDriverUnload();
VOID
ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo);
#endif

View file

@ -671,6 +671,44 @@ typedef struct _IMAGE_DOS_HEADER
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
PVOID ExceptionTable;
ULONG ExceptionTableSize;
// ULONG padding on IA64
PVOID GpValue;
PVOID NonPagedDebugInfo;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Unused5;
PVOID SectionPointer;
ULONG CheckSum;
// ULONG padding on IA64
PVOID LoadedImports;
PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
typedef struct _IMAGE_EXPORT_DIRECTORY
{
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions;
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
typedef struct _LOCAL_NT_HEADER
{
unsigned long Signature;

View file

@ -9,6 +9,7 @@
#include "thread.h"
#include "modules.h"
#include "integrity.h"
#include "imports.h"
STATIC
VOID
@ -214,11 +215,11 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName,
UNICODE_STRING value = {0};
PVOID temp_buffer = NULL;
RtlInitUnicodeString(&value_name, ValueName);
ImpRtlInitUnicodeString(&value_name, ValueName);
if (RtlCompareUnicodeString(&value_name, &image_path, FALSE) == FALSE)
if (ImpRtlCompareUnicodeString(&value_name, &image_path, FALSE) == FALSE)
{
temp_buffer = ExAllocatePool2(POOL_FLAG_PAGED, ValueLength, POOL_TAG_STRINGS);
temp_buffer = ImpExAllocatePool2(POOL_FLAG_PAGED, ValueLength, POOL_TAG_STRINGS);
if (!temp_buffer)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -230,9 +231,10 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName,
driver_config.driver_path.MaximumLength = ValueLength;
}
if (RtlCompareUnicodeString(&value_name, &display_name, FALSE) == FALSE)
if (ImpRtlCompareUnicodeString(&value_name, &display_name, FALSE) == FALSE)
{
temp_buffer = ExAllocatePool2(POOL_FLAG_PAGED, ValueLength + 20, POOL_TAG_STRINGS);
temp_buffer =
ImpExAllocatePool2(POOL_FLAG_PAGED, ValueLength + 20, POOL_TAG_STRINGS);
if (!temp_buffer)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -284,7 +286,7 @@ FreeApcContextStructure(_Inout_ PAPC_CONTEXT_HEADER Context)
if (Context->count != 0)
goto unlock;
ExFreePoolWithTag(Context, POOL_TAG_APC);
ImpExFreePoolWithTag(Context, POOL_TAG_APC);
entry[index] = NULL;
result = TRUE;
goto unlock;
@ -307,9 +309,9 @@ IncrementApcCount(_In_ LONG ContextId)
if (!header)
return;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
header->count += 1;
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -320,16 +322,16 @@ FreeApcAndDecrementApcCount(_Inout_ PRKAPC Apc, _In_ LONG ContextId)
{
PAPC_CONTEXT_HEADER context = NULL;
ExFreePoolWithTag(Apc, POOL_TAG_APC);
ImpExFreePoolWithTag(Apc, POOL_TAG_APC);
GetApcContext(&context, ContextId);
if (!context)
goto end;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
context->count -= 1;
end:
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
/*
@ -367,11 +369,11 @@ QueryActiveApcContextsForCompletion()
GetApcContextByIndex(&entry, index);
/* acquire mutex after we get the context to prevent thread deadlock */
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
if (entry == NULL)
{
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
continue;
}
@ -380,7 +382,7 @@ QueryActiveApcContextsForCompletion()
if (entry->count > 0 || entry->allocation_in_progress == TRUE)
{
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
continue;
}
@ -392,7 +394,7 @@ QueryActiveApcContextsForCompletion()
break;
}
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
return STATUS_SUCCESS;
}
@ -413,7 +415,7 @@ InsertApcContext(_In_ PVOID Context)
driver_config.unload_in_progress) == TRUE)
return STATUS_UNSUCCESSFUL;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
PAPC_CONTEXT_HEADER header = Context;
@ -428,7 +430,7 @@ InsertApcContext(_In_ PVOID Context)
}
}
end:
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
return status;
}
@ -438,7 +440,7 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
GetApcContext(_Out_ PVOID* Context, _In_ LONG ContextIdentifier)
{
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
{
@ -455,7 +457,7 @@ GetApcContext(_Out_ PVOID* Context, _In_ LONG ContextIdentifier)
}
unlock:
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -468,9 +470,9 @@ GetApcContextByIndex(_Out_ PVOID* Context, _In_ INT Index)
return;
*Context = NULL;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
*Context = driver_config.apc_contexts[Index];
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
/*
@ -488,9 +490,9 @@ GetCallbackConfigStructure(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration)
return;
*CallbackConfiguration = NULL;
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
*CallbackConfiguration = &process_config.ob_cb_config;
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -505,9 +507,9 @@ GetDriverName(_Out_ LPCSTR* DriverName)
return;
*DriverName = NULL;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
*DriverName = driver_config.ansi_driver_name.Buffer;
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
PDEVICE_OBJECT
@ -516,6 +518,12 @@ GetDriverDeviceObject()
return driver_config.device_object;
}
PDRIVER_OBJECT
GetDriverObject()
{
return driver_config.driver_object;
}
GetSystemModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT* Context)
{
*Context = &driver_config.sys_val_context;
@ -529,10 +537,10 @@ GetDriverPath(_Out_ PUNICODE_STRING DriverPath)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DriverPath, sizeof(UNICODE_STRING));
RtlInitUnicodeString(DriverPath, driver_config.driver_path.Buffer);
KeReleaseGuardedMutex(&driver_config.lock);
ImpRtlInitUnicodeString(DriverPath, driver_config.driver_path.Buffer);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -543,10 +551,10 @@ GetDriverRegistryPath(_Out_ PUNICODE_STRING RegistryPath)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(RegistryPath, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(RegistryPath, &driver_config.registry_path);
KeReleaseGuardedMutex(&driver_config.lock);
ImpRtlCopyUnicodeString(RegistryPath, &driver_config.registry_path);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -557,10 +565,10 @@ GetDriverDeviceName(_Out_ PUNICODE_STRING DeviceName)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceName, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceName, &driver_config.device_name);
KeReleaseGuardedMutex(&driver_config.lock);
ImpRtlCopyUnicodeString(DeviceName, &driver_config.device_name);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -571,10 +579,10 @@ GetDriverSymbolicLink(_Out_ PUNICODE_STRING DeviceSymbolicLink)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceSymbolicLink, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceSymbolicLink, &driver_config.device_symbolic_link);
KeReleaseGuardedMutex(&driver_config.lock);
ImpRtlCopyUnicodeString(DeviceSymbolicLink, &driver_config.device_symbolic_link);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -589,9 +597,9 @@ GetDriverConfigSystemInformation(_Out_ PSYSTEM_INFORMATION* SystemInformation)
return;
*SystemInformation = NULL;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
*SystemInformation = &driver_config.system_information;
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -605,9 +613,9 @@ ReadProcessInitialisedConfigFlag(_Out_ PBOOLEAN Flag)
if (Flag == NULL)
return;
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
*Flag = process_config.initialised;
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -622,9 +630,9 @@ GetProtectedProcessEProcess(_Out_ PEPROCESS* Process)
return;
*Process = NULL;
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
*Process = process_config.process;
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -635,10 +643,10 @@ GetProtectedProcessId(_Out_ PLONG ProcessId)
{
PAGED_CODE();
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
RtlZeroMemory(ProcessId, sizeof(LONG));
*ProcessId = process_config.km_handle;
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
/*
@ -655,15 +663,15 @@ ProcCloseDisableObCallbacks()
{
PAGED_CODE();
KeAcquireGuardedMutex(&process_config.ob_cb_config.lock);
ImpKeAcquireGuardedMutex(&process_config.ob_cb_config.lock);
if (process_config.ob_cb_config.registration_handle)
{
ObUnRegisterCallbacks(process_config.ob_cb_config.registration_handle);
ImpObUnRegisterCallbacks(process_config.ob_cb_config.registration_handle);
process_config.ob_cb_config.registration_handle = NULL;
}
KeReleaseGuardedMutex(&process_config.ob_cb_config.lock);
ImpKeReleaseGuardedMutex(&process_config.ob_cb_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -676,12 +684,12 @@ ProcCloseClearProcessConfiguration()
DEBUG_INFO("Protected process closed. Clearing process configuration.");
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&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);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
/*
@ -711,7 +719,7 @@ ProcLoadEnableObCallbacks()
DEBUG_VERBOSE("Enabling ObRegisterCallbacks.");
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
OB_CALLBACK_REGISTRATION callback_registration = {0};
OB_OPERATION_REGISTRATION operation_registration = {0};
@ -728,7 +736,7 @@ ProcLoadEnableObCallbacks()
callback_registration.OperationRegistrationCount = 1;
callback_registration.RegistrationContext = NULL;
status = ObRegisterCallbacks(&callback_registration,
status = ImpObRegisterCallbacks(&callback_registration,
&process_config.ob_cb_config.registration_handle);
if (!NT_SUCCESS(status))
@ -746,7 +754,7 @@ ProcLoadEnableObCallbacks()
// DEBUG_ERROR( "Failed to launch ps create notif routines with status %x", status );
end:
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
return status;
}
@ -756,9 +764,9 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
ImageLoadSetProcessId(_In_ HANDLE ProcessId)
{
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
process_config.km_handle = (ULONG)ProcessId;
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -783,14 +791,14 @@ ProcLoadInitialiseProcessConfig(_In_ PIRP Irp)
information = (PDRIVER_INITIATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
KeAcquireGuardedMutex(&process_config.lock);
ImpKeAcquireGuardedMutex(&process_config.lock);
process_config.um_handle = information->protected_process_id;
/*
* What if we pass an invalid handle here? not good.
*/
status = PsLookupProcessByProcessId(process_config.um_handle, &process);
status = ImpPsLookupProcessByProcessId(process_config.um_handle, &process);
if (!NT_SUCCESS(status))
{
@ -798,7 +806,7 @@ ProcLoadInitialiseProcessConfig(_In_ PIRP Irp)
goto end;
}
process_config.km_handle = PsGetProcessId(process);
process_config.km_handle = ImpPsGetProcessId(process);
if (!process_config.km_handle)
{
@ -811,7 +819,7 @@ ProcLoadInitialiseProcessConfig(_In_ PIRP Irp)
process_config.initialised = TRUE;
end:
KeReleaseGuardedMutex(&process_config.lock);
ImpKeReleaseGuardedMutex(&process_config.lock);
return status;
}
@ -872,8 +880,8 @@ BOOLEAN
DrvUnloadFreeAllApcContextStructures()
{
BOOLEAN flag = TRUE;
KeAcquireGuardedMutex(&driver_config.lock);
ImpKeAcquireGuardedMutex(&driver_config.lock);
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++)
{
@ -889,12 +897,12 @@ DrvUnloadFreeAllApcContextStructures()
goto unlock;
}
ExFreePoolWithTag(entry, POOL_TAG_APC);
ImpExFreePoolWithTag(entry, POOL_TAG_APC);
}
}
unlock:
KeReleaseGuardedMutex(&driver_config.lock);
ImpKeReleaseGuardedMutex(&driver_config.lock);
return flag;
}
@ -905,13 +913,13 @@ DrvUnloadFreeConfigStrings()
PAGED_CODE();
if (driver_config.unicode_driver_name.Buffer)
ExFreePoolWithTag(driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS);
ImpExFreePoolWithTag(driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS);
if (driver_config.driver_path.Buffer)
ExFreePoolWithTag(driver_config.driver_path.Buffer, POOL_TAG_STRINGS);
ImpExFreePoolWithTag(driver_config.driver_path.Buffer, POOL_TAG_STRINGS);
if (driver_config.ansi_driver_name.Buffer)
RtlFreeAnsiString(&driver_config.ansi_driver_name);
ImpRtlFreeAnsiString(&driver_config.ansi_driver_name);
}
STATIC
@ -920,7 +928,7 @@ DrvUnloadFreeSymbolicLink()
{
PAGED_CODE();
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
ImpIoDeleteSymbolicLink(&driver_config.device_symbolic_link);
}
STATIC
@ -941,6 +949,15 @@ DrvUnloadFreeThreadList()
CleanupThreadListOnDriverUnload();
}
STATIC
VOID
DrvUnloadFreeDriverList()
{
PAGED_CODE();
CleanupDriverListOnDriverUnload();
}
STATIC
VOID
DrvUnloadFreeProcessList()
@ -959,6 +976,15 @@ DrvUnloadFreeModuleValidationContext()
CleanupValidationContextOnUnload(&driver_config.sys_val_context);
}
STATIC
VOID
DrvUnloadFreeImportsStructure()
{
PAGED_CODE();
FreeDriverImportsStructure();
}
STATIC
VOID
DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
@ -979,11 +1005,12 @@ DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
DrvUnloadUnregisterObCallbacks();
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
DrvUnloadFreeDriverList();
DrvUnloadFreeConfigStrings();
DrvUnloadFreeGlobalReportQueue();
DrvUnloadFreeSymbolicLink();
IoDeleteDevice(DriverObject->DeviceObject);
ImpIoDeleteDevice(DriverObject->DeviceObject);
DrvUnloadFreeImportsStructure();
DEBUG_INFO("Driver successfully unloaded.");
}
@ -1004,10 +1031,20 @@ DrvLoadEnableNotifyRoutines()
DEBUG_VERBOSE("Enabling driver wide notify routines.");
status = InitialiseDriverList();
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("InitialiseDriverList failed with status %x", status);
return status;
}
status = InitialiseThreadList();
if (!NT_SUCCESS(status))
{
DrvUnloadFreeDriverList();
DEBUG_ERROR("InitialiseThreadList failed with status %x", status);
return status;
}
@ -1017,43 +1054,47 @@ DrvLoadEnableNotifyRoutines()
if (!NT_SUCCESS(status))
{
DrvUnloadFreeThreadList();
DrvUnloadFreeDriverList();
DEBUG_ERROR("InitialiseProcessList failed with status %x", status);
return status;
}
status = PsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
status = PsSetLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("PsSetLoadImageNotifyRoutine failed with status %x", status);
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
DrvUnloadFreeDriverList();
return status;
}
status = ImpPsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("PsSetCreateThreadNotifyRoutine failed with status %x", status);
PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
DrvUnloadFreeDriverList();
return status;
}
status = PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, FALSE);
status = ImpPsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, FALSE);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", status);
PsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
ImpPsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
DrvUnloadFreeDriverList();
return status;
}
// status = PsSetLoadImageNotifyRoutine(ImageLoadNotifyRoutine);
// if (!NT_SUCCESS(status))
//{
// DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", status);
// PsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
// PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, TRUE);
// DrvUnloadFreeThreadList();
// DrvUnloadFreeProcessList();
// return status;
// }
DEBUG_VERBOSE("Successfully enabled driver wide notify routines.");
return status;
@ -1069,7 +1110,7 @@ DrvLoadInitialiseObCbConfig()
* 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);
ImpKeInitializeGuardedMutex(&process_config.ob_cb_config.lock);
}
STATIC
@ -1087,7 +1128,7 @@ DrvLoadInitialiseProcessConfig()
{
PAGED_CODE();
KeInitializeGuardedMutex(&process_config.lock);
ImpKeInitializeGuardedMutex(&process_config.lock);
}
/*
@ -1213,7 +1254,7 @@ DrvLoadGatherSystemEnvironmentSettings()
*/
if (APERFMsrTimingCheck())
driver_config.system_information.virtualised_environment = TRUE;
status = GetOsVersionInformation(&driver_config.system_information.os_information);
if (!NT_SUCCESS(status))
@ -1221,7 +1262,7 @@ DrvLoadGatherSystemEnvironmentSettings()
DEBUG_ERROR("GetOsVersionInformation failed with status %x", status);
return status;
}
status = GetSystemProcessorType();
if (!NT_SUCCESS(status))
@ -1229,7 +1270,7 @@ DrvLoadGatherSystemEnvironmentSettings()
DEBUG_ERROR("GetSystemProcessorType failed with status %x", status);
return status;
}
status = ParseSmbiosForGivenSystemEnvironment();
if (!NT_SUCCESS(status))
@ -1238,7 +1279,7 @@ DrvLoadGatherSystemEnvironmentSettings()
DrvUnloadFreeConfigStrings();
return status;
}
status =
GetHardDiskDriveSerialNumber(&driver_config.system_information.drive_0_serial,
sizeof(driver_config.system_information.drive_0_serial));
@ -1249,7 +1290,7 @@ DrvLoadGatherSystemEnvironmentSettings()
DrvUnloadFreeConfigStrings();
return status;
}
DEBUG_VERBOSE("OS Major Version: %lx, Minor Version: %lx, Build Number: %lx",
driver_config.system_information.os_information.dwMajorVersion,
driver_config.system_information.os_information.dwMinorVersion,
@ -1259,7 +1300,7 @@ DrvLoadGatherSystemEnvironmentSettings()
DEBUG_VERBOSE("Motherboard serial: %s",
driver_config.system_information.motherboard_serial);
DEBUG_VERBOSE("Drive 0 serial: %s", driver_config.system_information.drive_0_serial);
return status;
}
@ -1301,7 +1342,7 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath)
* when querying the system modules for our driver.
*/
status = RtlUnicodeStringToAnsiString(
status = ImpRtlUnicodeStringToAnsiString(
&driver_config.ansi_driver_name, &driver_config.unicode_driver_name, TRUE);
if (!NT_SUCCESS(status))
@ -1321,15 +1362,15 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST
DEBUG_VERBOSE("Initialising driver configuration");
KeInitializeGuardedMutex(&driver_config.lock);
ImpKeInitializeGuardedMutex(&driver_config.lock);
driver_config.unload_in_progress = FALSE;
driver_config.system_information.virtualised_environment = FALSE;
driver_config.sys_val_context.active = FALSE;
RtlInitUnicodeString(&driver_config.device_name, L"\\Device\\DonnaAC");
RtlInitUnicodeString(&driver_config.device_symbolic_link, L"\\??\\DonnaAC");
RtlCopyUnicodeString(&driver_config.registry_path, RegistryPath);
ImpRtlInitUnicodeString(&driver_config.device_name, L"\\Device\\DonnaAC");
ImpRtlInitUnicodeString(&driver_config.device_symbolic_link, L"\\??\\DonnaAC");
ImpRtlCopyUnicodeString(&driver_config.registry_path, RegistryPath);
status = DrvLoadRetrieveDriverNameFromRegistry(RegistryPath);
@ -1369,6 +1410,11 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
BOOLEAN flag = FALSE;
NTSTATUS status = STATUS_UNSUCCESSFUL;
/* store the driver object here as we need to access it in ResolveNtImports */
driver_config.driver_object = DriverObject;
ResolveNtImports();
DEBUG_VERBOSE("Beginning driver entry routine...");
@ -1382,7 +1428,7 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
DrvLoadInitialiseProcessConfig();
status = IoCreateDevice(DriverObject,
status = ImpIoCreateDevice(DriverObject,
NULL,
&driver_config.device_name,
FILE_DEVICE_UNKNOWN,
@ -1401,13 +1447,13 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
driver_config.device_object = DriverObject->DeviceObject;
status =
IoCreateSymbolicLink(&driver_config.device_symbolic_link, &driver_config.device_name);
ImpIoCreateSymbolicLink(&driver_config.device_symbolic_link, &driver_config.device_name);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("IoCreateSymbolicLink failed with status %x", status);
DrvUnloadFreeConfigStrings();
IoDeleteDevice(DriverObject->DeviceObject);
ImpIoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}
@ -1422,8 +1468,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
DEBUG_ERROR("InitialiseReportQueue failed with no status.");
DrvUnloadFreeConfigStrings();
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
IoDeleteDevice(DriverObject->DeviceObject);
ImpIoDeleteSymbolicLink(&driver_config.device_symbolic_link);
ImpIoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}
@ -1434,8 +1480,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
DEBUG_ERROR("EnablenotifyRoutines failed with status %x", status);
DrvUnloadFreeGlobalReportQueue();
DrvUnloadFreeConfigStrings();
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
IoDeleteDevice(DriverObject->DeviceObject);
ImpIoDeleteSymbolicLink(&driver_config.device_symbolic_link);
ImpIoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}

View file

@ -191,4 +191,7 @@ GetDriverDeviceObject();
GetSystemModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT* Context);
PDRIVER_OBJECT
GetDriverObject();
#endif

View file

@ -191,6 +191,7 @@
<ClCompile Include="callbacks.c" />
<ClCompile Include="driver.c" />
<ClCompile Include="hv.c" />
<ClCompile Include="imports.c" />
<ClCompile Include="integrity.c" />
<ClCompile Include="ioctl.c" />
<ClCompile Include="modules.c" />
@ -204,6 +205,7 @@
<ClInclude Include="driver.h" />
<ClInclude Include="hv.h" />
<ClInclude Include="ia32.h" />
<ClInclude Include="imports.h" />
<ClInclude Include="integrity.h" />
<ClInclude Include="ioctl.h" />
<ClInclude Include="modules.h" />

View file

@ -51,6 +51,9 @@
<ClCompile Include="thread.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imports.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="driver.h">
@ -86,6 +89,9 @@
<ClInclude Include="ia32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="imports.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="asm.asm">

View file

@ -1,7 +1,7 @@
#include "hv.h"
#include <intrin.h>
#include "imports.h"
#include "common.h"
#include "ioctl.h"
@ -34,7 +34,7 @@ _IRQL_always_function_max_(HIGH_LEVEL) INT APERFMsrTimingCheck()
* its executing on.
*/
new_affinity = (KAFFINITY)(1ull << KeGetCurrentProcessorNumber());
old_affinity = KeSetSystemAffinityThreadEx(new_affinity);
old_affinity = ImpKeSetSystemAffinityThreadEx(new_affinity);
/*
* Once we've locked our thread to the current core, we save the old irql
@ -69,7 +69,7 @@ _IRQL_always_function_max_(HIGH_LEVEL) INT APERFMsrTimingCheck()
*/
_enable();
__writecr8(old_irql);
KeRevertToUserAffinityThreadEx(old_affinity);
ImpKeRevertToUserAffinityThreadEx(old_affinity);
/*
* Now the only thing left to do is calculate the change. Now, on some VMs

215
driver/imports.c Normal file
View file

@ -0,0 +1,215 @@
#include "imports.h"
#include "common.h"
#include "driver.h"
#define EPROCESS_SECTION_BASE_OFFSET 0x520
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
#define IMAGE_DIRECTORY_ENTRY_TLS 9
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
PDRIVER_IMPORTS driver_imports = NULL;
VOID
FreeDriverImportsStructure()
{
if (driver_imports)
ExFreePoolWithTag(driver_imports, POOL_TAG_INTEGRITY);
}
PVOID
FindDriverBaseNoApi(_In_ PWCH Name)
{
PDRIVER_OBJECT driver = GetDriverObject();
PKLDR_DATA_TABLE_ENTRY first = (PKLDR_DATA_TABLE_ENTRY)driver->DriverSection;
/* first entry contains invalid data, 2nd entry is the kernel */
PKLDR_DATA_TABLE_ENTRY entry =
((PKLDR_DATA_TABLE_ENTRY)driver->DriverSection)->InLoadOrderLinks.Flink->Flink;
while (entry->InLoadOrderLinks.Flink != first)
{
/* todo: write our own unicode string comparison function, since the entire point of
* this is to find exports with no exports. */
if (!wcscmp(entry->BaseDllName.Buffer, Name))
{
return entry->DllBase;
}
entry = entry->InLoadOrderLinks.Flink;
}
return NULL;
}
void*
FindNtExport(const char* ExportName)
{
PVOID image_base = NULL;
PIMAGE_DOS_HEADER dos_header = NULL;
PLOCAL_NT_HEADER nt_header = NULL;
PIMAGE_OPTIONAL_HEADER64 optional_header = NULL;
PIMAGE_DATA_DIRECTORY data_dir = NULL;
PIMAGE_EXPORT_DIRECTORY export_dir = NULL;
PUINT32 export_name_table = NULL;
PCHAR name = NULL;
PUINT16 ordinals_table = NULL;
PUINT32 export_addr_table = NULL;
UINT32 ordinal = 0;
PVOID target_function_addr = 0;
UINT32 export_offset = 0;
if (!ExportName)
return NULL;
image_base = FindDriverBaseNoApi(L"ntoskrnl.exe");
if (!image_base)
{
DEBUG_ERROR("FindDriverBaseNoApi failed with no status");
return NULL;
}
/*
* todo: add comment explaining this shit
*/
dos_header = (PIMAGE_DOS_HEADER)image_base;
nt_header = (struct _IMAGE_NT_HEADERS64*)((UINT64)image_base + dos_header->e_lfanew);
optional_header = (PIMAGE_OPTIONAL_HEADER64)&nt_header->OptionalHeader;
data_dir = (PIMAGE_DATA_DIRECTORY) &
(optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
export_dir = (PIMAGE_EXPORT_DIRECTORY)((UINT64)image_base + data_dir->VirtualAddress);
export_name_table = (PUINT32)((UINT64)image_base + export_dir->AddressOfNames);
ordinals_table = (PUINT16)((UINT64)image_base + export_dir->AddressOfNameOrdinals);
export_addr_table = (PUINT32)((UINT64)image_base + export_dir->AddressOfFunctions);
for (INT index = 0; index < export_dir->NumberOfNames; index++)
{
name = (PCHAR)((UINT64)image_base + export_name_table[index]);
if (strcmp(name, ExportName))
continue;
ordinal = ordinals_table[index];
export_offset = export_addr_table[ordinal];
target_function_addr = (PVOID)((UINT64)image_base + export_offset);
DEBUG_VERBOSE("Function: %s, Address: %llx", name, target_function_addr);
return target_function_addr;
}
return NULL;
}
NTSTATUS
ResolveNtImports()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
/* todo fix! */
driver_imports =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(DRIVER_IMPORTS), POOL_TAG_INTEGRITY);
if (!driver_imports)
return STATUS_MEMORY_NOT_ALLOCATED;
// clang-format off
driver_imports->DrvImpObDereferenceObject = FindNtExport("ObDereferenceObject");
driver_imports->DrvImpPsGetProcessImageFileName = FindNtExport("PsGetProcessImageFileName");
driver_imports->DrvImpPsSetCreateProcessNotifyRoutine = FindNtExport("PsSetCreateProcessNotifyRoutine");
driver_imports->DrvImpPsRemoveCreateThreadNotifyRoutine = FindNtExport("PsRemoveCreateThreadNotifyRoutine");
driver_imports->DrvImpPsGetCurrentThreadId = FindNtExport("PsGetCurrentThreadId");
driver_imports->DrvImpPsGetProcessId = FindNtExport("PsGetProcessId");
driver_imports->DrvImpPsLookupProcessByProcessId = FindNtExport("PsLookupProcessByProcessId");
driver_imports->DrvImpExEnumHandleTable = FindNtExport("ExEnumHandleTable");
driver_imports->DrvImpObGetObjectType = FindNtExport("ObGetObjectType");
driver_imports->DrvImpExfUnblockPushLock = FindNtExport("ExfUnblockPushLock");
driver_imports->DrvImpstrstr = FindNtExport("strstr");
driver_imports->DrvImpRtlInitUnicodeString = FindNtExport("RtlInitUnicodeString");
driver_imports->DrvImpMmGetSystemRoutineAddress = FindNtExport("MmGetSystemRoutineAddress");
driver_imports->DrvImpRtlUnicodeStringToAnsiString = FindNtExport("RtlUnicodeStringToAnsiString");
driver_imports->DrvImpRtlCopyUnicodeString = FindNtExport("RtlCopyUnicodeString");
driver_imports->DrvImpRtlFreeAnsiString = FindNtExport("RtlFreeAnsiString");
driver_imports->DrvImpKeInitializeGuardedMutex = FindNtExport("KeInitializeGuardedMutex");
driver_imports->DrvImpIoCreateDevice = FindNtExport("IoCreateDevice");
driver_imports->DrvImpIoCreateSymbolicLink = FindNtExport("IoCreateSymbolicLink");
driver_imports->DrvImpIoDeleteDevice = FindNtExport("IoDeleteDevice");
driver_imports->DrvImpIoDeleteSymbolicLink = FindNtExport("IoDeleteSymbolicLink");
driver_imports->DrvImpObRegisterCallbacks = FindNtExport("ObRegisterCallbacks");
driver_imports->DrvImpObUnRegisterCallbacks = FindNtExport("ObUnRegisterCallbacks");
driver_imports->DrvImpPsSetCreateThreadNotifyRoutine = FindNtExport("PsSetCreateThreadNotifyRoutine");
driver_imports->DrvImpKeRevertToUserAffinityThreadEx = FindNtExport("KeRevertToUserAffinityThreadEx");
driver_imports->DrvImpKeSetSystemAffinityThreadEx = FindNtExport("KeSetSystemAffinityThreadEx");
driver_imports->DrvImpstrnlen = FindNtExport("strnlen");
driver_imports->DrvImpRtlInitAnsiString = FindNtExport("RtlInitAnsiString");
driver_imports->DrvImpRtlAnsiStringToUnicodeString = FindNtExport("RtlAnsiStringToUnicodeString");
driver_imports->DrvImpIoGetCurrentProcess = FindNtExport("IoGetCurrentProcess");
driver_imports->DrvImpRtlGetVersion = FindNtExport("RtlGetVersion");
driver_imports->DrvImpRtlCompareMemory = FindNtExport("RtlCompareMemory");
driver_imports->DrvImpExGetSystemFirmwareTable = FindNtExport("ExGetSystemFirmwareTable");
driver_imports->DrvImpIoAllocateWorkItem = FindNtExport("IoAllocateWorkItem");
driver_imports->DrvImpIoFreeWorkItem = FindNtExport("IoFreeWorkItem");
driver_imports->DrvImpIoQueueWorkItem = FindNtExport("IoQueueWorkItem");
driver_imports->DrvImpZwOpenFile = FindNtExport("ZwOpenFile");
driver_imports->DrvImpZwClose = FindNtExport("ZwClose");
driver_imports->DrvImpZwCreateSection = FindNtExport("ZwCreateSection");
driver_imports->DrvImpZwMapViewOfSection = FindNtExport("ZwMapViewOfSection");
driver_imports->DrvImpZwUnmapViewOfSection = FindNtExport("ZwUnmapViewOfSection");
driver_imports->DrvImpMmCopyMemory = FindNtExport("MmCopyMemory");
driver_imports->DrvImpZwDeviceIoControlFile = FindNtExport("ZwDeviceIoControlFile");
driver_imports->DrvImpKeStackAttachProcess = FindNtExport("KeStackAttachProcess");
driver_imports->DrvImpKeUnstackDetachProcess = FindNtExport("KeUnstackDetachProcess");
driver_imports->DrvImpKeWaitForSingleObject = FindNtExport("KeWaitForSingleObject");
driver_imports->DrvImpPsCreateSystemThread = FindNtExport("PsCreateSystemThread");
driver_imports->DrvImpIofCompleteRequest = FindNtExport("IofCompleteRequest");
driver_imports->DrvImpObReferenceObjectByHandle = FindNtExport("ObReferenceObjectByHandle");
driver_imports->DrvImpKeDelayExecutionThread = FindNtExport("KeDelayExecutionThread");
driver_imports->DrvImpKeRegisterNmiCallback = FindNtExport("KeRegisterNmiCallback");
driver_imports->DrvImpKeDeregisterNmiCallback = FindNtExport("KeDeregisterNmiCallback");
driver_imports->DrvImpKeQueryActiveProcessorCount = FindNtExport("KeQueryActiveProcessorCount");
driver_imports->DrvImpExAcquirePushLockExclusiveEx = FindNtExport("ExAcquirePushLockExclusiveEx");
driver_imports->DrvImpExReleasePushLockExclusiveEx = FindNtExport("ExReleasePushLockExclusiveEx");
driver_imports->DrvImpPsGetThreadId = FindNtExport("PsGetThreadId");
driver_imports->DrvImpRtlCaptureStackBackTrace = FindNtExport("RtlCaptureStackBackTrace");
driver_imports->DrvImpZwOpenDirectoryObject = FindNtExport("ZwOpenDirectoryObject");
driver_imports->DrvImpKeInitializeAffinityEx = FindNtExport("KeInitializeAffinityEx");
driver_imports->DrvImpKeAddProcessorAffinityEx = FindNtExport("KeAddProcessorAffinityEx");
driver_imports->DrvImpRtlQueryModuleInformation = FindNtExport("RtlQueryModuleInformation");
driver_imports->DrvImpKeInitializeApc = FindNtExport("KeInitializeApc");
driver_imports->DrvImpKeInsertQueueApc = FindNtExport("KeInsertQueueApc");
driver_imports->DrvImpKeGenericCallDpc = FindNtExport("KeGenericCallDpc");
driver_imports->DrvImpKeSignalCallDpcDone = FindNtExport("KeSignalCallDpcDone");
driver_imports->DrvImpMmGetPhysicalMemoryRangesEx2 = FindNtExport("MmGetPhysicalMemoryRangesEx2");
driver_imports->DrvImpMmGetVirtualForPhysical = FindNtExport("MmGetVirtualForPhysical");
driver_imports->DrvImpObfReferenceObject = FindNtExport("ObfReferenceObject");
driver_imports->DrvImpExFreePoolWithTag = FindNtExport("ExFreePoolWithTag");
driver_imports->DrvImpExAllocatePool2 = FindNtExport("ExAllocatePool2");
driver_imports->DrvImpKeReleaseGuardedMutex = FindNtExport("KeReleaseGuardedMutex");
driver_imports->DrvImpKeAcquireGuardedMutex = FindNtExport("KeAcquireGuardedMutex");
driver_imports->DrvImpDbgPrintEx = FindNtExport("DbgPrintEx");
driver_imports->DrvImpRtlCompareUnicodeString = FindNtExport("RtlCompareUnicodeString");
driver_imports->DrvImpRtlFreeUnicodeString = FindNtExport("RtlFreeUnicodeString");
driver_imports->DrvImpPsLookupThreadByThreadId = FindNtExport("PsLookupThreadByThreadId");
driver_imports->DrvImpIoGetCurrentIrpStackLocation = FindNtExport("IoGetCurrentIrpStackLocation");
driver_imports->DrvImpMmIsAddressValid = FindNtExport("MmIsAddressValid");
// clang-format on
return STATUS_SUCCESS;
}

719
driver/imports.h Normal file
View file

@ -0,0 +1,719 @@
#ifndef IMPORTS_H
#define IMPORTS_H
#include "common.h"
void*
FindNtExport(const char* ExportName);
VOID
FreeDriverImportsStructure();
#define IMPORT_FUNCTION_MAX_LENGTH 128
#define IMPORT_FUNCTION_COUNT 256
// clang-format off
typedef
void* (*pObDereferenceObject)(
void* Object
);
typedef
void* (*pObReferenceObject)(
void* Object
);
typedef
NTSTATUS (*pPsLookupThreadByThreadId)(
HANDLE ThreadId,
PETHREAD* Thread
);
typedef
BOOLEAN (*pMmIsAddressValid)(
void* VirtualAddress
);
typedef
NTSTATUS (*pPsSetCreateProcessNotifyRoutine)(
PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
BOOLEAN Remove
);
typedef
NTSTATUS (*pPsRemoveCreateThreadNotifyRoutine)(
PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
);
typedef
HANDLE (*pPsGetCurrentThreadId)(
void
);
typedef
HANDLE (*pPsGetProcessId)(
PEPROCESS Process
);
typedef
NTSTATUS (*pPsLookupProcessByProcessId)(
HANDLE ProcessId,
PEPROCESS* Process
);
typedef
void* (*pExEnumHandleTable)(
PHANDLE_TABLE HandleTable,
void* Callback,
void* Context,
PHANDLE Handle);
typedef
POBJECT_TYPE (*pObGetObjectType)(
void* Object
);
typedef
void (*pExfUnblockPushLock)(
PEX_PUSH_LOCK PushLock,
void* WaitBlock
);
typedef
LPCSTR (*pPsGetProcessImageFileName)(
PEPROCESS Process
);
typedef
INT (*pstrcmp)(
const CHAR* str1,
const CHAR* str2
);
typedef
PCHAR (*pstrstr)(
const CHAR* haystack,
const CHAR* needle
);
typedef
void (*pRtlInitUnicodeString)(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
typedef
NTSTATUS (*pRtlQueryRegistryValues)(
ULONG RelativeTo,
PCWSTR Path,
PRTL_QUERY_REGISTRY_TABLE QueryTable,
void* Context,
void* Environment
);
typedef
void* (*pMmGetSystemRoutineAddress)(
PUNICODE_STRING SystemRoutineName
);
typedef
NTSTATUS (*pRtlUnicodeStringToAnsiString)(
PANSI_STRING DestinationString,
PCUNICODE_STRING SourceString,
BOOLEAN AllocateDestinationString
);
typedef
void (*pRtlCopyUnicodeString)(
PUNICODE_STRING DestinationString,
PCUNICODE_STRING SourceString
);
typedef
void (*pRtlFreeAnsiString)(
PANSI_STRING AnsiString
);
typedef
void (*pKeInitializeGuardedMutex)(
PKGUARDED_MUTEX GuardedMutex
);
typedef
NTSTATUS (*pIoCreateDevice)(
PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize,
PUNICODE_STRING DeviceName,
DEVICE_TYPE DeviceType,
ULONG DeviceCharacteristics,
BOOLEAN Exclusive,
PDEVICE_OBJECT *DeviceObject
);
typedef
NTSTATUS (*pIoCreateSymbolicLink)(
PUNICODE_STRING SymbolicLinkName,
PUNICODE_STRING DeviceName
);
typedef
void (*pIoDeleteDevice)(
PDEVICE_OBJECT DeviceObject
);
typedef
void (*pIoDeleteSymbolicLink)(
PUNICODE_STRING SymbolicLinkName
);
typedef
NTSTATUS (*pObRegisterCallbacks)(
POB_CALLBACK_REGISTRATION CallbackRegistration,
void** RegistrationHandle
);
typedef
void (*pObUnRegisterCallbacks)(
void* RegistrationHandle
);
typedef
NTSTATUS (*pPsSetCreateThreadNotifyRoutine)(
PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
);
typedef
void (*pKeRevertToUserAffinityThreadEx)(
KAFFINITY Affinity
);
typedef
KAFFINITY (*pKeSetSystemAffinityThreadEx)(
KAFFINITY Affinity
);
typedef
SIZE_T (*pstrnlen)(
const CHAR* str,
SIZE_T maxCount
);
typedef
void (*pRtlInitAnsiString)(
PANSI_STRING DestinationString,
PCSZ SourceString
);
typedef
NTSTATUS (*pRtlAnsiStringToUnicodeString)(
PUNICODE_STRING DestinationString,
PCANSI_STRING SourceString,
BOOLEAN AllocateDestinationString
);
typedef
PEPROCESS (*pIoGetCurrentProcess)(
void
);
typedef
NTSTATUS (*pRtlGetVersion)(
PRTL_OSVERSIONINFOW lpVersionInformation
);
typedef
SIZE_T (*pRtlCompareMemory)(
const void* Source1,
const void* Source2,
SIZE_T Length
);
typedef
NTSTATUS (*pExGetSystemFirmwareTable)(
ULONG FirmwareTableProviderSignature,
ULONG FirmwareTableID,
void* pFirmwareTableBuffer,
ULONG BufferLength,
PULONG ReturnLength
);
typedef
PIO_WORKITEM (*pIoAllocateWorkItem)(
PDEVICE_OBJECT DeviceObject
);
typedef
void (*pIoFreeWorkItem)(
PIO_WORKITEM WorkItem
);
typedef
void (*pIoQueueWorkItem)(
PIO_WORKITEM IoWorkItem,
PIO_WORKITEM_ROUTINE WorkerRoutine,
WORK_QUEUE_TYPE QueueType,
void* Context
);
typedef
NTSTATUS (*pZwOpenFile)(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions
);
typedef
NTSTATUS (*pZwClose)(
HANDLE Handle
);
typedef
NTSTATUS (*pZwCreateSection)(
PHANDLE SectionHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PLARGE_INTEGER MaximumSize,
ULONG SectionPageProtection,
ULONG AllocationAttributes,
HANDLE FileHandle
);
typedef
NTSTATUS (*pZwMapViewOfSection)(
HANDLE SectionHandle,
HANDLE ProcessHandle,
void** BaseAddress,
ULONG_PTR ZeroBits,
SIZE_T CommitSize,
PLARGE_INTEGER SectionOffset,
PSIZE_T ViewSize,
SECTION_INHERIT InheritDisposition,
ULONG AllocationType,
ULONG Win32Protect
);
typedef
NTSTATUS (*pZwUnmapViewOfSection)(
HANDLE ProcessHandle,
void* BaseAddress
);
typedef
NTSTATUS (*pMmCopyMemory)(
PVOID TargetAddress,
MM_COPY_ADDRESS SourceAddress,
SIZE_T NumberOfBytes,
ULONG Flags,
PSIZE_T NumberOfBytesTransferred
);
typedef
NTSTATUS (*pZwDeviceIoControlFile)(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
void* ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG IoControlCode,
void* InputBuffer,
ULONG InputBufferLength,
void* OutputBuffer,
ULONG OutputBufferLength
);
typedef
void (*pKeStackAttachProcess)(
PRKPROCESS Process,
PKAPC_STATE ApcState
);
typedef
void (*pKeUnstackDetachProcess)(
PKAPC_STATE ApcState
);
typedef
NTSTATUS (*pKeWaitForSingleObject)(
void* Object,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
typedef
NTSTATUS (*pPsCreateSystemThread)(
PHANDLE ThreadHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine,
void* StartContext
);
typedef
void (*pIofCompleteRequest)(
PIRP Irp,
CCHAR PriorityBoost
);
typedef
NTSTATUS (*pObReferenceObjectByHandle)(
HANDLE Handle,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
void** Object,
POBJECT_HANDLE_INFORMATION HandleInformation
);
typedef
NTSTATUS (*pKeDelayExecutionThread)(
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Interval
);
typedef
void* (*pKeRegisterNmiCallback)(
void* CallbackRoutine,
void* Context
);
typedef
NTSTATUS (*pKeDeregisterNmiCallback)(
void* Handle
);
typedef
ULONG (*pKeQueryActiveProcessorCount)(
PKAFFINITY ActiveProcessors
);
typedef
void (*pExAcquirePushLockExclusiveEx)(
PEX_PUSH_LOCK PushLock,
ULONG Flags
);
typedef
void (*pExReleasePushLockExclusiveEx)(
PEX_PUSH_LOCK PushLock,
ULONG Flags
);
typedef
HANDLE (*pPsGetThreadId)(
PETHREAD Thread
);
typedef
USHORT (*pRtlCaptureStackBackTrace)(
ULONG FramesToSkip,
ULONG FramesToCapture,
void** BackTrace,
PULONG BackTraceHash
);
typedef
NTSTATUS (*pZwOpenDirectoryObject)(
PHANDLE DirectoryHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
typedef
void (*pKeInitializeAffinityEx)(
PKAFFINITY_EX AffinityMask
);
typedef
void (*pKeAddProcessorAffinityEx)(
PKAFFINITY_EX affinity,
INT num
);
typedef
NTSTATUS (*pRtlQueryModuleInformation)(
ULONG* InformationLength,
ULONG SizePerModule,
PVOID InformationBuffer
);
typedef
void (*pKeInitializeApc)(
PKAPC Apc,
PKTHREAD Thread,
KAPC_ENVIRONMENT Environment,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine,
KPROCESSOR_MODE ApcMode,
void* NormalContext
);
typedef
BOOLEAN (*pKeInsertQueueApc)(
PKAPC Apc,
void* SystemArgument1,
void* SystemArgument2,
KPRIORITY Increment
);
typedef
void (*pKeGenericCallDpc)(
PKDEFERRED_ROUTINE DpcRoutine,
void* Context
);
typedef
void (*pKeSignalCallDpcDone)(
void* SystemArgument1
);
typedef
PPHYSICAL_MEMORY_RANGE (*pMmGetPhysicalMemoryRangesEx2)(
PVOID PartitionObject,
ULONG Flags
);
typedef
void* (*pMmGetVirtualForPhysical)(
PHYSICAL_ADDRESS PhysicalAddress
);
typedef
LONG_PTR (*pObfReferenceObject)(
void* Object
);
typedef
void (*pExFreePoolWithTag)(
void* P,
ULONG Tag
);
typedef
void* (*pExAllocatePool2)(
POOL_FLAGS Flags,
SIZE_T NumberOfBytes,
ULONG Tag
);
typedef
void (*pKeReleaseGuardedMutex)(
PKGUARDED_MUTEX GuardedMutex
);
typedef
void (*pKeAcquireGuardedMutex)(
PKGUARDED_MUTEX GuardedMutex
);
typedef
ULONG (*pDbgPrintEx)(
ULONG ComponentId,
ULONG Level,
PCSTR Format,
...
);
typedef
LONG (*pRtlCompareUnicodeString)(
PCUNICODE_STRING String1,
PCUNICODE_STRING String2,
BOOLEAN CaseInSensitive
);
typedef
PIO_STACK_LOCATION (*pIoGetCurrentIrpStackLocation)(
PIRP Irp
);
typedef
void (*pRtlFreeUnicodeString)(
PUNICODE_STRING UnicodeString
);
// clang-format on
typedef struct _DRIVER_IMPORTS
{
pObDereferenceObject DrvImpObDereferenceObject;
pIoGetCurrentIrpStackLocation DrvImpIoGetCurrentIrpStackLocation;
pPsLookupThreadByThreadId DrvImpPsLookupThreadByThreadId;
pMmIsAddressValid DrvImpMmIsAddressValid;
pPsSetCreateProcessNotifyRoutine DrvImpPsSetCreateProcessNotifyRoutine;
pPsRemoveCreateThreadNotifyRoutine DrvImpPsRemoveCreateThreadNotifyRoutine;
pPsGetCurrentThreadId DrvImpPsGetCurrentThreadId;
pPsGetProcessId DrvImpPsGetProcessId;
pPsLookupProcessByProcessId DrvImpPsLookupProcessByProcessId;
pExEnumHandleTable DrvImpExEnumHandleTable;
pObGetObjectType DrvImpObGetObjectType;
pExfUnblockPushLock DrvImpExfUnblockPushLock;
pPsGetProcessImageFileName DrvImpPsGetProcessImage;
pstrstr DrvImpstrstr;
pRtlInitUnicodeString DrvImpRtlInitUnicodeString;
pRtlQueryRegistryValues DrvImpRtlQueryRegistryValues;
pMmGetSystemRoutineAddress DrvImpMmGetSystemRoutineAddress;
pRtlUnicodeStringToAnsiString DrvImpRtlUnicodeStringToAnsiString;
pRtlCopyUnicodeString DrvImpRtlCopyUnicodeString;
pRtlFreeAnsiString DrvImpRtlFreeAnsiString;
pKeInitializeGuardedMutex DrvImpKeInitializeGuardedMutex;
pIoCreateDevice DrvImpIoCreateDevice;
pIoCreateSymbolicLink DrvImpIoCreateSymbolicLink;
pIoDeleteDevice DrvImpIoDeleteDevice;
pIoDeleteSymbolicLink DrvImpIoDeleteSymbolicLink;
pObRegisterCallbacks DrvImpObRegisterCallbacks;
pObUnRegisterCallbacks DrvImpObUnRegisterCallbacks;
pPsSetCreateThreadNotifyRoutine DrvImpPsSetCreateThreadNotifyRoutine;
pKeRevertToUserAffinityThreadEx DrvImpKeRevertToUserAffinityThreadEx;
pKeSetSystemAffinityThreadEx DrvImpKeSetSystemAffinityThreadEx;
pstrnlen DrvImpstrnlen;
pRtlInitAnsiString DrvImpRtlInitAnsiString;
pRtlAnsiStringToUnicodeString DrvImpRtlAnsiStringToUnicodeString;
pIoGetCurrentProcess DrvImpIoGetCurrentProcess;
pRtlGetVersion DrvImpRtlGetVersion;
pRtlCompareMemory DrvImpRtlCompareMemory;
pExGetSystemFirmwareTable DrvImpExGetSystemFirmwareTable;
pIoAllocateWorkItem DrvImpIoAllocateWorkItem;
pIoFreeWorkItem DrvImpIoFreeWorkItem;
pIoQueueWorkItem DrvImpIoQueueWorkItem;
pZwOpenFile DrvImpZwOpenFile;
pZwClose DrvImpZwClose;
pZwCreateSection DrvImpZwCreateSection;
pZwMapViewOfSection DrvImpZwMapViewOfSection;
pZwUnmapViewOfSection DrvImpZwUnmapViewOfSection;
pMmCopyMemory DrvImpMmCopyMemory;
pZwDeviceIoControlFile DrvImpZwDeviceIoControlFile;
pKeStackAttachProcess DrvImpKeStackAttachProcess;
pKeUnstackDetachProcess DrvImpKeUnstackDetachProcess;
pKeWaitForSingleObject DrvImpKeWaitForSingleObject;
pPsCreateSystemThread DrvImpPsCreateSystemThread;
pIofCompleteRequest DrvImpIofCompleteRequest;
pObReferenceObjectByHandle DrvImpObReferenceObjectByHandle;
pKeDelayExecutionThread DrvImpKeDelayExecutionThread;
pKeRegisterNmiCallback DrvImpKeRegisterNmiCallback;
pKeDeregisterNmiCallback DrvImpKeDeregisterNmiCallback;
pKeQueryActiveProcessorCount DrvImpKeQueryActiveProcessorCount;
pExAcquirePushLockExclusiveEx DrvImpExAcquirePushLockExclusiveEx;
pExReleasePushLockExclusiveEx DrvImpExReleasePushLockExclusiveEx;
pPsGetThreadId DrvImpPsGetThreadId;
pRtlCaptureStackBackTrace DrvImpRtlCaptureStackBackTrace;
pZwOpenDirectoryObject DrvImpZwOpenDirectoryObject;
pKeInitializeAffinityEx DrvImpKeInitializeAffinityEx;
pKeAddProcessorAffinityEx DrvImpKeAddProcessorAffinityEx;
pRtlQueryModuleInformation DrvImpRtlQueryModuleInformation;
pKeInitializeApc DrvImpKeInitializeApc;
pKeInsertQueueApc DrvImpKeInsertQueueApc;
pKeGenericCallDpc DrvImpKeGenericCallDpc;
pKeSignalCallDpcDone DrvImpKeSignalCallDpcDone;
pMmGetPhysicalMemoryRangesEx2 DrvImpMmGetPhysicalMemoryRangesEx2;
pMmGetVirtualForPhysical DrvImpMmGetVirtualForPhysical;
pObfReferenceObject DrvImpObfReferenceObject;
pExFreePoolWithTag DrvImpExFreePoolWithTag;
pExAllocatePool2 DrvImpExAllocatePool2;
pKeReleaseGuardedMutex DrvImpKeReleaseGuardedMutex;
pKeAcquireGuardedMutex DrvImpKeAcquireGuardedMutex;
pDbgPrintEx DrvImpDbgPrintEx;
pRtlCompareUnicodeString DrvImpRtlCompareUnicodeString;
pRtlFreeUnicodeString DrvImpRtlFreeUnicodeString;
pPsGetProcessImageFileName DrvImpPsGetProcessImageFileName;
} DRIVER_IMPORTS, *PDRIVER_IMPORTS;
extern PDRIVER_IMPORTS driver_imports;
#define DRVIMPORTS driver_imports
#define ImpIoGetCurrentIrpStackLocation DRVIMPORTS->DrvImpIoGetCurrentIrpStackLocation
#define ImpObDereferenceObject DRVIMPORTS->DrvImpObDereferenceObject
#define ImpPsLookupThreadByThreadId DRVIMPORTS->DrvImpPsLookupThreadByThreadId
#define ImpMmIsAddressValid DRVIMPORTS->DrvImpMmIsAddressValid
#define ImpPsSetCreateProcessNotifyRoutine DRVIMPORTS->DrvImpPsSetCreateProcessNotifyRoutine
#define ImpPsRemoveCreateThreadNotifyRoutine DRVIMPORTS->DrvImpPsRemoveCreateThreadNotifyRoutine
#define ImpPsGetCurrentThreadId DRVIMPORTS->DrvImpPsGetCurrentThreadId
#define ImpPsGetProcessId DRVIMPORTS->DrvImpPsGetProcessId
#define ImpPsLookupProcessByProcessId DRVIMPORTS->DrvImpPsLookupProcessByProcessId
#define ImpExEnumHandleTable DRVIMPORTS->DrvImpExEnumHandleTable
#define ImpObGetObjectType DRVIMPORTS->DrvImpObGetObjectType
#define ImpExfUnblockPushLock DRVIMPORTS->DrvImpExfUnblockPushLock
#define ImpPsGetProcessImageFileName DRVIMPORTS->DrvImpPsGetProcessImageFileName
#define Impstrstr DRVIMPORTS->DrvImpstrstr
#define ImpRtlInitUnicodeString DRVIMPORTS->DrvImpRtlInitUnicodeString
#define ImpRtlQueryRegistryValues DRVIMPORTS->DrvImpRtlQueryRegistryValues
#define ImpMmGetSystemRoutineAddress DRVIMPORTS->DrvImpMmGetSystemRoutineAddress
#define ImpRtlUnicodeStringToAnsiString DRVIMPORTS->DrvImpRtlUnicodeStringToAnsiString
#define ImpRtlCopyUnicodeString DRVIMPORTS->DrvImpRtlCopyUnicodeString
#define ImpRtlFreeAnsiString DRVIMPORTS->DrvImpRtlFreeAnsiString
#define ImpKeInitializeGuardedMutex DRVIMPORTS->DrvImpKeInitializeGuardedMutex
#define ImpIoCreateDevice DRVIMPORTS->DrvImpIoCreateDevice
#define ImpIoCreateSymbolicLink DRVIMPORTS->DrvImpIoCreateSymbolicLink
#define ImpIoDeleteDevice DRVIMPORTS->DrvImpIoDeleteDevice
#define ImpIoDeleteSymbolicLink DRVIMPORTS->DrvImpIoDeleteSymbolicLink
#define ImpObRegisterCallbacks DRVIMPORTS->DrvImpObRegisterCallbacks
#define ImpObUnRegisterCallbacks DRVIMPORTS->DrvImpObUnRegisterCallbacks
#define ImpPsSetCreateThreadNotifyRoutine DRVIMPORTS->DrvImpPsSetCreateThreadNotifyRoutine
#define ImpPsProcessType DRVIMPORTS->DrvImpPsProcessType
#define ImpKeRevertToUserAffinityThreadEx DRVIMPORTS->DrvImpKeRevertToUserAffinityThreadEx
#define ImpKeSetSystemAffinityThreadEx DRVIMPORTS->DrvImpKeSetSystemAffinityThreadEx
#define Impstrnlen DRVIMPORTS->DrvImpstrnlen
#define ImpRtlInitAnsiString DRVIMPORTS->DrvImpRtlInitAnsiString
#define ImpRtlAnsiStringToUnicodeString DRVIMPORTS->DrvImpRtlAnsiStringToUnicodeString
#define ImpIoGetCurrentProcess DRVIMPORTS->DrvImpIoGetCurrentProcess
#define ImpRtlGetVersion DRVIMPORTS->DrvImpRtlGetVersion
#define ImpRtlCompareMemory DRVIMPORTS->DrvImpRtlCompareMemory
#define ImpExGetSystemFirmwareTable DRVIMPORTS->DrvImpExGetSystemFirmwareTable
#define ImpIoAllocateWorkItem DRVIMPORTS->DrvImpIoAllocateWorkItem
#define ImpIoFreeWorkItem DRVIMPORTS->DrvImpIoFreeWorkItem
#define ImpIoQueueWorkItem DRVIMPORTS->DrvImpIoQueueWorkItem
#define ImpZwOpenFile DRVIMPORTS->DrvImpZwOpenFile
#define ImpZwClose DRVIMPORTS->DrvImpZwClose
#define ImpZwCreateSection DRVIMPORTS->DrvImpZwCreateSection
#define ImpZwMapViewOfSection DRVIMPORTS->DrvImpZwMapViewOfSection
#define ImpZwUnmapViewOfSection DRVIMPORTS->DrvImpZwUnmapViewOfSection
#define ImpMmCopyMemory DRVIMPORTS->DrvImpMmCopyMemory
#define ImpZwDeviceIoControlFile DRVIMPORTS->DrvImpZwDeviceIoControlFile
#define ImpKeStackAttachProcess DRVIMPORTS->DrvImpKeStackAttachProcess
#define ImpKeUnstackDetachProcess DRVIMPORTS->DrvImpKeUnstackDetachProcess
#define ImpKeWaitForSingleObject DRVIMPORTS->DrvImpKeWaitForSingleObject
#define ImpPsCreateSystemThread DRVIMPORTS->DrvImpPsCreateSystemThread
#define ImpIofCompleteRequest DRVIMPORTS->DrvImpIofCompleteRequest
#define ImpObReferenceObjectByHandle DRVIMPORTS->DrvImpObReferenceObjectByHandle
#define ImpPsThreadType DRVIMPORTS->DrvImpPsThreadType
#define ImpKeDelayExecutionThread DRVIMPORTS->DrvImpKeDelayExecutionThread
#define ImpKeRegisterNmiCallback DRVIMPORTS->DrvImpKeRegisterNmiCallback
#define ImpKeDeregisterNmiCallback DRVIMPORTS->DrvImpKeDeregisterNmiCallback
#define ImpKeQueryActiveProcessorCount DRVIMPORTS->DrvImpKeQueryActiveProcessorCount
#define ImpExAcquirePushLockExclusiveEx DRVIMPORTS->DrvImpExAcquirePushLockExclusiveEx
#define ImpExReleasePushLockExclusiveEx DRVIMPORTS->DrvImpExReleasePushLockExclusiveEx
#define ImpPsGetThreadId DRVIMPORTS->DrvImpPsGetThreadId
#define ImpRtlCaptureStackBackTrace DRVIMPORTS->DrvImpRtlCaptureStackBackTrace
#define ImpZwOpenDirectoryObject DRVIMPORTS->DrvImpZwOpenDirectoryObject
#define ImpKeInitializeAffinityEx DRVIMPORTS->DrvImpKeInitializeAffinityEx
#define ImpKeAddProcessorAffinityEx DRVIMPORTS->DrvImpKeAddProcessorAffinityEx
#define ImpRtlQueryModuleInformation DRVIMPORTS->DrvImpRtlQueryModuleInformation
#define ImpKeInitializeApc DRVIMPORTS->DrvImpKeInitializeApc
#define ImpKeInsertQueueApc DRVIMPORTS->DrvImpKeInsertQueueApc
#define ImpKeGenericCallDpc DRVIMPORTS->DrvImpKeGenericCallDpc
#define ImpKeSignalCallDpcDone DRVIMPORTS->DrvImpKeSignalCallDpcDone
#define ImpMmGetPhysicalMemoryRangesEx2 DRVIMPORTS->DrvImpMmGetPhysicalMemoryRangesEx2
#define ImpMmGetVirtualForPhysical DRVIMPORTS->DrvImpMmGetVirtualForPhysical
#define ImpObfReferenceObject DRVIMPORTS->DrvImpObfReferenceObject
#define ImpExFreePoolWithTag DRVIMPORTS->DrvImpExFreePoolWithTag
#define ImpExAllocatePool2 DRVIMPORTS->DrvImpExAllocatePool2
#define ImpKeReleaseGuardedMutex DRVIMPORTS->DrvImpKeReleaseGuardedMutex
#define ImpKeAcquireGuardedMutex DRVIMPORTS->DrvImpKeAcquireGuardedMutex
#define ImpDbgPrintEx DRVIMPORTS->DrvImpDbgPrintEx
#define ImpRtlCompareUnicodeString DRVIMPORTS->DrvImpRtlCompareUnicodeString
#define ImpRtlFreeUnicodeString DRVIMPORTS->DrvImpRtlFreeUnicodeString
#define ImpPsGetProcessImageFileName DRVIMPORTS->DrvImpPsGetProcessImageFileName
NTSTATUS
ResolveNtImports();
#endif

View file

@ -5,6 +5,7 @@
#include "modules.h"
#include "callbacks.h"
#include "ioctl.h"
#include "imports.h"
#include <bcrypt.h>
#include <initguid.h>
@ -141,7 +142,7 @@ GetDriverImageSize(_Inout_ PIRP Irp)
if (!driver_info)
{
DEBUG_ERROR("FindSystemModuleByName failed with no status code");
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return STATUS_NOT_FOUND;
}
@ -159,7 +160,7 @@ GetDriverImageSize(_Inout_ PIRP Irp)
end:
if (modules.address)
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return status;
}
@ -196,7 +197,7 @@ GetModuleInformationByName(_Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo, _In_ LPCS
if (!driver_info)
{
DEBUG_ERROR("FindSystemModuleByName failed with no status");
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return STATUS_NOT_FOUND;
}
@ -208,7 +209,7 @@ GetModuleInformationByName(_Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo, _In_ LPCS
ModuleInfo->FullPathName, driver_info->FullPathName, sizeof(ModuleInfo->FullPathName));
if (modules.address)
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return status;
}
@ -248,7 +249,7 @@ StoreModuleExecutableRegionsInBuffer(_Outptr_result_bytebuffer_(*BytesWritten) P
buffer_size = ModuleSize + sizeof(INTEGRITY_CHECK_HEADER);
*BytesWritten = 0;
*Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_INTEGRITY);
*Buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_INTEGRITY);
if (*Buffer == NULL)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -285,33 +286,33 @@ StoreModuleExecutableRegionsInBuffer(_Outptr_result_bytebuffer_(*BytesWritten) P
*/
address.VirtualAddress = section;
status = MmCopyMemory((UINT64)buffer_base + total_packet_size,
address,
sizeof(IMAGE_SECTION_HEADER),
MM_COPY_MEMORY_VIRTUAL,
&bytes_returned);
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size,
address,
sizeof(IMAGE_SECTION_HEADER),
MM_COPY_MEMORY_VIRTUAL,
&bytes_returned);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("MmCopyMemory failed with status %x", status);
ExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
*Buffer = NULL;
return status;
}
address.VirtualAddress = (UINT64)ModuleBase + section->PointerToRawData;
status = MmCopyMemory((UINT64)buffer_base + total_packet_size +
sizeof(IMAGE_SECTION_HEADER),
address,
section->SizeOfRawData,
MM_COPY_MEMORY_VIRTUAL,
&bytes_returned);
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size +
sizeof(IMAGE_SECTION_HEADER),
address,
section->SizeOfRawData,
MM_COPY_MEMORY_VIRTUAL,
&bytes_returned);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("MmCopyMemory failed with status %x", status);
ExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
*Buffer = NULL;
return status;
}
@ -350,12 +351,12 @@ MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE Sec
*Section = NULL;
*Size = 0;
RtlInitUnicodeString(&path, Path->Buffer);
ImpRtlInitUnicodeString(&path, Path->Buffer);
InitializeObjectAttributes(
&object_attributes, &path, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
InitializeObjectAttributes(&object_attributes, &path, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenFile(&file_handle, GENERIC_READ, &object_attributes, &pio_block, NULL, NULL);
status =
ImpZwOpenFile(&file_handle, GENERIC_READ, &object_attributes, &pio_block, NULL, NULL);
if (!NT_SUCCESS(status))
{
@ -369,22 +370,27 @@ MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE Sec
* Its important that we set the SEC_IMAGE flag with the PAGE_READONLY
* flag as we are mapping an executable image.
*/
status = ZwCreateSection(SectionHandle,
SECTION_ALL_ACCESS,
&object_attributes,
NULL,
PAGE_READONLY,
SEC_IMAGE,
file_handle);
status = ImpZwCreateSection(SectionHandle,
SECTION_ALL_ACCESS,
&object_attributes,
NULL,
PAGE_READONLY,
SEC_IMAGE,
file_handle);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ZwCreateSection failed with status %x", status);
ZwClose(file_handle);
ImpZwClose(file_handle);
*SectionHandle = NULL;
return status;
}
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectByHandle failed with status %x", status);
return status;
}
/*
* Mapping a section with the flag SEC_IMAGE (see function above) tells the os we
* are mapping an executable image. This then allows the OS to take care of parsing
@ -406,13 +412,13 @@ MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE Sec
{
/* caller is responsible for closing handle on success, therefore null it */
DEBUG_ERROR("ZwMapViewOfSection failed with status %x", status);
ZwClose(file_handle);
ZwClose(*SectionHandle);
ImpZwClose(file_handle);
ImpZwClose(*SectionHandle);
*SectionHandle = NULL;
return status;
}
ZwClose(file_handle);
ImpZwClose(file_handle);
return status;
}
@ -463,7 +469,7 @@ ComputeHashOfBuffer(_In_ PVOID Buffer,
goto end;
}
hash_object = ExAllocatePool2(POOL_FLAG_NON_PAGED, hash_object_size, POOL_TAG_INTEGRITY);
hash_object = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, hash_object_size, POOL_TAG_INTEGRITY);
if (!hash_object)
{
@ -489,7 +495,7 @@ ComputeHashOfBuffer(_In_ PVOID Buffer,
}
resulting_hash =
ExAllocatePool2(POOL_FLAG_NON_PAGED, resulting_hash_size, POOL_TAG_INTEGRITY);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, resulting_hash_size, POOL_TAG_INTEGRITY);
if (!resulting_hash)
{
@ -545,7 +551,7 @@ end:
BCryptDestroyHash(hash_handle);
if (hash_object)
ExFreePoolWithTag(hash_object, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(hash_object, POOL_TAG_INTEGRITY);
return status;
}
@ -601,7 +607,7 @@ RetrieveInMemoryModuleExecutableSections(_Inout_ PIRP Irp)
end:
if (buffer)
ExFreePoolWithTag(buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(buffer, POOL_TAG_INTEGRITY);
return status;
}
@ -733,7 +739,7 @@ ParseSMBIOSTable(_Out_ PVOID Buffer,
PSMBIOS_TABLE_HEADER smbios_table_header = NULL;
PRAW_SMBIOS_TABLE_01 smbios_baseboard_information = NULL;
status = ExGetSystemFirmwareTable(SMBIOS_TABLE, 0, NULL, 0, &firmware_table_buffer_size);
status = ImpExGetSystemFirmwareTable(SMBIOS_TABLE, 0, NULL, 0, &firmware_table_buffer_size);
/*
* Because we pass a null buffer here, the NTSTATUS result will be a BUFFER_TOO_SMALL error,
@ -747,12 +753,12 @@ ParseSMBIOSTable(_Out_ PVOID Buffer,
}
firmware_table_buffer =
ExAllocatePool2(POOL_FLAG_NON_PAGED, firmware_table_buffer_size, POOL_TAG_INTEGRITY);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, firmware_table_buffer_size, POOL_TAG_INTEGRITY);
if (!firmware_table_buffer)
return STATUS_MEMORY_NOT_ALLOCATED;
status = ExGetSystemFirmwareTable(
status = ImpExGetSystemFirmwareTable(
SMBIOS_TABLE, NULL, firmware_table_buffer, firmware_table_buffer_size, &bytes_returned);
if (!NT_SUCCESS(status))
@ -786,7 +792,7 @@ ParseSMBIOSTable(_Out_ PVOID Buffer,
end:
if (firmware_table_buffer)
ExFreePoolWithTag(firmware_table_buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(firmware_table_buffer, POOL_TAG_INTEGRITY);
return status;
}
@ -902,17 +908,17 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
module_info = (PPROCESS_MODULE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
GetProtectedProcessEProcess(&process);
RtlInitUnicodeString(&module_path, &module_info->module_path);
ImpRtlInitUnicodeString(&module_path, &module_info->module_path);
/*
* Attach because the offsets given are from the process' context.
*/
KeStackAttachProcess(process, &apc_state);
ImpKeStackAttachProcess(process, &apc_state);
status = StoreModuleExecutableRegionsInBuffer(
&memory_buffer, module_info->module_base, module_info->module_size, &bytes_written);
KeUnstackDetachProcess(&apc_state);
ImpKeUnstackDetachProcess(&apc_state);
if (!NT_SUCCESS(status))
{
@ -921,7 +927,7 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
}
status = MapDiskImageIntoVirtualAddressSpace(
&section_handle, &section, &module_path, &section_size);
&section_handle, &section, &module_path, &section_size, 0);
if (!NT_SUCCESS(status))
{
@ -957,10 +963,7 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
* We also don't need to send any module information since usermode has everything
* needed to file the report.
*/
if (CompareHashes(disk_hash, memory_hash, memory_hash_size))
validation_result.is_module_valid = TRUE;
else
validation_result.is_module_valid = FALSE;
validation_result.is_module_valid = CompareHashes(disk_hash, memory_hash, memory_hash_size);
status = ValidateIrpOutputBuffer(Irp, sizeof(PROCESS_MODULE_VALIDATION_RESULT));
@ -979,22 +982,22 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
end:
if (section_handle)
ZwClose(section_handle);
ImpZwClose(section_handle);
if (section)
ZwUnmapViewOfSection(ZwCurrentProcess(), section);
ImpZwUnmapViewOfSection(ZwCurrentProcess(), section);
if (memory_buffer)
ExFreePoolWithTag(memory_buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(memory_buffer, POOL_TAG_INTEGRITY);
if (memory_hash)
ExFreePoolWithTag(memory_hash, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(memory_hash, POOL_TAG_INTEGRITY);
if (disk_buffer)
ExFreePoolWithTag(disk_buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(disk_buffer, POOL_TAG_INTEGRITY);
if (disk_hash)
ExFreePoolWithTag(disk_hash, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(disk_hash, POOL_TAG_INTEGRITY);
return status;
}
@ -1019,7 +1022,7 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
PCHAR serial_number = NULL;
SIZE_T serial_length = 0;
RtlInitUnicodeString(&physical_drive_path, L"\\DosDevices\\PhysicalDrive0");
ImpRtlInitUnicodeString(&physical_drive_path, L"\\DosDevices\\PhysicalDrive0");
/*
* No need to use the flag OBJ_FORCE_ACCESS_CHECK since we arent passing a handle given
@ -1031,7 +1034,7 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
NULL,
NULL);
status = ZwOpenFile(&handle, GENERIC_READ, &attributes, &status_block, NULL, NULL);
status = ImpZwOpenFile(&handle, GENERIC_READ, &attributes, &status_block, NULL, NULL);
if (!NT_SUCCESS(status))
{
@ -1042,16 +1045,16 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
storage_property.PropertyId = StorageDeviceProperty;
storage_property.QueryType = PropertyStandardQuery;
status = ZwDeviceIoControlFile(handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
&storage_property,
sizeof(STORAGE_PROPERTY_QUERY),
&storage_descriptor_header,
sizeof(STORAGE_DESCRIPTOR_HEADER));
status = ImpZwDeviceIoControlFile(handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
&storage_property,
sizeof(STORAGE_PROPERTY_QUERY),
&storage_descriptor_header,
sizeof(STORAGE_DESCRIPTOR_HEADER));
if (!NT_SUCCESS(status))
{
@ -1059,7 +1062,7 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
goto end;
}
device_descriptor = ExAllocatePool2(
device_descriptor = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, storage_descriptor_header.Size, POOL_TAG_INTEGRITY);
if (!device_descriptor)
@ -1068,16 +1071,16 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
goto end;
}
status = ZwDeviceIoControlFile(handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
&storage_property,
sizeof(STORAGE_PROPERTY_QUERY),
device_descriptor,
storage_descriptor_header.Size);
status = ImpZwDeviceIoControlFile(handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
&storage_property,
sizeof(STORAGE_PROPERTY_QUERY),
device_descriptor,
storage_descriptor_header.Size);
if (!NT_SUCCESS(status))
{
@ -1106,10 +1109,10 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T Confi
end:
if (handle)
ZwClose(handle);
ImpZwClose(handle);
if (device_descriptor)
ExFreePoolWithTag(device_descriptor, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(device_descriptor, POOL_TAG_INTEGRITY);
return status;
}
@ -1139,7 +1142,7 @@ end:
//
// if ( !NT_SUCCESS( status ) )
// {
// DEBUG_LOG( "IoGetDeviceInterfaces failed with status %x", status );
// DEBUG_VERBOSE( "IoGetDeviceInterfaces failed with status %x", status );
// return;
// }
//
@ -1153,12 +1156,12 @@ end:
// symbolic_link.Length = string_length;
// symbolic_link.MaximumLength = string_length;
//
// DEBUG_LOG( "Device Interface: %wZ", symbolic_link );
// DEBUG_VERBOSE( "Device Interface: %wZ", symbolic_link );
//
// current_string += symbolic_link.Length + 1;
// }
//
// ExFreePoolWithTag( device_interfaces, NULL );
// ImpExFreePoolWithTag( device_interfaces, NULL );
// }
PVOID
@ -1310,8 +1313,8 @@ InitiateEptFunctionAddressArrays()
for (INT index = 0; index < EPT_CONTROL_FUNCTIONS_COUNT; index++)
{
RtlInitUnicodeString(&current_function, CONTROL_FUNCTIONS[index]);
CONTROL_FUNCTION_ADDRESSES[index] = MmGetSystemRoutineAddress(&current_function);
ImpRtlInitUnicodeString(&current_function, CONTROL_FUNCTIONS[index]);
CONTROL_FUNCTION_ADDRESSES[index] = ImpMmGetSystemRoutineAddress(&current_function);
if (!CONTROL_FUNCTION_ADDRESSES[index])
return STATUS_UNSUCCESSFUL;
@ -1319,8 +1322,9 @@ InitiateEptFunctionAddressArrays()
for (INT index = 0; index < EPT_PROTECTED_FUNCTIONS_COUNT; index++)
{
RtlInitUnicodeString(&current_function, CONTROL_FUNCTIONS[index]);
PROTECTED_FUNCTION_ADDRESSES[index] = MmGetSystemRoutineAddress(&current_function);
ImpRtlInitUnicodeString(&current_function, CONTROL_FUNCTIONS[index]);
PROTECTED_FUNCTION_ADDRESSES[index] =
ImpMmGetSystemRoutineAddress(&current_function);
if (!PROTECTED_FUNCTION_ADDRESSES[index])
return STATUS_UNSUCCESSFUL;
@ -1340,6 +1344,8 @@ DetectEptHooksInKeyFunctions()
UINT64 control_time_sum = 0;
UINT64 control_average = 0;
/* todo: once we call this, we need to set a flag to skip this, otherwise we just return
* early */
status = InitiateEptFunctionAddressArrays();
if (!NT_SUCCESS(status))
@ -1369,7 +1375,7 @@ DetectEptHooksInKeyFunctions()
control_average = control_time_sum / (EPT_CONTROL_FUNCTIONS_COUNT - control_fails);
if (control_average == 0)
return STATUS_ABANDONED;
return STATUS_UNSUCCESSFUL;
for (INT index = 0; index < EPT_PROTECTED_FUNCTIONS_COUNT; index++)
{
@ -1413,7 +1419,7 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context)
if (!Context)
return;
process_name = PsGetProcessImageFileName(Entry->process);
process_name = ImpPsGetProcessImageFileName(Entry->process);
if (!strcmp(process_name, "winlogon.exe"))
{
@ -1423,23 +1429,12 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context)
}
}
/*
* Validate .rdata and other read only/executable sections etc.
*/
STATIC
VOID
ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
NTSTATUS
HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
ANSI_STRING ansi_string = {0};
UNICODE_STRING path = {0};
ULONG section_size = 0;
HANDLE section_handle = NULL;
PVOID section = NULL;
PVAL_INTEGRITY_HEADER disk_buffer = NULL;
ULONG disk_buffer_size = 0;
PVOID disk_hash = NULL;
ULONG disk_hash_size = 0;
ULONG memory_text_size = 0;
PVOID memory_hash = NULL;
ULONG memory_hash_size = 0;
@ -1448,7 +1443,7 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
PEPROCESS process = NULL;
KAPC_STATE apc_state = {0};
RtlInitAnsiString(&ansi_string, Module->FullPathName);
ImpRtlInitAnsiString(&ansi_string, Module->FullPathName);
if (!ansi_string.Buffer)
{
@ -1456,7 +1451,7 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
return;
}
status = RtlAnsiStringToUnicodeString(&path, &ansi_string, TRUE);
status = ImpRtlAnsiStringToUnicodeString(&path, &ansi_string, TRUE);
if (!NT_SUCCESS(status))
{
@ -1464,24 +1459,6 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
goto end;
}
status =
MapDiskImageIntoVirtualAddressSpace(&section_handle, &section, &path, &section_size);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("MapDiskImageIntoVirtualAddressSpace failed with status %x", status);
goto end;
}
status = StoreModuleExecutableRegionsInBuffer(
(PVOID)&disk_buffer, section, section_size, &disk_buffer_size);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("StoreModuleExecutableRegionsInBuffer failed with status %x", status);
goto end;
}
/*
* For win32k and related modules, because they are 32bit for us to read the
* memory we need to attach to a 32 bit process. A simple check is that the
@ -1489,23 +1466,25 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
* Then we simply attach to a 32 bit address space, in our case winlogon,
* which will allow us to perform the copy.
*/
if (!MmIsAddressValid(Module->ImageBase))
if (!ImpMmIsAddressValid(Module->ImageBase))
{
DEBUG_VERBOSE("Win32k related module found, acquiring 32 bit address space...");
// DEBUG_VERBOSE("Win32k related module found, acquiring 32 bit address space...");
EnumerateProcessListWithCallbackRoutine(FindWinLogonProcess, &process);
// EnumerateProcessListWithCallbackRoutine(FindWinLogonProcess, &process);
if (!process)
goto end;
// if (!process)
// goto end;
KeStackAttachProcess(process, &apc_state);
// ImpKeStackAttachProcess(process, &apc_state);
status = StoreModuleExecutableRegionsInBuffer((PVOID)&memory_buffer,
Module->ImageBase,
Module->ImageSize,
&memory_buffer_size);
// status = StoreModuleExecutableRegionsInBuffer((PVOID)&memory_buffer,
// Module->ImageBase,
// Module->ImageSize,
// &memory_buffer_size);
KeUnstackDetachProcess(&apc_state);
// ImpKeUnstackDetachProcess(&apc_state);
status = STATUS_INVALID_IMAGE_WIN_32;
goto end;
}
else
{
@ -1521,12 +1500,10 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
goto end;
}
status = ComputeHashOfSections(&memory_buffer->section_header,
&disk_buffer->section_header,
&disk_hash,
&disk_hash_size,
&memory_hash,
&memory_hash_size);
status = ComputeHashOfBuffer(memory_buffer->section_base,
memory_buffer->section_header.SizeOfRawData,
&memory_hash,
&memory_hash_size);
if (!NT_SUCCESS(status))
{
@ -1534,53 +1511,80 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
goto end;
}
/*
* Since we don't pass a return value, I think we would raise an invalid module error and
* stop the users game session ? since module .text section error would be a large red flag
*/
if (CompareHashes(disk_hash, memory_hash, memory_hash_size))
DEBUG_VERBOSE("thread: %lx, section: %s is valid for module: %s",
PsGetCurrentThreadId(),
memory_buffer->section_header.Name,
Module->FullPathName);
else
DEBUG_WARNING("thread: %lx, section: %s is not valid for module: %s",
PsGetCurrentThreadId(),
memory_buffer->section_header.Name,
Module->FullPathName);
RtlCopyMemory(Hash, memory_hash, memory_hash_size);
end:
if (memory_buffer)
ExFreePoolWithTag(memory_buffer, POOL_TAG_INTEGRITY);
if (disk_buffer)
ExFreePoolWithTag(disk_buffer, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(memory_buffer, POOL_TAG_INTEGRITY);
if (memory_hash)
ExFreePoolWithTag(memory_hash, POOL_TAG_INTEGRITY);
if (disk_hash)
ExFreePoolWithTag(disk_hash, POOL_TAG_INTEGRITY);
if (section_handle)
ZwClose(section_handle);
if (section)
ZwUnmapViewOfSection(ZwCurrentProcess(), section);
ImpExFreePoolWithTag(memory_hash, POOL_TAG_INTEGRITY);
if (path.Buffer)
RtlFreeUnicodeString(&path);
ImpRtlFreeUnicodeString(&path);
return status;
}
VOID
ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDRIVER_LIST_ENTRY entry = NULL;
PVOID hash = NULL;
hash = ExAllocatePool2(POOL_FLAG_NON_PAGED, 32, POOL_TAG_INTEGRITY);
if (!hash)
return;
FindDriverEntryByBaseAddress(Module->ImageBase, &entry);
if (!entry)
{
DEBUG_ERROR("FindDriverEntryByBaseAddress failed with no status");
goto end;
}
status = HashModule(Module, hash);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("HashModule failed with status %x", status);
goto end;
}
if (CompareHashes(hash, entry->text_hash, sizeof(entry->text_hash)))
DEBUG_VERBOSE("Module: %s text regions are valid.", Module->FullPathName);
else
DEBUG_WARNING("**!!** Module: %s text regions are not valid **!!**", Module->FullPathName);
end:
if (hash)
ExFreePoolWithTag(hash, POOL_TAG_INTEGRITY);
}
NTSTATUS
ValidateOurDriverImage()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
LPCSTR driver_name = NULL;
UNICODE_STRING path = {0};
SYSTEM_MODULES modules = {0};
PRTL_MODULE_EXTENDED_INFO module_info = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
LPCSTR driver_name = NULL;
UNICODE_STRING path = {0};
SYSTEM_MODULES modules = {0};
PRTL_MODULE_EXTENDED_INFO module_info = NULL;
PVOID section = NULL;
HANDLE section_handle = NULL;
ULONG section_size = 0;
PVAL_INTEGRITY_HEADER disk_buffer = NULL;
ULONG disk_buffer_size = 0;
PVOID disk_hash = NULL;
ULONG disk_hash_size = 0;
ULONG memory_text_size = 0;
PVOID memory_hash = NULL;
ULONG memory_hash_size = 0;
PVAL_INTEGRITY_HEADER memory_buffer = NULL;
ULONG memory_buffer_size = 0;
GetDriverPath(&path);
GetDriverName(&driver_name);
@ -1607,9 +1611,77 @@ ValidateOurDriverImage()
goto end;
}
ValidateSystemModule(module_info);
/* here we need to map our disk image, like the previous integ checks */
status =
MapDiskImageIntoVirtualAddressSpace(&section_handle, &section, &path, &section_size);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("MapDiskImageIntoVirtualAddressSpace failed with status %x", status);
goto end;
}
status = StoreModuleExecutableRegionsInBuffer(
(PVOID)&disk_buffer, section, section_size, &disk_buffer_size);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("StoreModuleExecutableRegionsInBuffer failed with status %x", status);
goto end;
}
status = StoreModuleExecutableRegionsInBuffer((PVOID)&memory_buffer,
module_info->ImageBase,
module_info->ImageSize,
&memory_buffer_size);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("StoreModuleExecutableRegionsInBuffer 2 failed with status %x", status);
goto end;
}
status = ComputeHashOfSections(&memory_buffer->section_header,
&disk_buffer->section_header,
&disk_hash,
&disk_hash_size,
&memory_hash,
&memory_hash_size);
if (!NT_SUCCESS(status))
{
DEBUG_VERBOSE("ComputeHashOfSections failed with status %x", status);
goto end;
}
/*
* Since we don't pass a return value, I think we would raise an invalid module error and
* stop the users game session ? since module .text section error would be a large red flag
*/
if (CompareHashes(disk_hash, memory_hash, memory_hash_size))
DEBUG_VERBOSE("Driver image is valid. Integrity check complete");
else
DEBUG_WARNING("Drive image is NOT valid. !!!");
end:
if (memory_buffer)
ExFreePoolWithTag(memory_buffer, POOL_TAG_INTEGRITY);
if (disk_buffer)
ExFreePoolWithTag(disk_buffer, POOL_TAG_INTEGRITY);
if (memory_hash)
ExFreePoolWithTag(memory_hash, POOL_TAG_INTEGRITY);
if (disk_hash)
ExFreePoolWithTag(disk_hash, POOL_TAG_INTEGRITY);
if (section_handle)
ZwClose(section_handle);
if (section)
ZwUnmapViewOfSection(ZwCurrentProcess(), section);
if (modules.address)
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
@ -1670,12 +1742,15 @@ InitialiseSystemModuleVerificationContext(PSYS_MODULE_VAL_CONTEXT Context)
return status;
}
dispatcher_array = ExAllocatePool2(POOL_FLAG_NON_PAGED,
modules.module_count * sizeof(MODULE_DISPATCHER_HEADER),
POOL_TAG_INTEGRITY);
DEBUG_VERBOSE("driver count: %lx", modules.module_count);
dispatcher_array =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
modules.module_count * sizeof(MODULE_DISPATCHER_HEADER),
POOL_TAG_INTEGRITY);
if (!dispatcher_array)
{
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@ -1700,8 +1775,8 @@ FreeWorkItems(_In_ PSYS_MODULE_VAL_CONTEXT Context)
{
if (Context->work_items[index])
{
IoFreeWorkItem(Context->work_items[index]);
Context->work_items[index] = 0ull;
ImpIoFreeWorkItem(Context->work_items[index]);
Context->work_items[index] = NULL;
}
}
}
@ -1716,19 +1791,22 @@ FreeModuleVerificationItems(_In_ PSYS_MODULE_VAL_CONTEXT Context)
YieldProcessor();
if (Context->module_info)
ExFreePoolWithTag(Context->module_info, SYSTEM_MODULES_POOL);
{
ImpExFreePoolWithTag(Context->module_info, SYSTEM_MODULES_POOL);
Context->module_info = NULL;
}
if (Context->dispatcher_info)
ExFreePoolWithTag(Context->dispatcher_info, POOL_TAG_INTEGRITY);
{
ImpExFreePoolWithTag(Context->dispatcher_info, POOL_TAG_INTEGRITY);
Context->dispatcher_info = NULL;
}
}
VOID
CleanupValidationContextOnUnload(_In_ PSYS_MODULE_VAL_CONTEXT Context)
{
/* again.. maybe not the best idea? todo: think */
while (Context->active_thread_count)
YieldProcessor();
Context->active = FALSE;
Context->active = FALSE;
Context->complete = TRUE;
FreeWorkItems(Context);
FreeModuleVerificationItems(Context);
@ -1774,12 +1852,12 @@ SystemModuleVerificationDispatcher()
for (INT index = 0; index < VERIFICATION_THREAD_COUNT; index++)
{
work_item = IoAllocateWorkItem(GetDriverDeviceObject());
work_item = ImpIoAllocateWorkItem(GetDriverDeviceObject());
if (!work_item)
continue;
IoQueueWorkItem(
ImpIoQueueWorkItem(
work_item, SystemModuleVerificationDispatchFunction, DelayedWorkQueue, context);
context->work_items[index] = work_item;
@ -1799,7 +1877,7 @@ GetOsVersionInformation(_Out_ PRTL_OSVERSIONINFOW VersionInfo)
if (!VersionInfo)
return STATUS_INVALID_PARAMETER;
status = RtlGetVersion(&info);
status = ImpRtlGetVersion(&info);
if (!NT_SUCCESS(status))
{
@ -1817,4 +1895,36 @@ GetOsVersionInformation(_Out_ PRTL_OSVERSIONINFOW VersionInfo)
VersionInfo->szCSDVersion, info.szCSDVersion, sizeof(VersionInfo->szCSDVersion));
return status;
}
#define KPCR_KPRCB_OFFSET 0x180
#define KPCRB_IDLE_THREAD_OFFSET 0x018
#define KTHREAD_IDLE_TIME_OFFSET 0x28c
#define KPCRB_KERNEL_TIME_OFFSET 0x7e84
#define KPCRB_USER_TIME_OFFSET 0x7e88
UINT32
CalculateCpuCoreUsage(_In_ UINT32 Core)
{
PVOID kpcr = NULL;
PVOID kpcrb = NULL;
PVOID idle_thread = NULL;
UINT32 idle_time = 0;
UINT32 kernel_time = 0;
UINT32 user_time = 0;
KeSetSystemAffinityThread(1ull << Core);
while (Core != KeGetCurrentProcessorNumber())
YieldProcessor();
kpcr = __readmsr(IA32_GS_BASE);
kpcrb = (UINT64)kpcr + KPCR_KPRCB_OFFSET;
idle_thread = *(UINT64*)((UINT64)kpcrb + KPCRB_IDLE_THREAD_OFFSET);
idle_time = *(UINT32*)((UINT64)idle_thread + KTHREAD_IDLE_TIME_OFFSET);
kernel_time = *(UINT32*)((UINT64)kpcrb + KPCRB_KERNEL_TIME_OFFSET);
user_time = *(UINT32*)((UINT64)kpcrb + KPCRB_USER_TIME_OFFSET);
return (100 - (UINT32)(UInt32x32To64(idle_time, 100) / (UINT64)(kernel_time + user_time)));
}

View file

@ -106,9 +106,6 @@ ScanForSignature(_In_ PVOID BaseAddress,
// _Inout_ PBOOLEAN Result
//);
NTSTATUS
ValidateSystemModules();
NTSTATUS
ValidateNtoskrnl();
@ -124,4 +121,13 @@ ValidateOurDriverImage();
VOID
CleanupValidationContextOnUnload(_In_ PSYS_MODULE_VAL_CONTEXT Context);
UINT32
CalculateCpuCoreUsage(_In_ UINT32 Core);
NTSTATUS
HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash);
VOID
ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module);
#endif

View file

@ -8,6 +8,7 @@
#include "thread.h"
#include "queue.h"
#include "hv.h"
#include "imports.h"
STATIC
NTSTATUS
@ -114,7 +115,7 @@ ValidateIrpOutputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize)
PIO_STACK_LOCATION io = IoGetCurrentIrpStackLocation(Irp);
if (!io)
return STATUS_ABANDONED;
return STATUS_UNSUCCESSFUL;
if (io->Parameters.DeviceIoControl.OutputBufferLength < RequiredSize)
return STATUS_BUFFER_TOO_SMALL;
@ -139,7 +140,7 @@ ValidateIrpInputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize)
PIO_STACK_LOCATION io = IoGetCurrentIrpStackLocation(Irp);
if (!io)
return STATUS_ABANDONED;
return STATUS_UNSUCCESSFUL;
if (io->Parameters.DeviceIoControl.InputBufferLength != RequiredSize)
return STATUS_INVALID_BUFFER_SIZE;
@ -197,7 +198,7 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
* it will issue a bug check under windows driver verifier.
*/
status = PsCreateSystemThread(
status = ImpPsCreateSystemThread(
&handle, PROCESS_ALL_ACCESS, NULL, NULL, NULL, HandleValidateDriversIOCTL, Irp);
if (!NT_SUCCESS(status))
@ -212,35 +213,35 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
* us to wait til our threads terminated and the IRP buffer has been either filled
* or left empty and then from there we can complete the IRP and return.
*/
status = ObReferenceObjectByHandle(
status = ImpObReferenceObjectByHandle(
handle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &thread, NULL);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectbyhandle failed with status %lx", status);
ZwClose(handle);
DEBUG_ERROR("ObReferenceObjectByHandle failed with status %lx", status);
ImpZwClose(handle);
goto end;
}
KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
ImpKeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
ZwClose(handle);
ObDereferenceObject(thread);
ImpZwClose(handle);
ImpObDereferenceObject(thread);
break;
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH:;
DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH Received");
status = ProcLoadInitialiseProcessConfig(Irp);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("InitialiseProcessConfig failed with status %x", status);
goto end;
}
status = ProcLoadEnableObCallbacks();
if (!NT_SUCCESS(status))
@ -290,7 +291,7 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
DEBUG_VERBOSE("IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS Received");
status = PsCreateSystemThread(&handle,
status = ImpPsCreateSystemThread(&handle,
PROCESS_ALL_ACCESS,
NULL,
NULL,
@ -304,20 +305,20 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
goto end;
}
status = ObReferenceObjectByHandle(
status = ImpObReferenceObjectByHandle(
handle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &thread, NULL);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectbyhandle failed with status %lx", status);
ZwClose(handle);
ImpZwClose(handle);
goto end;
}
KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
ImpKeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
ZwClose(handle);
ObDereferenceObject(thread);
ImpZwClose(handle);
ImpObDereferenceObject(thread);
break;

View file

@ -4,6 +4,7 @@
#include "driver.h"
#include "ioctl.h"
#include "ia32.h"
#include "imports.h"
#include "thread.h"
@ -344,7 +345,7 @@ AddDriverToList(_Inout_ PINVALID_DRIVERS_HEAD InvalidDriversHead,
{
PAGED_CODE();
PINVALID_DRIVER new_entry = ExAllocatePool2(
PINVALID_DRIVER new_entry = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(INVALID_DRIVER), INVALID_DRIVER_LIST_ENTRY_POOL);
if (!new_entry)
@ -368,7 +369,7 @@ RemoveInvalidDriverFromList(_Inout_ PINVALID_DRIVERS_HEAD InvalidDriversHead)
{
PINVALID_DRIVER entry = InvalidDriversHead->first_entry;
InvalidDriversHead->first_entry = InvalidDriversHead->first_entry->next;
ExFreePoolWithTag(entry, INVALID_DRIVER_LIST_ENTRY_POOL);
ImpExFreePoolWithTag(entry, INVALID_DRIVER_LIST_ENTRY_POOL);
}
}
@ -456,8 +457,8 @@ GetSystemModuleInformation(_Out_ PSYSTEM_MODULES ModuleInformation)
}
/* Query the modules again this time passing a pointer to the allocated buffer */
status =
RtlQueryModuleInformation(&size, sizeof(RTL_MODULE_EXTENDED_INFO), driver_information);
status = RtlQueryModuleInformation(
&size, sizeof(RTL_MODULE_EXTENDED_INFO), driver_information);
if (!NT_SUCCESS(status))
{
@ -493,11 +494,11 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES SystemModules,
NTSTATUS status = STATUS_UNSUCCESSFUL;
POBJECT_DIRECTORY directory_object = NULL;
RtlInitUnicodeString(&directory_name, L"\\Driver");
ImpRtlInitUnicodeString(&directory_name, L"\\Driver");
InitializeObjectAttributes(&attributes, &directory_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenDirectoryObject(&handle, DIRECTORY_ALL_ACCESS, &attributes);
status = ImpZwOpenDirectoryObject(&handle, DIRECTORY_ALL_ACCESS, &attributes);
if (!NT_SUCCESS(status))
{
@ -505,13 +506,13 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES SystemModules,
return status;
}
status = ObReferenceObjectByHandle(
status = ImpObReferenceObjectByHandle(
handle, DIRECTORY_ALL_ACCESS, NULL, KernelMode, &directory, NULL);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectByHandle failed with status %x", status);
ZwClose(handle);
ImpZwClose(handle);
return status;
}
@ -530,10 +531,10 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES SystemModules,
directory_object = (POBJECT_DIRECTORY)directory;
ExAcquirePushLockExclusiveEx(&directory_object->Lock, NULL);
ImpExAcquirePushLockExclusiveEx(&directory_object->Lock, NULL);
whitelisted_regions_buffer =
ExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE,
WHITELISTED_MODULE_TAG);
@ -620,11 +621,11 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES SystemModules,
end:
if (whitelisted_regions_buffer)
ExFreePoolWithTag(whitelisted_regions_buffer, WHITELISTED_MODULE_TAG);
ImpExFreePoolWithTag(whitelisted_regions_buffer, WHITELISTED_MODULE_TAG);
ExReleasePushLockExclusiveEx(&directory_object->Lock, 0);
ObDereferenceObject(directory);
ZwClose(handle);
ImpExReleasePushLockExclusiveEx(&directory_object->Lock, 0);
ImpObDereferenceObject(directory);
ImpZwClose(handle);
return STATUS_SUCCESS;
}
@ -652,12 +653,12 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
return status;
}
head = ExAllocatePool2(
head = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(INVALID_DRIVERS_HEAD), INVALID_DRIVER_LIST_HEAD_POOL);
if (!head)
{
ExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@ -697,12 +698,12 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
goto end;
}
buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, MODULES_REPORT_POOL_TAG);
buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, MODULES_REPORT_POOL_TAG);
if (!buffer)
{
ExFreePoolWithTag(head, INVALID_DRIVER_LIST_HEAD_POOL);
ExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(head, INVALID_DRIVER_LIST_HEAD_POOL);
ImpExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@ -732,7 +733,7 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
string.MaximumLength = MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE;
string.Buffer = &report.driver_name;
status = RtlUnicodeStringToAnsiString(
status = ImpRtlUnicodeStringToAnsiString(
&string, &head->first_entry->driver->DriverName, FALSE);
/* still continue if we fail to get the driver name */
@ -754,7 +755,7 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT *
sizeof(MODULE_VALIDATION_FAILURE));
ExFreePoolWithTag(buffer, MODULES_REPORT_POOL_TAG);
ImpExFreePoolWithTag(buffer, MODULES_REPORT_POOL_TAG);
}
else
{
@ -762,8 +763,8 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
}
end:
ExFreePoolWithTag(head, INVALID_DRIVER_LIST_HEAD_POOL);
ExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(head, INVALID_DRIVER_LIST_HEAD_POOL);
ImpExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
return status;
}
@ -841,8 +842,8 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES SystemModules,
if (!NmiContext || !SystemModules)
return STATUS_INVALID_PARAMETER;
for (INT core = 0; core < KeQueryActiveProcessorCount(0); core++)
for (INT core = 0; core < ImpKeQueryActiveProcessorCount(0); core++)
{
/* Make sure our NMIs were run */
if (!NmiContext[core].callback_count)
@ -898,7 +899,7 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES SystemModules,
NmiContext[core].kthread);
PHIDDEN_SYSTEM_THREAD_REPORT report =
ExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(HIDDEN_SYSTEM_THREAD_REPORT),
REPORT_POOL_TAG);
@ -908,7 +909,7 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES SystemModules,
report->report_code = REPORT_HIDDEN_SYSTEM_THREAD;
report->found_in_kthreadlist = FALSE; // wip
report->found_in_pspcidtable = FALSE;
report->thread_id = PsGetThreadId(NmiContext[core].kthread);
report->thread_id = ImpPsGetThreadId(NmiContext[core].kthread);
report->thread_address = NmiContext[core].kthread;
RtlCopyMemory(
@ -1028,7 +1029,7 @@ LaunchNonMaskableInterrupt()
PAGED_CODE();
PKAFFINITY_EX ProcAffinityPool =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAFFINITY_EX), PROC_AFFINITY_POOL);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAFFINITY_EX), PROC_AFFINITY_POOL);
if (!ProcAffinityPool)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -1036,10 +1037,10 @@ LaunchNonMaskableInterrupt()
LARGE_INTEGER delay = {0};
delay.QuadPart -= NMI_DELAY_TIME;
for (ULONG core = 0; core < KeQueryActiveProcessorCount(0); core++)
for (ULONG core = 0; core < ImpKeQueryActiveProcessorCount(0); core++)
{
KeInitializeAffinityEx(ProcAffinityPool);
KeAddProcessorAffinityEx(ProcAffinityPool, core);
ImpKeInitializeAffinityEx(ProcAffinityPool);
ImpKeAddProcessorAffinityEx(ProcAffinityPool, core);
DEBUG_VERBOSE("Sending NMI");
HalSendNMI(ProcAffinityPool);
@ -1048,10 +1049,10 @@ LaunchNonMaskableInterrupt()
* Only a single NMI can be active at any given time, so arbitrarily
* delay execution to allow time for the NMI to be processed
*/
KeDelayExecutionThread(KernelMode, FALSE, &delay);
ImpKeDelayExecutionThread(KernelMode, FALSE, &delay);
}
ExFreePoolWithTag(ProcAffinityPool, PROC_AFFINITY_POOL);
ImpExFreePoolWithTag(ProcAffinityPool, PROC_AFFINITY_POOL);
return STATUS_SUCCESS;
}
@ -1072,8 +1073,8 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateHalDispatchTables failed with status %x", status);
nmi_context = ExAllocatePool2(POOL_FLAG_NON_PAGED,
KeQueryActiveProcessorCount(0) * sizeof(NMI_CONTEXT),
nmi_context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpKeQueryActiveProcessorCount(0) * sizeof(NMI_CONTEXT),
NMI_CONTEXT_POOL);
if (!nmi_context)
@ -1083,12 +1084,12 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
* We want to register and unregister our callback each time so it becomes harder
* for people to hook our callback and get up to some funny business
*/
callback_handle = KeRegisterNmiCallback(NmiCallback, nmi_context);
callback_handle = ImpKeRegisterNmiCallback(NmiCallback, nmi_context);
if (!callback_handle)
{
DEBUG_ERROR("KeRegisterNmiCallback failed with no status.");
ExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
ImpExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
return STATUS_UNSUCCESSFUL;
}
@ -1100,8 +1101,8 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
if (!NT_SUCCESS(status))
{
KeDeregisterNmiCallback(callback_handle);
ExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
ImpKeDeregisterNmiCallback(callback_handle);
ImpExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
DEBUG_ERROR("Error retriving system module information");
return status;
}
@ -1111,9 +1112,9 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("Error running NMI callbacks");
KeDeregisterNmiCallback(callback_handle);
ExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
ImpKeDeregisterNmiCallback(callback_handle);
ImpExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
return status;
}
@ -1122,9 +1123,9 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
if (!NT_SUCCESS(status))
DEBUG_ERROR("Error analysing nmi data");
ExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
KeDeregisterNmiCallback(callback_handle);
ImpExFreePoolWithTag(system_modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(nmi_context, NMI_CONTEXT_POOL);
ImpKeDeregisterNmiCallback(callback_handle);
return status;
}
@ -1173,13 +1174,13 @@ ApcKernelRoutine(_In_ PRKAPC Apc,
if (!thread_list_entry)
return;
buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, STACK_FRAME_POOL_SIZE, POOL_TAG_APC);
buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, STACK_FRAME_POOL_SIZE, POOL_TAG_APC);
if (!buffer)
goto free;
frames_captured =
RtlCaptureStackBackTrace(NULL, STACK_FRAME_POOL_SIZE / sizeof(UINT64), buffer, NULL);
ImpRtlCaptureStackBackTrace(NULL, STACK_FRAME_POOL_SIZE / sizeof(UINT64), buffer, NULL);
if (!frames_captured)
goto free;
@ -1203,7 +1204,7 @@ ApcKernelRoutine(_In_ PRKAPC Apc,
if (flag == FALSE)
{
PAPC_STACKWALK_REPORT report = ExAllocatePool2(
PAPC_STACKWALK_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(APC_STACKWALK_REPORT), POOL_TAG_APC);
if (!report)
@ -1224,7 +1225,7 @@ ApcKernelRoutine(_In_ PRKAPC Apc,
free:
if (buffer)
ExFreePoolWithTag(buffer, POOL_TAG_APC);
ImpExFreePoolWithTag(buffer, POOL_TAG_APC);
FreeApcAndDecrementApcCount(Apc, APC_CONTEXT_ID_STACKWALK);
@ -1278,7 +1279,7 @@ ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
PUCHAR state = NULL;
BOOLEAN apc_queueable = FALSE;
PAPC_STACKWALK_CONTEXT context = (PAPC_STACKWALK_CONTEXT)Context;
LPCSTR process_name = PsGetProcessImageFileName(ThreadListEntry->owning_process);
LPCSTR process_name = ImpPsGetProcessImageFileName(ThreadListEntry->owning_process);
/*
* we dont want to schedule an apc to threads owned by the kernel
@ -1329,12 +1330,12 @@ ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
FlipKThreadMiscFlagsFlag(
ThreadListEntry->thread, KTHREAD_MISC_FLAGS_ALERTABLE, TRUE);
apc = (PKAPC)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAPC), POOL_TAG_APC);
apc = (PKAPC)ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAPC), POOL_TAG_APC);
if (!apc)
return;
KeInitializeApc(apc,
ImpKeInitializeApc(apc,
ThreadListEntry->thread,
OriginalApcEnvironment,
ApcKernelRoutine,
@ -1343,12 +1344,12 @@ ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
KernelMode,
Context);
apc_status = KeInsertQueueApc(apc, NULL, NULL, IO_NO_INCREMENT);
apc_status = ImpKeInsertQueueApc(apc, NULL, NULL, IO_NO_INCREMENT);
if (!apc_status)
{
DEBUG_ERROR("KeInsertQueueApc failed with no status.");
ExFreePoolWithTag(apc, POOL_TAG_APC);
ImpExFreePoolWithTag(apc, POOL_TAG_APC);
return;
}
@ -1381,18 +1382,18 @@ ValidateThreadsViaKernelApc()
return STATUS_SUCCESS;
}
context = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(APC_STACKWALK_CONTEXT), POOL_TAG_APC);
context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(APC_STACKWALK_CONTEXT), POOL_TAG_APC);
if (!context)
return STATUS_MEMORY_NOT_ALLOCATED;
context->header.context_id = APC_CONTEXT_ID_STACKWALK;
context->modules =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(SYSTEM_MODULES), POOL_TAG_APC);
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(SYSTEM_MODULES), POOL_TAG_APC);
if (!context->modules)
{
ExFreePoolWithTag(context, POOL_TAG_APC);
ImpExFreePoolWithTag(context, POOL_TAG_APC);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@ -1401,18 +1402,18 @@ ValidateThreadsViaKernelApc()
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("GetSystemModuleInformation failed with status %x", status);
ExFreePoolWithTag(context->modules, POOL_TAG_APC);
ExFreePoolWithTag(context, POOL_TAG_APC);
ImpExFreePoolWithTag(context->modules, POOL_TAG_APC);
ImpExFreePoolWithTag(context, POOL_TAG_APC);
return STATUS_MEMORY_NOT_ALLOCATED;
}
status = InsertApcContext(context);
status =InsertApcContext(context);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("InsertApcContext failed with status %x", status);
ExFreePoolWithTag(context->modules, POOL_TAG_APC);
ExFreePoolWithTag(context, POOL_TAG_APC);
ImpExFreePoolWithTag(context->modules, POOL_TAG_APC);
ImpExFreePoolWithTag(context, POOL_TAG_APC);
return status;
}
@ -1427,14 +1428,16 @@ VOID
FreeApcStackwalkApcContextInformation(_Inout_ PAPC_STACKWALK_CONTEXT Context)
{
if (Context->modules->address)
ExFreePoolWithTag(Context->modules->address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(Context->modules->address, SYSTEM_MODULES_POOL);
if (Context->modules)
ExFreePoolWithTag(Context->modules, POOL_TAG_APC);
ImpExFreePoolWithTag(Context->modules, POOL_TAG_APC);
}
#define DPC_STACKWALK_STACKFRAME_COUNT 10
#define DPC_STACKWALK_FRAMES_TO_SKIP 3
/* the first 3 frames are isr handlers which we dont care about */
#define DPC_STACKWALK_FRAMES_TO_SKIP 3
typedef struct _DPC_CONTEXT
{
@ -1456,12 +1459,12 @@ DpcStackwalkCallbackRoutine(_In_ PKDPC Dpc,
{
PDPC_CONTEXT context = &((PDPC_CONTEXT)DeferredContext)[KeGetCurrentProcessorNumber()];
context->frames_captured = RtlCaptureStackBackTrace(DPC_STACKWALK_FRAMES_TO_SKIP,
context->frames_captured = ImpRtlCaptureStackBackTrace(DPC_STACKWALK_FRAMES_TO_SKIP,
DPC_STACKWALK_STACKFRAME_COUNT,
&context->stack_frame,
NULL);
InterlockedExchange(&context->executed, TRUE);
KeSignalCallDpcDone(SystemArgument1);
ImpKeSignalCallDpcDone(SystemArgument1);
DEBUG_VERBOSE("Executed DPC on core: %lx, with %lx frames captured.",
KeGetCurrentProcessorNumber(),
@ -1472,7 +1475,7 @@ STATIC
BOOLEAN
CheckForDpcCompletion(_In_ PDPC_CONTEXT Context)
{
for (UINT32 index = 0; index < KeQueryActiveProcessorCount(0); index++)
for (UINT32 index = 0; index < ImpKeQueryActiveProcessorCount(0); index++)
{
if (!InterlockedExchange(&Context[index].executed, Context[index].executed))
return FALSE;
@ -1489,7 +1492,7 @@ ValidateDpcCapturedStack(_In_ PSYSTEM_MODULES Modules, _In_ PDPC_CONTEXT Context
BOOLEAN flag = FALSE;
PDPC_STACKWALK_REPORT report = NULL;
for (UINT32 core = 0; core < KeQueryActiveProcessorCount(0); core++)
for (UINT32 core = 0; core < ImpKeQueryActiveProcessorCount(0); core++)
{
for (UINT32 frame = 0; frame < Context[core].frames_captured; frame++)
{
@ -1506,7 +1509,7 @@ ValidateDpcCapturedStack(_In_ PSYSTEM_MODULES Modules, _In_ PDPC_CONTEXT Context
if (!flag)
{
report = ExAllocatePool2(POOL_FLAG_NON_PAGED,
report = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(DPC_STACKWALK_REPORT),
POOL_TAG_DPC);
@ -1541,8 +1544,8 @@ DispatchStackwalkToEachCpuViaDpc()
PDPC_CONTEXT context = NULL;
SYSTEM_MODULES modules = {0};
context = ExAllocatePool2(POOL_FLAG_NON_PAGED,
KeQueryActiveProcessorCount(0) * sizeof(DPC_CONTEXT),
context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpKeQueryActiveProcessorCount(0) * sizeof(DPC_CONTEXT),
POOL_TAG_DPC);
if (!context)
@ -1559,7 +1562,7 @@ DispatchStackwalkToEachCpuViaDpc()
/* KeGenericCallDpc will queue a DPC to each processor with importance =
* HighImportance. This means our DPC will be inserted into the front of the DPC
* queue and executed immediately.*/
KeGenericCallDpc(DpcStackwalkCallbackRoutine, context);
ImpKeGenericCallDpc(DpcStackwalkCallbackRoutine, context);
while (!CheckForDpcCompletion(context))
YieldProcessor();
@ -1576,9 +1579,9 @@ DispatchStackwalkToEachCpuViaDpc()
end:
if (modules.address)
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
if (context)
ExFreePoolWithTag(context, POOL_TAG_DPC);
ImpExFreePoolWithTag(context, POOL_TAG_DPC);
return status;
}
@ -1649,7 +1652,7 @@ ValidateHalPrivateDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modul
DEBUG_VERBOSE("Validating HalPrivateDispatchTable.");
table = MmGetSystemRoutineAddress(&string);
table = ImpMmGetSystemRoutineAddress(&string);
if (!table)
return status;
@ -1825,7 +1828,7 @@ STATIC
VOID
ReportDataTableInvalidRoutine(_In_ TABLE_ID TableId, _In_ UINT64 Address)
{
PDATA_TABLE_ROUTINE_REPORT report = ExAllocatePool2(
PDATA_TABLE_ROUTINE_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(DATA_TABLE_ROUTINE_REPORT), POOL_TAG_INTEGRITY);
if (!report)
@ -1886,7 +1889,7 @@ ValidateHalDispatchTables()
end:
if (modules.address)
ExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
ImpExFreePoolWithTag(modules.address, SYSTEM_MODULES_POOL);
return status;
}

View file

@ -130,4 +130,7 @@ DispatchStackwalkToEachCpuViaDpc();
NTSTATUS
ValidateHalDispatchTables();
PVOID
FindDriverBaseNoApi(_In_ PWCH Name);
#endif

View file

@ -5,6 +5,7 @@
#include "callbacks.h"
#include "queue.h"
#include "ia32.h"
#include "imports.h"
#define PAGE_BASE_SIZE 0x1000
#define POOL_TAG_SIZE 0x004
@ -109,7 +110,7 @@ GetGlobalDebuggerData()
RtlCaptureContext(&context);
dump_header = ExAllocatePool2(POOL_FLAG_NON_PAGED, DUMP_BLOCK_SIZE, POOL_DUMP_BLOCK_TAG);
dump_header = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, DUMP_BLOCK_SIZE, POOL_DUMP_BLOCK_TAG);
if (!dump_header)
goto end;
@ -127,7 +128,7 @@ GetGlobalDebuggerData()
end:
if (dump_header)
ExFreePoolWithTag(dump_header, POOL_DUMP_BLOCK_TAG);
ImpExFreePoolWithTag(dump_header, POOL_DUMP_BLOCK_TAG);
return debugger_data;
}
@ -145,7 +146,7 @@ GetPsActiveProcessHead(_Out_ PUINT64 Address)
return;
*Address = *(UINT64*)(debugger_data->PsActiveProcessHead);
ExFreePoolWithTag(debugger_data, POOL_DEBUGGER_DATA_TAG);
ImpExFreePoolWithTag(debugger_data, POOL_DEBUGGER_DATA_TAG);
}
/*
@ -196,19 +197,19 @@ ValidateIfAddressIsProcessStructure(_In_ PVOID Address, _In_ PPOOL_HEADER PoolHe
BOOLEAN object_table_test = FALSE;
UINT64 allocation_size_test = 0;
if (MmIsAddressValid((UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET))
if (ImpMmIsAddressValid((UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET))
dir_table_base = *(UINT64*)((UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET);
if (MmIsAddressValid((UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET))
if (ImpMmIsAddressValid((UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET))
peak_virtual_size = *(UINT64*)((UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET);
if (MmIsAddressValid((UINT64)PoolHeader + POOL_HEADER_BLOCK_SIZE_OFFSET))
if (ImpMmIsAddressValid((UINT64)PoolHeader + POOL_HEADER_BLOCK_SIZE_OFFSET))
allocation_size = PoolHeader->BlockSize * CHUNK_SIZE - sizeof(POOL_HEADER);
if (MmIsAddressValid((UINT64)Address + EPROCESS_PEB_OFFSET))
if (ImpMmIsAddressValid((UINT64)Address + EPROCESS_PEB_OFFSET))
peb = *(UINT64*)((UINT64)Address + EPROCESS_PEB_OFFSET);
if (MmIsAddressValid((UINT64)Address + EPROCESS_OBJECT_TABLE_OFFSET))
if (ImpMmIsAddressValid((UINT64)Address + EPROCESS_OBJECT_TABLE_OFFSET))
object_table = *(UINT64*)((UINT64)Address + EPROCESS_OBJECT_TABLE_OFFSET);
peb_test = peb == NULL || (peb & 0x7ffd0000 == 0x7ffd0000 && peb % 0x1000 == NULL);
@ -279,7 +280,7 @@ ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase,
{
for (INT sig_index = 0; sig_index < POOL_TAG_LENGTH + 1; sig_index++)
{
if (!MmIsAddressValid(PageBase + offset + sig_index))
if (!ImpMmIsAddressValid(PageBase + offset + sig_index))
break;
current_char = *(PCHAR)(PageBase + offset + sig_index);
@ -289,7 +290,7 @@ ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase,
{
pool_header = (UINT64)PageBase + offset - POOL_HEADER_TAG_OFFSET;
if (!MmIsAddressValid((PVOID)pool_header))
if (!ImpMmIsAddressValid((PVOID)pool_header))
break;
/*
@ -437,7 +438,7 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
PPHYSICAL_MEMORY_RANGE physical_memory_ranges = NULL;
KIRQL irql = {0};
physical_memory_ranges = MmGetPhysicalMemoryRangesEx2(NULL, NULL);
physical_memory_ranges = ImpMmGetPhysicalMemoryRangesEx2(NULL, NULL);
if (!physical_memory_ranges)
{
@ -449,14 +450,14 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart = cr3.AddressOfPageDirectory << PAGE_4KB_SHIFT;
pml4_base.BitAddress = MmGetVirtualForPhysical(physical);
pml4_base.BitAddress = ImpMmGetVirtualForPhysical(physical);
if (!MmIsAddressValid(pml4_base.BitAddress) || !pml4_base.BitAddress)
if (!ImpMmIsAddressValid(pml4_base.BitAddress) || !pml4_base.BitAddress)
return;
for (INT pml4_index = 0; pml4_index < PML4_ENTRY_COUNT; pml4_index++)
{
if (!MmIsAddressValid(pml4_base.BitAddress + pml4_index * sizeof(UINT64)))
if (!ImpMmIsAddressValid(pml4_base.BitAddress + pml4_index * sizeof(UINT64)))
continue;
pml4_entry.BitAddress =
@ -467,14 +468,14 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart = pml4_entry.Bits.PhysicalAddress << PAGE_4KB_SHIFT;
pdpt_base = MmGetVirtualForPhysical(physical);
pdpt_base = ImpMmGetVirtualForPhysical(physical);
if (!pdpt_base || !MmIsAddressValid(pdpt_base))
if (!pdpt_base || !ImpMmIsAddressValid(pdpt_base))
continue;
for (INT pdpt_index = 0; pdpt_index < PDPT_ENTRY_COUNT; pdpt_index++)
{
if (!MmIsAddressValid(pdpt_base + pdpt_index * sizeof(UINT64)))
if (!ImpMmIsAddressValid(pdpt_base + pdpt_index * sizeof(UINT64)))
continue;
pdpt_entry.BitAddress = *(UINT64*)(pdpt_base + pdpt_index * sizeof(UINT64));
@ -494,10 +495,10 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart, physical_memory_ranges) == FALSE)
continue;
base_1gb_virtual_page = MmGetVirtualForPhysical(physical);
base_1gb_virtual_page = ImpMmGetVirtualForPhysical(physical);
if (!base_1gb_virtual_page ||
!MmIsAddressValid(base_1gb_virtual_page))
!ImpMmIsAddressValid(base_1gb_virtual_page))
continue;
EnumerateKernelLargePages(base_1gb_virtual_page,
@ -510,14 +511,14 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart = pdpt_entry.Bits.PhysicalAddress << PAGE_4KB_SHIFT;
pd_base = MmGetVirtualForPhysical(physical);
pd_base = ImpMmGetVirtualForPhysical(physical);
if (!pd_base || !MmIsAddressValid(pd_base))
if (!pd_base || !ImpMmIsAddressValid(pd_base))
continue;
for (INT pd_index = 0; pd_index < PD_ENTRY_COUNT; pd_index++)
{
if (!MmIsAddressValid(pd_base + pd_index * sizeof(UINT64)))
if (!ImpMmIsAddressValid(pd_base + pd_index * sizeof(UINT64)))
continue;
pd_entry.BitAddress =
@ -538,10 +539,11 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart, physical_memory_ranges) == FALSE)
continue;
base_2mb_virtual_page = MmGetVirtualForPhysical(physical);
base_2mb_virtual_page =
ImpMmGetVirtualForPhysical(physical);
if (!base_2mb_virtual_page ||
!MmIsAddressValid(base_2mb_virtual_page))
!ImpMmIsAddressValid(base_2mb_virtual_page))
continue;
EnumerateKernelLargePages(base_2mb_virtual_page,
@ -554,17 +556,18 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart = pd_entry.Bits.PhysicalAddress << PAGE_4KB_SHIFT;
if (!MmIsAddressValid(pd_base + pd_index * sizeof(UINT64)))
if (!ImpMmIsAddressValid(pd_base + pd_index * sizeof(UINT64)))
continue;
pt_base = MmGetVirtualForPhysical(physical);
pt_base = ImpMmGetVirtualForPhysical(physical);
if (!pt_base || !MmIsAddressValid(pt_base))
if (!pt_base || !ImpMmIsAddressValid(pt_base))
continue;
for (INT pt_index = 0; pt_index < PT_ENTRY_COUNT; pt_index++)
{
if (!MmIsAddressValid(pt_base + pt_index * sizeof(UINT64)))
if (!ImpMmIsAddressValid(pt_base +
pt_index * sizeof(UINT64)))
continue;
pt_entry.BitAddress =
@ -581,11 +584,11 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
physical.QuadPart, physical_memory_ranges) == FALSE)
continue;
base_virtual_page = MmGetVirtualForPhysical(physical);
base_virtual_page = ImpMmGetVirtualForPhysical(physical);
/* stupid fucking intellisense error GO AWAY! */
if (base_virtual_page == NULL ||
!MmIsAddressValid(base_virtual_page))
!ImpMmIsAddressValid(base_virtual_page))
continue;
ScanPageForKernelObjectAllocation(base_virtual_page,
@ -690,7 +693,7 @@ FindUnlinkedProcesses()
DEBUG_WARNING("Potentially found an unlinked process allocation at address: %llx",
allocation);
report_buffer = ExAllocatePool2(
report_buffer = ImpExAllocatePool2(
POOL_FLAG_PAGED, sizeof(INVALID_PROCESS_ALLOCATION_REPORT), REPORT_POOL_TAG);
if (!report_buffer)
@ -707,7 +710,7 @@ FindUnlinkedProcesses()
end:
if (context.process_buffer)
ExFreePoolWithTag(context.process_buffer, PROCESS_ADDRESS_LIST_TAG);
ImpExFreePoolWithTag(context.process_buffer, PROCESS_ADDRESS_LIST_TAG);
return STATUS_SUCCESS;
}
@ -726,7 +729,7 @@ EnumerateBigPoolAllocations()
SYSTEM_BIGPOOL_INFORMATION pool_information = {0};
PSYSTEM_BIGPOOL_INFORMATION pool_entries = NULL;
UNICODE_STRING routine = RTL_CONSTANT_STRING(L"ZwQuerySystemInformation");
ZwQuerySystemInformation pZwQuerySystemInformation = MmGetSystemRoutineAddress(&routine);
ZwQuerySystemInformation pZwQuerySystemInformation = ImpMmGetSystemRoutineAddress(&routine);
if (!pZwQuerySystemInformation)
{
@ -747,7 +750,7 @@ EnumerateBigPoolAllocations()
return_length += sizeof(SYSTEM_BIGPOOL_INFORMATION);
pool_entries = ExAllocatePool2(POOL_FLAG_NON_PAGED, return_length, POOL_TAG_INTEGRITY);
pool_entries = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, return_length, POOL_TAG_INTEGRITY);
if (!pool_entries)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -770,7 +773,7 @@ EnumerateBigPoolAllocations()
end:
if (pool_entries)
ExFreePoolWithTag(pool_entries, POOL_TAG_INTEGRITY);
ImpExFreePoolWithTag(pool_entries, POOL_TAG_INTEGRITY);
return status;
}

View file

@ -9,6 +9,7 @@
#include "thread.h"
#include "ioctl.h"
#include "common.h"
#include "imports.h"
/*
* This mutex is to prevent a new item being pushed to the queue
@ -36,8 +37,8 @@ InitialiseGlobalReportQueue(_Out_ PBOOLEAN Status)
report_queue_config.head.entries = 0;
report_queue_config.is_driver_unloading = FALSE;
KeInitializeGuardedMutex(&report_queue_config.head.lock);
KeInitializeGuardedMutex(&report_queue_config.lock);
ImpKeInitializeGuardedMutex(&report_queue_config.head.lock);
ImpKeInitializeGuardedMutex(&report_queue_config.lock);
*Status = TRUE;
}
@ -65,7 +66,7 @@ _Releases_lock_(_Lock_kind_mutex_)
VOID
QueuePush(_Inout_ PQUEUE_HEAD Head, _In_ PVOID Data)
{
KeAcquireGuardedMutex(&Head->lock);
ImpKeAcquireGuardedMutex(&Head->lock);
PQUEUE_NODE temp = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(QUEUE_NODE), QUEUE_POOL_TAG);
@ -85,7 +86,7 @@ QueuePush(_Inout_ PQUEUE_HEAD Head, _In_ PVOID Data)
Head->start = temp;
end:
KeReleaseGuardedMutex(&Head->lock);
ImpKeReleaseGuardedMutex(&Head->lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -94,7 +95,7 @@ _Releases_lock_(_Lock_kind_mutex_)
PVOID
QueuePop(_Inout_ PQUEUE_HEAD Head)
{
KeAcquireGuardedMutex(&Head->lock);
ImpKeAcquireGuardedMutex(&Head->lock);
PVOID data = NULL;
PQUEUE_NODE temp = Head->start;
@ -110,10 +111,10 @@ QueuePop(_Inout_ PQUEUE_HEAD Head)
if (Head->end == temp)
Head->end = NULL;
ExFreePoolWithTag(temp, QUEUE_POOL_TAG);
ImpExFreePoolWithTag(temp, QUEUE_POOL_TAG);
end:
KeReleaseGuardedMutex(&Head->lock);
ImpKeReleaseGuardedMutex(&Head->lock);
return data;
}
@ -127,9 +128,9 @@ InsertReportToQueue(_In_ PVOID Report)
report_queue_config.is_driver_unloading))
return;
KeAcquireGuardedMutex(&report_queue_config.lock);
ImpKeAcquireGuardedMutex(&report_queue_config.lock);
QueuePush(&report_queue_config.head, Report);
KeReleaseGuardedMutex(&report_queue_config.lock);
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
@ -139,20 +140,20 @@ VOID
FreeGlobalReportQueueObjects()
{
InterlockedExchange(&report_queue_config.is_driver_unloading, TRUE);
KeAcquireGuardedMutex(&report_queue_config.lock);
ImpKeAcquireGuardedMutex(&report_queue_config.lock);
PVOID report = QueuePop(&report_queue_config.head);
while (report != NULL)
{
ExFreePoolWithTag(report, REPORT_POOL_TAG);
ImpExFreePoolWithTag(report, REPORT_POOL_TAG);
report = QueuePop(&report_queue_config.head);
DEBUG_VERBOSE("Unloading report queue. Entries remaining: %i",
report_queue_config.head.entries);
}
end:
KeReleaseGuardedMutex(&report_queue_config.lock);
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
}
/*
@ -178,7 +179,7 @@ HandlePeriodicGlobalReportQueueQuery(_Inout_ PIRP Irp)
PREPORT_HEADER report_header = NULL;
GLOBAL_REPORT_QUEUE_HEADER header = {0};
KeAcquireGuardedMutex(&report_queue_config.lock);
ImpKeAcquireGuardedMutex(&report_queue_config.lock);
report_buffer_size = sizeof(INVALID_PROCESS_ALLOCATION_REPORT) * MAX_REPORTS_PER_IRP +
sizeof(GLOBAL_REPORT_QUEUE_HEADER);
@ -188,16 +189,16 @@ HandlePeriodicGlobalReportQueueQuery(_Inout_ PIRP Irp)
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ValidateIrpOutputBuffer failed with status %x", status);
KeReleaseGuardedMutex(&report_queue_config.lock);
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
return status;
}
report_buffer =
ExAllocatePool2(POOL_FLAG_NON_PAGED, report_buffer_size, REPORT_QUEUE_TEMP_BUFFER_TAG);
report_buffer = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, report_buffer_size, REPORT_QUEUE_TEMP_BUFFER_TAG);
if (!report_buffer)
{
KeReleaseGuardedMutex(&report_queue_config.lock);
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@ -290,7 +291,7 @@ HandlePeriodicGlobalReportQueueQuery(_Inout_ PIRP Irp)
}
/* QueuePop frees the node, but we still need to free the returned data */
ExFreePoolWithTag(report, REPORT_POOL_TAG);
ImpExFreePoolWithTag(report, REPORT_POOL_TAG);
report = QueuePop(&report_queue_config.head);
count += 1;
@ -298,7 +299,7 @@ HandlePeriodicGlobalReportQueueQuery(_Inout_ PIRP Irp)
end:
KeReleaseGuardedMutex(&report_queue_config.lock);
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
Irp->IoStatus.Information = sizeof(GLOBAL_REPORT_QUEUE_HEADER) + total_size;
@ -311,7 +312,7 @@ end:
sizeof(GLOBAL_REPORT_QUEUE_HEADER) + total_size);
if (report_buffer)
ExFreePoolWithTag(report_buffer, REPORT_QUEUE_TEMP_BUFFER_TAG);
ImpExFreePoolWithTag(report_buffer, REPORT_QUEUE_TEMP_BUFFER_TAG);
DEBUG_VERBOSE("All reports moved into the IRP, sending to usermode.");
return STATUS_SUCCESS;
@ -340,7 +341,7 @@ end:
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock)
{
KeInitializeGuardedMutex(Lock);
ImpKeInitializeGuardedMutex(Lock);
Head->Next = NULL;
}
@ -351,14 +352,14 @@ ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock)
{
KeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY old_entry = Head->Next;
Head->Next = NewEntry;
NewEntry->Next = old_entry;
KeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
}
/*
@ -375,21 +376,24 @@ ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_opt_ PVOID CallbackRoutine)
{
BOOLEAN result = FALSE;
KeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
if (Head->Next)
{
PSINGLE_LIST_ENTRY entry = Head->Next;
VOID (*callback_function_ptr)(PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry);
if (CallbackRoutine)
{
VOID (*callback_function_ptr)(PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry);
}
Head->Next = Head->Next->Next;
ExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
ImpExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
result = TRUE;
}
KeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
return result;
}
@ -404,7 +408,7 @@ ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
KeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY entry = Head->Next;
@ -414,7 +418,7 @@ ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
if (entry == Entry)
{
Head->Next = entry->Next;
ExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
@ -423,7 +427,7 @@ ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
if (entry->Next == Entry)
{
entry->Next = Entry->Next;
ExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
@ -431,5 +435,5 @@ ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
}
unlock:
KeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
}

View file

@ -6,6 +6,7 @@
#include "callbacks.h"
#include "driver.h"
#include "queue.h"
#include "imports.h"
#ifdef ALLOC_PRAGMA
# pragma alloc_text(PAGE, DetectThreadsAttachedToProtectedProcess)
@ -24,7 +25,7 @@ ValidateThreadsPspCidTableEntry(_In_ PETHREAD Thread)
/*
* PsGetThreadId simply returns ETHREAD->Cid.UniqueThread
*/
thread_id = PsGetThreadId(Thread);
thread_id = ImpPsGetThreadId(Thread);
/*
* For each core on the processor, the first x threads equal to x cores will be assigned a
@ -36,7 +37,7 @@ ValidateThreadsPspCidTableEntry(_In_ PETHREAD Thread)
* bypassed by simply modifying the ETHREAD->Cid.UniqueThread identifier.. So while it isnt
* a perfect detection method for now it's good enough.
*/
if ((UINT64)thread_id < (UINT64)KeQueryActiveProcessorCount(NULL))
if ((UINT64)thread_id < (UINT64)ImpKeQueryActiveProcessorCount(NULL))
return TRUE;
/*
@ -45,7 +46,7 @@ ValidateThreadsPspCidTableEntry(_In_ PETHREAD Thread)
* Meaning if we pass a valid thread id which we retrieved above and dont receive a
* STATUS_SUCCESS the cid entry could potentially be removed or disrupted..
*/
status = PsLookupThreadByThreadId(thread_id, &thread);
status = ImpPsLookupThreadByThreadId(thread_id, &thread);
if (!NT_SUCCESS(status))
{
@ -59,7 +60,7 @@ ValidateThreadsPspCidTableEntry(_In_ PETHREAD Thread)
/*
* I did not reverse this myself and previously had no idea how you would go about
* detecting KiAttachProcess so credits to KANKOSHEV for the explanation:
* detecting KiAttachProcess so credits to KANKOSHEV for the find:
*
* https://github.com/KANKOSHEV/Detect-KeAttachProcess/tree/main
* https://doxygen.reactos.org/d0/dc9/procobj_8c.html#adec6dc539d4a5c0ee7d0f48e24ef0933
@ -89,21 +90,23 @@ _IRQL_always_function_min_(DISPATCH_LEVEL) STATIC VOID
/*
* Just a sanity check even though it doesnt really make sense for internal threads of our
* protected process to attach..
*
* todo: this is filterless and will just report anything, need to have a look into what
* processes actually attach to real games
*/
if (apc_state->Process == protected_process &&
ThreadListEntry->owning_process != protected_process)
if (apc_state->Process == protected_process)
{
DEBUG_WARNING("Thread is attached to our protected process: %llx",
(UINT64)ThreadListEntry->thread);
PATTACH_PROCESS_REPORT report = ExAllocatePool2(
PATTACH_PROCESS_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(ATTACH_PROCESS_REPORT), REPORT_POOL_TAG);
if (!report)
return;
report->report_code = REPORT_ILLEGAL_ATTACH_PROCESS;
report->thread_id = PsGetThreadId(ThreadListEntry->thread);
report->thread_id = ImpPsGetThreadId(ThreadListEntry->thread);
report->thread_address = ThreadListEntry->thread;
InsertReportToQueue(report);

View file

@ -55,7 +55,6 @@ DriverUnload(
)
{
IoDeleteDevice(DriverObject->DeviceObject);
DEBUG_LOG("Driver unloaded");
}
NTSTATUS
@ -78,7 +77,6 @@ DriverEntry(
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("IoCreateDevice failed with status %x", status);
return STATUS_FAILED_DRIVER_ENTRY;
}
@ -89,7 +87,6 @@ DriverEntry(
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to create symbolic link");
IoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}

View file

@ -6,7 +6,7 @@
#define STATIC static
#define VOID void
#define DEBUG_LOG(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_LOG(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)
#endif

View file

@ -73,36 +73,34 @@ Init(HINSTANCE hinstDLL)
* have, such as the process module validation. At the end of the day an anti cheat that
* imposes a significant performance pentalty on the game its protecting is useless.
*/
srand(time(NULL));
while (!GetAsyncKeyState(VK_DELETE))
{
// int seed = (rand() % 11);
int seed = (rand() % 11);
// std::cout << "Seed: " << seed << std::endl;
std::cout << "Seed: " << seed << std::endl;
// switch (seed)
//switch (seed)
//{
// case 0: kmanager.EnumerateHandleTables(); break;
// case 1: kmanager.PerformIntegrityCheck(); break;
// case 2: kmanager.ScanPoolsForUnlinkedProcesses(); break;
// case 3: kmanager.VerifySystemModuleDriverObjects(); break;
// case 4: kmanager.ValidateProcessModules(); break;
// case 5: kmanager.RunNmiCallbacks(); break;
// case 6: kmanager.CheckForAttachedThreads(); break;
// case 7: kmanager.InitiateApcStackwalkOperation(); break;
// case 8: kmanager.CheckForEptHooks(); break;
// case 9: kmanager.StackwalkThreadsViaDpc(); break;
// case 10: kmanager.ValidateSystemModules(); break;
// }
//case 0: kmanager.EnumerateHandleTables(); break;
//case 1: kmanager.PerformIntegrityCheck(); break;
//case 2: kmanager.ScanPoolsForUnlinkedProcesses(); break;
//case 3: kmanager.VerifySystemModuleDriverObjects(); break;
//case 4: kmanager.ValidateProcessModules(); break;
//case 5: kmanager.RunNmiCallbacks(); break;
//case 6: kmanager.CheckForAttachedThreads(); break;
//case 7: kmanager.InitiateApcStackwalkOperation(); break;
//case 8: kmanager.CheckForEptHooks(); break;
//case 9: kmanager.StackwalkThreadsViaDpc(); break;
//case 10: kmanager.ValidateSystemModules(); break;
//}
kmanager.ValidateSystemModules();
std::this_thread::sleep_for(std::chrono::seconds(2));
kmanager.PerformIntegrityCheck();
std::this_thread::sleep_for(std::chrono::seconds(2));
kmanager.ValidateProcessModules();
// kmanager.MonitorCallbackReports();
kmanager.MonitorCallbackReports();
std::this_thread::sleep_for(std::chrono::seconds(10));
}