mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
significant refactor to mdouel vaerification + expoert stuff kinda wip
This commit is contained in:
parent
52f00b9a1a
commit
f29f4aad5f
21 changed files with 1907 additions and 547 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
254
driver/driver.c
254
driver/driver.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,4 +191,7 @@ GetDriverDeviceObject();
|
|||
|
||||
GetSystemModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT* Context);
|
||||
|
||||
PDRIVER_OBJECT
|
||||
GetDriverObject();
|
||||
|
||||
#endif
|
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
215
driver/imports.c
Normal 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
719
driver/imports.h
Normal 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
|
|
@ -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(
|
||||
§ion_handle, §ion, &module_path, §ion_size);
|
||||
§ion_handle, §ion, &module_path, §ion_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(¤t_function, CONTROL_FUNCTIONS[index]);
|
||||
CONTROL_FUNCTION_ADDRESSES[index] = MmGetSystemRoutineAddress(¤t_function);
|
||||
ImpRtlInitUnicodeString(¤t_function, CONTROL_FUNCTIONS[index]);
|
||||
CONTROL_FUNCTION_ADDRESSES[index] = ImpMmGetSystemRoutineAddress(¤t_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(¤t_function, CONTROL_FUNCTIONS[index]);
|
||||
PROTECTED_FUNCTION_ADDRESSES[index] = MmGetSystemRoutineAddress(¤t_function);
|
||||
ImpRtlInitUnicodeString(¤t_function, CONTROL_FUNCTIONS[index]);
|
||||
PROTECTED_FUNCTION_ADDRESSES[index] =
|
||||
ImpMmGetSystemRoutineAddress(¤t_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(§ion_handle, §ion, &path, §ion_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(§ion_handle, §ion, &path, §ion_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)));
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
159
driver/modules.c
159
driver/modules.c
|
@ -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;
|
||||
}
|
|
@ -130,4 +130,7 @@ DispatchStackwalkToEachCpuViaDpc();
|
|||
NTSTATUS
|
||||
ValidateHalDispatchTables();
|
||||
|
||||
PVOID
|
||||
FindDriverBaseNoApi(_In_ PWCH Name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue