This commit is contained in:
donnaskiez 2024-08-01 14:21:53 +10:00
parent 18109448bc
commit 197796d004
18 changed files with 2130 additions and 1836 deletions

View file

@ -1,9 +1,9 @@
BasedOnStyle: webkit BasedOnStyle: webkit
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignAfterOpenBracket: Align AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: true AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: true AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: true AlignConsecutiveMacros: true
@ -73,7 +73,7 @@ MaxEmptyLinesToKeep: 1
NamespaceIndentation: None #All NamespaceIndentation: None #All
PointerAlignment: Left PointerAlignment: Left
ReflowComments: true ReflowComments: true
SortIncludes: false SortIncludes: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true

View file

@ -137,7 +137,8 @@ QueryActiveApcContextsForCompletion()
switch (entry->context_id) { switch (entry->context_id) {
case APC_CONTEXT_ID_STACKWALK: case APC_CONTEXT_ID_STACKWALK:
FreeApcStackwalkApcContextInformation((PAPC_STACKWALK_CONTEXT)entry); FreeApcStackwalkApcContextInformation(
(PAPC_STACKWALK_CONTEXT)entry);
FreeApcContextStructure(entry); FreeApcContextStructure(entry);
break; break;
} }

View file

@ -2,24 +2,25 @@
#include "driver.h" #include "driver.h"
#include "pool.h"
#include "thread.h"
#include "modules.h"
#include "imports.h"
#include "session.h"
#include "crypt.h" #include "crypt.h"
#include "imports.h"
#include "modules.h"
#include "pool.h"
#include "session.h"
#include "thread.h"
#include "util.h" #include "util.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
#include "containers/tree.h"
#include "containers/map.h" #include "containers/map.h"
#include "containers/tree.h"
#define PROCESS_HASHMAP_BUCKET_COUNT 101 #define PROCESS_HASHMAP_BUCKET_COUNT 101
STATIC STATIC
BOOLEAN BOOLEAN
EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, EnumHandleCallback(
_In_ PHANDLE_TABLE HandleTable,
_In_ PHANDLE_TABLE_ENTRY Entry, _In_ PHANDLE_TABLE_ENTRY Entry,
_In_ HANDLE Handle, _In_ HANDLE Handle,
_In_ PVOID Context); _In_ PVOID Context);
@ -77,13 +78,13 @@ CleanupDriverListOnDriverUnload()
{ {
PDRIVER_LIST_HEAD head = GetDriverList(); PDRIVER_LIST_HEAD head = GetDriverList();
PLIST_ENTRY entry = NULL; PLIST_ENTRY entry = NULL;
PDRIVER_LIST_ENTRY driver = NULL;
ImpKeAcquireGuardedMutex(&head->lock); ImpKeAcquireGuardedMutex(&head->lock);
while (!IsListEmpty(&head->list_entry)) { while (!IsListEmpty(&head->list_entry)) {
entry = RemoveHeadList(&head->list_entry); entry = RemoveHeadList(&head->list_entry);
PDRIVER_LIST_ENTRY driverEntry = driver = CONTAINING_RECORD(entry, DRIVER_LIST_ENTRY, list_entry);
CONTAINING_RECORD(entry, DRIVER_LIST_ENTRY, list_entry);
ExFreePoolWithTag(entry, POOL_TAG_DRIVER_LIST); ExFreePoolWithTag(entry, POOL_TAG_DRIVER_LIST);
} }
@ -114,13 +115,15 @@ EnumerateDriverListWithCallbackRoutine(
} }
VOID VOID
DriverListEntryToExtendedModuleInfo(_In_ PDRIVER_LIST_ENTRY Entry, DriverListEntryToExtendedModuleInfo(
_Out_ PRTL_MODULE_EXTENDED_INFO Extended) _In_ PDRIVER_LIST_ENTRY Entry, _Out_ PRTL_MODULE_EXTENDED_INFO Extended)
{ {
Extended->ImageBase = Entry->ImageBase; Extended->ImageBase = Entry->ImageBase;
Extended->ImageSize = Entry->ImageSize; Extended->ImageSize = Entry->ImageSize;
IntCopyMemory( IntCopyMemory(
Extended->FullPathName, Entry->path, sizeof(Extended->FullPathName)); Extended->FullPathName,
Entry->path,
sizeof(Extended->FullPathName));
} }
NTSTATUS NTSTATUS
@ -156,7 +159,8 @@ InitialiseDriverList()
/* skip hal.dll and ntoskrnl.exe */ /* skip hal.dll and ntoskrnl.exe */
for (UINT32 index = 2; index < modules.module_count; index++) { for (UINT32 index = 2; index < modules.module_count; index++) {
entry = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, entry = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(DRIVER_LIST_ENTRY), sizeof(DRIVER_LIST_ENTRY),
POOL_TAG_DRIVER_LIST); POOL_TAG_DRIVER_LIST);
@ -169,14 +173,16 @@ InitialiseDriverList()
entry->ImageBase = module_entry->ImageBase; entry->ImageBase = module_entry->ImageBase;
entry->ImageSize = module_entry->ImageSize; entry->ImageSize = module_entry->ImageSize;
IntCopyMemory(entry->path, IntCopyMemory(
entry->path,
module_entry->FullPathName, module_entry->FullPathName,
sizeof(module_entry->FullPathName)); sizeof(module_entry->FullPathName));
status = HashModule(module_entry, entry->text_hash); status = HashModule(module_entry, entry->text_hash);
if (status == STATUS_INVALID_IMAGE_WIN_32) { if (status == STATUS_INVALID_IMAGE_WIN_32) {
DEBUG_ERROR("32 bit module not hashed, will hash later. %x", DEBUG_ERROR(
"32 bit module not hashed, will hash later. %x",
status); status);
entry->hashed = FALSE; entry->hashed = FALSE;
entry->x86 = TRUE; entry->x86 = TRUE;
@ -206,8 +212,8 @@ InitialiseDriverList()
* think! * think!
*/ */
VOID VOID
FindDriverEntryByBaseAddress(_In_ PVOID ImageBase, FindDriverEntryByBaseAddress(
_Out_ PDRIVER_LIST_ENTRY* Entry) _In_ PVOID ImageBase, _Out_ PDRIVER_LIST_ENTRY* Entry)
{ {
PDRIVER_LIST_HEAD head = GetDriverList(); PDRIVER_LIST_HEAD head = GetDriverList();
PLIST_ENTRY list_entry = NULL; PLIST_ENTRY list_entry = NULL;
@ -253,10 +259,10 @@ ProcessHashmapHashFunction(_In_ UINT64 Key)
STATIC STATIC
VOID VOID
ImageLoadInsertNonSystemImageIntoProcessHashmap(_In_ PIMAGE_INFO ImageInfo, ImageLoadInsertNonSystemImageIntoProcessHashmap(
_In_ PIMAGE_INFO ImageInfo,
_In_ HANDLE ProcessId, _In_ HANDLE ProcessId,
_In_opt_ PUNICODE_STRING _In_opt_ PUNICODE_STRING FullImageName)
FullImageName)
{ {
INT32 index = 0; INT32 index = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
@ -303,7 +309,9 @@ ImageLoadInsertNonSystemImageIntoProcessHashmap(_In_ PIMAGE_INFO ImageInfo,
*/ */
if (FullImageName) if (FullImageName)
UnicodeToCharBufString( UnicodeToCharBufString(
FullImageName, module->path, sizeof(module->path)); FullImageName,
module->path,
sizeof(module->path));
InsertTailList(&entry->module_list, &module->entry); InsertTailList(&entry->module_list, &module->entry);
entry->list_count++; entry->list_count++;
@ -313,7 +321,8 @@ end:
} }
VOID VOID
ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName, ImageLoadNotifyRoutineCallback(
_In_opt_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId, _In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo) _In_ PIMAGE_INFO ImageInfo)
{ {
@ -330,7 +339,9 @@ ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
if (ImageInfo->SystemModeImage == FALSE) { if (ImageInfo->SystemModeImage == FALSE) {
ImageLoadInsertNonSystemImageIntoProcessHashmap( ImageLoadInsertNonSystemImageIntoProcessHashmap(
ImageInfo, ProcessId, FullImageName); ImageInfo,
ProcessId,
FullImageName);
return; return;
} }
@ -341,7 +352,9 @@ ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
return; return;
entry = ExAllocatePool2( entry = ExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(DRIVER_LIST_ENTRY), POOL_TAG_DRIVER_LIST); POOL_FLAG_NON_PAGED,
sizeof(DRIVER_LIST_ENTRY),
POOL_TAG_DRIVER_LIST);
if (!entry) if (!entry)
return; return;
@ -356,9 +369,13 @@ ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
if (FullImageName) { if (FullImageName) {
UnicodeToCharBufString( UnicodeToCharBufString(
FullImageName, module.FullPathName, sizeof(module.FullPathName)); FullImageName,
module.FullPathName,
sizeof(module.FullPathName));
IntCopyMemory( IntCopyMemory(
entry->path, module.FullPathName, sizeof(module.FullPathName)); entry->path,
module.FullPathName,
sizeof(module.FullPathName));
} }
DEBUG_VERBOSE("New system image ansi: %s", entry->path); DEBUG_VERBOSE("New system image ansi: %s", entry->path);
@ -383,8 +400,8 @@ hash:
/* assumes map lock is held */ /* assumes map lock is held */
VOID VOID
FreeProcessEntryModuleList(_In_ PPROCESS_LIST_ENTRY Entry, FreeProcessEntryModuleList(
_In_opt_ PVOID Context) _In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context)
{ {
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Context);
@ -402,7 +419,8 @@ FreeProcessEntryModuleList(_In_ PPROCESS_LIST_ENTRY Entry,
} }
VOID VOID
EnumerateProcessModuleList(_In_ HANDLE ProcessId, EnumerateProcessModuleList(
_In_ HANDLE ProcessId,
_In_ PROCESS_MODULE_CALLBACK Callback, _In_ PROCESS_MODULE_CALLBACK Callback,
_In_opt_ PVOID Context) _In_opt_ PVOID Context)
{ {
@ -439,8 +457,8 @@ end:
} }
VOID VOID
FindOurUserModeModuleEntry(_In_ PROCESS_MODULE_CALLBACK Callback, FindOurUserModeModuleEntry(
_In_opt_ PVOID Context) _In_ PROCESS_MODULE_CALLBACK Callback, _In_opt_ PVOID Context)
{ {
INT32 index = 0; INT32 index = 0;
PRTL_HASHMAP map = GetProcessHashmap(); PRTL_HASHMAP map = GetProcessHashmap();
@ -520,14 +538,16 @@ InitialiseProcessHashmap()
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PPROCESS_MODULE_MAP_CONTEXT context = NULL; PPROCESS_MODULE_MAP_CONTEXT context = NULL;
context = ExAllocatePool2(POOL_FLAG_NON_PAGED, context = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(PROCESS_MODULE_MAP_CONTEXT), sizeof(PROCESS_MODULE_MAP_CONTEXT),
POOL_TAG_HASHMAP); POOL_TAG_HASHMAP);
if (!context) if (!context)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
status = ExInitializeLookasideListEx(&context->pool, status = ExInitializeLookasideListEx(
&context->pool,
NULL, NULL,
NULL, NULL,
NonPagedPoolNx, NonPagedPoolNx,
@ -541,7 +561,8 @@ InitialiseProcessHashmap()
return status; return status;
} }
status = RtlHashmapCreate(PROCESS_HASHMAP_BUCKET_COUNT, status = RtlHashmapCreate(
PROCESS_HASHMAP_BUCKET_COUNT,
sizeof(PROCESS_LIST_ENTRY), sizeof(PROCESS_LIST_ENTRY),
ProcessHashmapHashFunction, ProcessHashmapHashFunction,
ProcessHashmapCompareFunction, ProcessHashmapCompareFunction,
@ -590,8 +611,8 @@ InitialiseThreadList()
} }
VOID VOID
FindThreadListEntryByThreadAddress(_In_ HANDLE ThreadId, FindThreadListEntryByThreadAddress(
_Out_ PTHREAD_LIST_ENTRY* Entry) _In_ HANDLE ThreadId, _Out_ PTHREAD_LIST_ENTRY* Entry)
{ {
PRB_TREE tree = GetThreadTree(); PRB_TREE tree = GetThreadTree();
RtlRbTreeAcquireLock(tree); RtlRbTreeAcquireLock(tree);
@ -604,7 +625,8 @@ STATIC
BOOLEAN BOOLEAN
CanInitiateDeferredHashing(_In_ LPCSTR ProcessName, _In_ PDRIVER_LIST_HEAD Head) CanInitiateDeferredHashing(_In_ LPCSTR ProcessName, _In_ PDRIVER_LIST_HEAD Head)
{ {
return !IntCompareString(ProcessName, "winlogon.exe") && Head->work_item ? TRUE return !IntCompareString(ProcessName, "winlogon.exe") && Head->work_item
? TRUE
: FALSE; : FALSE;
} }
@ -621,7 +643,8 @@ PrintHashmapCallback(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context)
for (list = Entry->module_list.Flink; list != &Entry->module_list; for (list = Entry->module_list.Flink; list != &Entry->module_list;
list = list->Flink) { list = list->Flink) {
module = CONTAINING_RECORD(list, PROCESS_MAP_MODULE_ENTRY, entry); module = CONTAINING_RECORD(list, PROCESS_MAP_MODULE_ENTRY, entry);
DEBUG_VERBOSE(" -> Module Base: %p, size: %lx, path: %s", DEBUG_VERBOSE(
" -> Module Base: %p, size: %lx, path: %s",
(PVOID)module->base, (PVOID)module->base,
module->size, module->size,
module->path); module->path);
@ -635,9 +658,8 @@ EnumerateAndPrintProcessHashmap()
} }
VOID VOID
ProcessCreateNotifyRoutine(_In_ HANDLE ParentId, ProcessCreateNotifyRoutine(
_In_ HANDLE ProcessId, _In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOOLEAN Create)
_In_ BOOLEAN Create)
{ {
INT32 index = 0; INT32 index = 0;
PKPROCESS parent = NULL; PKPROCESS parent = NULL;
@ -681,7 +703,8 @@ ProcessCreateNotifyRoutine(_In_ HANDLE ParentId,
* any x86 modules that werent hashed. * any x86 modules that werent hashed.
*/ */
if (CanInitiateDeferredHashing(process_name, driver_list)) { if (CanInitiateDeferredHashing(process_name, driver_list)) {
IoQueueWorkItem(driver_list->work_item, IoQueueWorkItem(
driver_list->work_item,
DeferredModuleHashingCallback, DeferredModuleHashingCallback,
NormalWorkQueue, NormalWorkQueue,
NULL); NULL);
@ -707,9 +730,8 @@ end:
} }
VOID VOID
ThreadCreateNotifyRoutine(_In_ HANDLE ProcessId, ThreadCreateNotifyRoutine(
_In_ HANDLE ThreadId, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ BOOLEAN Create)
_In_ BOOLEAN Create)
{ {
PTHREAD_LIST_ENTRY entry = NULL; PTHREAD_LIST_ENTRY entry = NULL;
PKTHREAD thread = NULL; PKTHREAD thread = NULL;
@ -759,9 +781,9 @@ end:
} }
VOID VOID
ObPostOpCallbackRoutine(_In_ PVOID RegistrationContext, ObPostOpCallbackRoutine(
_In_ POB_POST_OPERATION_INFORMATION _In_ PVOID RegistrationContext,
OperationInformation) _In_ POB_POST_OPERATION_INFORMATION OperationInformation)
{ {
PAGED_CODE(); PAGED_CODE();
UNREFERENCED_PARAMETER(RegistrationContext); UNREFERENCED_PARAMETER(RegistrationContext);
@ -777,7 +799,8 @@ ObPostOpCallbackRoutine(_In_ PVOID RegistrationContext,
#define DOWNGRADE_MSMPENG 3 #define DOWNGRADE_MSMPENG 3
CHAR PROCESS_HANDLE_OPEN_DOWNGRADE[PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT] CHAR PROCESS_HANDLE_OPEN_DOWNGRADE[PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT]
[MAX_PROCESS_NAME_LENGTH] = {"lsass.exe", [MAX_PROCESS_NAME_LENGTH] = {
"lsass.exe",
"csrss.exe", "csrss.exe",
"WerFault.exe", "WerFault.exe",
"MsMpEng.exe"}; "MsMpEng.exe"};
@ -785,7 +808,8 @@ CHAR PROCESS_HANDLE_OPEN_DOWNGRADE[PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT]
#define PROCESS_HANDLE_OPEN_WHITELIST_COUNT 3 #define PROCESS_HANDLE_OPEN_WHITELIST_COUNT 3
CHAR PROCESS_HANDLE_OPEN_WHITELIST[PROCESS_HANDLE_OPEN_WHITELIST_COUNT] CHAR PROCESS_HANDLE_OPEN_WHITELIST[PROCESS_HANDLE_OPEN_WHITELIST_COUNT]
[MAX_PROCESS_NAME_LENGTH] = {"Discord.exe", [MAX_PROCESS_NAME_LENGTH] = {
"Discord.exe",
"svchost.exe", "svchost.exe",
"explorer.exe"}; "explorer.exe"};
@ -795,7 +819,9 @@ IsWhitelistedHandleOpenProcess(_In_ LPCSTR ProcessName)
{ {
for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_WHITELIST_COUNT; for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_WHITELIST_COUNT;
index++) { index++) {
if (!IntCompareString(ProcessName, PROCESS_HANDLE_OPEN_WHITELIST[index])) if (!IntCompareString(
ProcessName,
PROCESS_HANDLE_OPEN_WHITELIST[index]))
return TRUE; return TRUE;
} }
@ -808,7 +834,9 @@ IsDowngradeHandleOpenProcess(_In_ LPCSTR ProcessName)
{ {
for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT; for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT;
index++) { index++) {
if (!IntCompareString(ProcessName, PROCESS_HANDLE_OPEN_DOWNGRADE[index])) if (!IntCompareString(
ProcessName,
PROCESS_HANDLE_OPEN_DOWNGRADE[index]))
return TRUE; return TRUE;
} }
@ -819,7 +847,8 @@ IsDowngradeHandleOpenProcess(_In_ LPCSTR ProcessName)
#define GET_OBJECT_HEADER_FROM_HANDLE(x) ((x << 4) | 0xffff000000000000); #define GET_OBJECT_HEADER_FROM_HANDLE(x) ((x << 4) | 0xffff000000000000);
OB_PREOP_CALLBACK_STATUS OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, ObPreOpCallbackRoutine(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation) _In_ POB_PRE_OPERATION_INFORMATION OperationInformation)
{ {
PAGED_CODE(); PAGED_CODE();
@ -910,7 +939,9 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
sizeof(OPEN_HANDLE_FAILURE_REPORT)); sizeof(OPEN_HANDLE_FAILURE_REPORT));
POPEN_HANDLE_FAILURE_REPORT report = ImpExAllocatePool2( POPEN_HANDLE_FAILURE_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, report_size, REPORT_POOL_TAG); POOL_FLAG_NON_PAGED,
report_size,
REPORT_POOL_TAG);
if (!report) if (!report)
goto end; goto end;
@ -923,7 +954,8 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
report->access = OperationInformation->Parameters report->access = OperationInformation->Parameters
->CreateHandleInformation.DesiredAccess; ->CreateHandleInformation.DesiredAccess;
IntCopyMemory(report->process_name, IntCopyMemory(
report->process_name,
process_creator_name, process_creator_name,
HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH);
@ -946,8 +978,8 @@ end:
/* stolen from ReactOS xD */ /* stolen from ReactOS xD */
VOID NTAPI VOID NTAPI
ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, ExUnlockHandleTableEntry(
IN PHANDLE_TABLE_ENTRY HandleTableEntry) IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
{ {
INT64 old_value; INT64 old_value;
PAGED_CODE(); PAGED_CODE();
@ -975,7 +1007,8 @@ static UNICODE_STRING OBJECT_TYPE_THREAD = RTL_CONSTANT_STRING(L"Thread");
STATIC STATIC
BOOLEAN BOOLEAN
EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, EnumHandleCallback(
_In_ PHANDLE_TABLE HandleTable,
_In_ PHANDLE_TABLE_ENTRY Entry, _In_ PHANDLE_TABLE_ENTRY Entry,
_In_ HANDLE Handle, _In_ HANDLE Handle,
_In_ PVOID Context) _In_ PVOID Context)
@ -1003,7 +1036,9 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
/* TODO: check for threads aswell */ /* TODO: check for threads aswell */
if (ImpRtlCompareUnicodeString( if (ImpRtlCompareUnicodeString(
&object_type->Name, &OBJECT_TYPE_PROCESS, TRUE)) { &object_type->Name,
&OBJECT_TYPE_PROCESS,
TRUE)) {
goto end; goto end;
} }
@ -1118,7 +1153,8 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
report->thread_id = 0; report->thread_id = 0;
report->access = handle_access_mask; report->access = handle_access_mask;
IntCopyMemory(&report->process_name, IntCopyMemory(
&report->process_name,
process_name, process_name,
HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH);
@ -1175,8 +1211,8 @@ EnumerateProcessHandles(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context)
STATIC STATIC
VOID VOID
TimerObjectValidateProcessModuleCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry, TimerObjectValidateProcessModuleCallback(
_In_opt_ PVOID Context) _In_ PPROCESS_MAP_MODULE_ENTRY Entry, _In_opt_ PVOID Context)
{ {
CHAR hash[SHA_256_HASH_LENGTH] = {0}; CHAR hash[SHA_256_HASH_LENGTH] = {0};
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
@ -1203,8 +1239,8 @@ TimerObjectValidateProcessModuleCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
STATIC STATIC
VOID VOID
TimerObjectWorkItemRoutine(_In_ PDEVICE_OBJECT DeviceObject, TimerObjectWorkItemRoutine(
_In_opt_ PVOID Context) _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PTIMER_OBJECT timer = (PTIMER_OBJECT)Context; PTIMER_OBJECT timer = (PTIMER_OBJECT)Context;
@ -1238,7 +1274,8 @@ TimerObjectWorkItemRoutine(_In_ PDEVICE_OBJECT DeviceObject,
goto end; goto end;
} }
FindOurUserModeModuleEntry(TimerObjectValidateProcessModuleCallback, FindOurUserModeModuleEntry(
TimerObjectValidateProcessModuleCallback,
session); session);
KeReleaseGuardedMutex(&session->lock); KeReleaseGuardedMutex(&session->lock);
@ -1251,7 +1288,8 @@ end:
*/ */
STATIC STATIC
VOID VOID
TimerObjectCallbackRoutine(_In_ PKDPC Dpc, TimerObjectCallbackRoutine(
_In_ PKDPC Dpc,
_In_opt_ PVOID DeferredContext, _In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2) _In_opt_ PVOID SystemArgument2)
@ -1272,7 +1310,8 @@ TimerObjectCallbackRoutine(_In_ PKDPC Dpc,
/* we queue a work item because DPCs run at IRQL = DISPATCH_LEVEL and we /* we queue a work item because DPCs run at IRQL = DISPATCH_LEVEL and we
* need certain routines which cannot be run at an IRQL this high.*/ * need certain routines which cannot be run at an IRQL this high.*/
InterlockedExchange(&timer->state, TRUE); InterlockedExchange(&timer->state, TRUE);
IoQueueWorkItem(timer->work_item, IoQueueWorkItem(
timer->work_item,
TimerObjectWorkItemRoutine, TimerObjectWorkItemRoutine,
BackgroundWorkQueue, BackgroundWorkQueue,
timer); timer);

View file

@ -11,7 +11,8 @@ RtlHashmapDelete(_In_ PRTL_HASHMAP Hashmap)
} }
NTSTATUS NTSTATUS
RtlHashmapCreate(_In_ UINT32 BucketCount, RtlHashmapCreate(
_In_ UINT32 BucketCount,
_In_ UINT32 EntryObjectSize, _In_ UINT32 EntryObjectSize,
_In_ HASH_FUNCTION HashFunction, _In_ HASH_FUNCTION HashFunction,
_In_ COMPARE_FUNCTION CompareFunction, _In_ COMPARE_FUNCTION CompareFunction,
@ -26,12 +27,15 @@ RtlHashmapCreate(_In_ UINT32 BucketCount,
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
Hashmap->buckets = ExAllocatePool2( Hashmap->buckets = ExAllocatePool2(
POOL_FLAG_NON_PAGED, BucketCount * entry_size, POOL_TAG_HASHMAP); POOL_FLAG_NON_PAGED,
BucketCount * entry_size,
POOL_TAG_HASHMAP);
if (!Hashmap->buckets) if (!Hashmap->buckets)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
Hashmap->locks = ExAllocatePool2(POOL_FLAG_NON_PAGED, Hashmap->locks = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(KGUARDED_MUTEX) * BucketCount, sizeof(KGUARDED_MUTEX) * BucketCount,
POOL_TAG_HASHMAP); POOL_TAG_HASHMAP);
@ -47,7 +51,8 @@ RtlHashmapCreate(_In_ UINT32 BucketCount,
KeInitializeGuardedMutex(&Hashmap->locks[index]); KeInitializeGuardedMutex(&Hashmap->locks[index]);
} }
status = ExInitializeLookasideListEx(&Hashmap->pool, status = ExInitializeLookasideListEx(
&Hashmap->pool,
NULL, NULL,
NULL, NULL,
NonPagedPoolNx, NonPagedPoolNx,
@ -172,9 +177,8 @@ RtlHashmapEntryInsert(_In_ PRTL_HASHMAP Hashmap, _In_ UINT32 Index)
* Also assumes lock is held. * Also assumes lock is held.
*/ */
PVOID PVOID
RtlHashmapEntryLookup(_In_ PRTL_HASHMAP Hashmap, RtlHashmapEntryLookup(
_In_ UINT32 Index, _In_ PRTL_HASHMAP Hashmap, _In_ UINT32 Index, _In_ PVOID Compare)
_In_ PVOID Compare)
{ {
UINT32 index = 0; UINT32 index = 0;
PRTL_HASHMAP_ENTRY entry = NULL; PRTL_HASHMAP_ENTRY entry = NULL;
@ -201,9 +205,8 @@ RtlHashmapEntryLookup(_In_ PRTL_HASHMAP Hashmap,
/* Assumes lock is held */ /* Assumes lock is held */
BOOLEAN BOOLEAN
RtlHashmapEntryDelete(_Inout_ PRTL_HASHMAP Hashmap, RtlHashmapEntryDelete(
_In_ UINT32 Index, _Inout_ PRTL_HASHMAP Hashmap, _In_ UINT32 Index, _In_ PVOID Compare)
_In_ PVOID Compare)
{ {
UINT32 index = 0; UINT32 index = 0;
PLIST_ENTRY list_head = NULL; PLIST_ENTRY list_head = NULL;
@ -240,7 +243,8 @@ RtlHashmapEntryDelete(_Inout_ PRTL_HASHMAP Hashmap,
/* assumes lock is held */ /* assumes lock is held */
VOID VOID
RtlHashmapEnumerate(_In_ PRTL_HASHMAP Hashmap, RtlHashmapEnumerate(
_In_ PRTL_HASHMAP Hashmap,
_In_ ENUMERATE_HASHMAP EnumerationCallback, _In_ ENUMERATE_HASHMAP EnumerationCallback,
_In_opt_ PVOID Context) _In_opt_ PVOID Context)
{ {

View file

@ -108,9 +108,9 @@ RtlRbTreePrintCurrentStatistics(_In_ PRB_TREE Tree)
* - This stores the size of the objects that will be stored in the tree. It * - This stores the size of the objects that will be stored in the tree. It
* is used to allocate memory for the nodes. * is used to allocate memory for the nodes.
* - Lets say each node needs to have a THREAD_LIST_ENTRY object. The * - Lets say each node needs to have a THREAD_LIST_ENTRY object. The
* ObjectSize = sizeof(THREAD_LIST_OBJECT) and in turn will mean each node will * ObjectSize = sizeof(THREAD_LIST_OBJECT) and in turn will mean each node
* be of size: sizeof(THREAD_LIST_OBJECT) + sizeof(RB_TREE_NODE). This is also * will be of size: sizeof(THREAD_LIST_OBJECT) + sizeof(RB_TREE_NODE). This is
* this size the lookaside list pools will be set to. * also this size the lookaside list pools will be set to.
* *
* > `LOOKASIDE_LIST_EX pool`: * > `LOOKASIDE_LIST_EX pool`:
* - This is a lookaside list that provides a fast, efficient way to allocate * - This is a lookaside list that provides a fast, efficient way to allocate
@ -118,16 +118,16 @@ RtlRbTreePrintCurrentStatistics(_In_ PRB_TREE Tree)
* block is `ObjectSize + sizeof(RB_TREE_NODE)`. * block is `ObjectSize + sizeof(RB_TREE_NODE)`.
*/ */
NTSTATUS NTSTATUS
RtlRbTreeCreate(_In_ RB_COMPARE Compare, RtlRbTreeCreate(
_In_ UINT32 ObjectSize, _In_ RB_COMPARE Compare, _In_ UINT32 ObjectSize, _Out_ PRB_TREE Tree)
_Out_ PRB_TREE Tree)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
if (!ARGUMENT_PRESENT(Compare) || ObjectSize == 0) if (!ARGUMENT_PRESENT(Compare) || ObjectSize == 0)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
status = ExInitializeLookasideListEx(&Tree->pool, status = ExInitializeLookasideListEx(
&Tree->pool,
NULL, NULL,
NULL, NULL,
NonPagedPoolNx, NonPagedPoolNx,
@ -538,7 +538,8 @@ RtlpRbTreeFixupDelete(_In_ PRB_TREE Tree, _In_ PRB_TREE_NODE Node)
*/ */
STATIC STATIC
VOID VOID
RtlpRbTreeTransplant(_In_ PRB_TREE Tree, RtlpRbTreeTransplant(
_In_ PRB_TREE Tree,
_In_ PRB_TREE_NODE Target, _In_ PRB_TREE_NODE Target,
_In_ PRB_TREE_NODE Replacement) _In_ PRB_TREE_NODE Replacement)
{ {
@ -673,7 +674,8 @@ RtlRbTreeFindNodeObject(_In_ PRB_TREE Tree, _In_ PVOID Key)
STATIC STATIC
VOID VOID
RtlpRbTreeEnumerate(_In_ PRB_TREE_NODE Node, RtlpRbTreeEnumerate(
_In_ PRB_TREE_NODE Node,
_In_ RB_ENUM_CALLBACK Callback, _In_ RB_ENUM_CALLBACK Callback,
_In_opt_ PVOID Context) _In_opt_ PVOID Context)
{ {
@ -686,9 +688,8 @@ RtlpRbTreeEnumerate(_In_ PRB_TREE_NODE Node,
} }
VOID VOID
RtlRbTreeEnumerate(_In_ PRB_TREE Tree, RtlRbTreeEnumerate(
_In_ RB_ENUM_CALLBACK Callback, _In_ PRB_TREE Tree, _In_ RB_ENUM_CALLBACK Callback, _In_opt_ PVOID Context)
_In_opt_ PVOID Context)
{ {
if (Tree->root == NULL) if (Tree->root == NULL)
return; return;
@ -708,7 +709,8 @@ RtlpPrintInOrder(PRB_TREE_NODE Node)
RtlpPrintInOrder(Node->left); RtlpPrintInOrder(Node->left);
const char* color = (Node->colour == red) ? "Red" : "Black"; const char* color = (Node->colour == red) ? "Red" : "Black";
DbgPrintEx(DPFLTR_DEFAULT_ID, DbgPrintEx(
DPFLTR_DEFAULT_ID,
DPFLTR_INFO_LEVEL, DPFLTR_INFO_LEVEL,
"Node: Key=%p, Color=%s\n", "Node: Key=%p, Color=%s\n",
*((PHANDLE)Node->object), *((PHANDLE)Node->object),

View file

@ -1,8 +1,8 @@
#include "crypt.h" #include "crypt.h"
#include "driver.h"
#include "imports.h" #include "imports.h"
#include "session.h" #include "session.h"
#include "driver.h"
#include "util.h" #include "util.h"
#include "types/tpm20.h" #include "types/tpm20.h"
@ -10,8 +10,8 @@
#include "lib/stdlib.h" #include "lib/stdlib.h"
#include <immintrin.h>
#include <bcrypt.h> #include <bcrypt.h>
#include <immintrin.h>
FORCEINLINE FORCEINLINE
STATIC STATIC
@ -60,14 +60,16 @@ CryptEncryptImportsArray(_In_ PUINT64 Array, _In_ UINT32 Entries)
__m256i load_block = {0}; __m256i load_block = {0};
__m256i xored_block = {0}; __m256i xored_block = {0};
IntCopyMemory(&current_block, IntCopyMemory(
&current_block,
&Array[block_index * block_size], &Array[block_index * block_size],
sizeof(__m256i)); sizeof(__m256i));
load_block = _mm256_loadu_si256(&current_block); load_block = _mm256_loadu_si256(&current_block);
xored_block = _mm256_xor_si256(load_block, *imports_key); xored_block = _mm256_xor_si256(load_block, *imports_key);
IntCopyMemory(&Array[block_index * block_size], IntCopyMemory(
&Array[block_index * block_size],
&xored_block, &xored_block,
sizeof(__m256i)); sizeof(__m256i));
} }
@ -82,7 +84,8 @@ CryptDecryptImportBlock(_In_ PUINT64 Array, _In_ UINT32 BlockIndex)
__m256i* imports_key = GetDriverImportsKey(); __m256i* imports_key = GetDriverImportsKey();
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64); UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
IntCopyMemory(&load_block, IntCopyMemory(
&load_block,
&Array[BlockIndex * block_size], &Array[BlockIndex * block_size],
sizeof(__m256i)); sizeof(__m256i));
@ -92,7 +95,8 @@ CryptDecryptImportBlock(_In_ PUINT64 Array, _In_ UINT32 BlockIndex)
FORCEINLINE FORCEINLINE
INLINE INLINE
VOID VOID
CryptFindContainingBlockForArrayIndex(_In_ UINT32 EntryIndex, CryptFindContainingBlockForArrayIndex(
_In_ UINT32 EntryIndex,
_In_ UINT32 BlockSize, _In_ UINT32 BlockSize,
_Out_ PUINT32 ContainingBlockIndex, _Out_ PUINT32 ContainingBlockIndex,
_Out_ PUINT32 BlockSubIndex) _Out_ PUINT32 BlockSubIndex)
@ -122,9 +126,8 @@ CryptFindContainingBlockForArrayIndex(_In_ UINT32 EntryIndex,
} }
UINT64 UINT64
CryptDecryptImportsArrayEntry(_In_ PUINT64 Array, CryptDecryptImportsArrayEntry(
_In_ UINT32 Entries, _In_ PUINT64 Array, _In_ UINT32 Entries, _In_ UINT32 EntryIndex)
_In_ UINT32 EntryIndex)
{ {
__m256i original_block = {0}; __m256i original_block = {0};
__m128i original_half = {0}; __m128i original_half = {0};
@ -133,7 +136,8 @@ CryptDecryptImportsArrayEntry(_In_ PUINT64 Array,
UINT32 block_sub_index = 0; UINT32 block_sub_index = 0;
UINT64 pointer = 0; UINT64 pointer = 0;
CryptFindContainingBlockForArrayIndex(EntryIndex, CryptFindContainingBlockForArrayIndex(
EntryIndex,
block_size, block_size,
&containing_block_index, &containing_block_index,
&block_sub_index); &block_sub_index);
@ -164,8 +168,8 @@ STATIC
PBCRYPT_KEY_DATA_BLOB_HEADER PBCRYPT_KEY_DATA_BLOB_HEADER
CryptBuildBlobForKeyImport(_In_ PACTIVE_SESSION Session) CryptBuildBlobForKeyImport(_In_ PACTIVE_SESSION Session)
{ {
PBCRYPT_KEY_DATA_BLOB_HEADER blob = PBCRYPT_KEY_DATA_BLOB_HEADER blob = ExAllocatePool2(
ExAllocatePool2(POOL_FLAG_NON_PAGED, POOL_FLAG_NON_PAGED,
sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + AES_256_KEY_SIZE, sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + AES_256_KEY_SIZE,
POOL_TAG_CRYPT); POOL_TAG_CRYPT);
@ -176,7 +180,8 @@ CryptBuildBlobForKeyImport(_In_ PACTIVE_SESSION Session)
blob->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; blob->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
blob->cbKeyData = AES_256_KEY_SIZE; blob->cbKeyData = AES_256_KEY_SIZE;
IntCopyMemory((UINT64)blob + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), IntCopyMemory(
(UINT64)blob + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER),
Session->aes_key, Session->aes_key,
AES_256_KEY_SIZE); AES_256_KEY_SIZE);
@ -226,7 +231,8 @@ CryptEncryptBuffer(_In_ PVOID Buffer, _In_ UINT32 BufferLength)
buffer = buffer + AES_256_BLOCK_SIZE; buffer = buffer + AES_256_BLOCK_SIZE;
length = length - AES_256_BLOCK_SIZE; length = length - AES_256_BLOCK_SIZE;
status = BCryptEncrypt(session->key_handle, status = BCryptEncrypt(
session->key_handle,
buffer, buffer,
length, length,
NULL, NULL,
@ -276,7 +282,8 @@ CryptInitialiseSessionCryptObjects()
if (!blob) if (!blob)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
status = BCryptGetProperty(*handle, status = BCryptGetProperty(
*handle,
BCRYPT_OBJECT_LENGTH, BCRYPT_OBJECT_LENGTH,
&session->key_object_length, &session->key_object_length,
sizeof(UINT32), sizeof(UINT32),
@ -288,7 +295,8 @@ CryptInitialiseSessionCryptObjects()
goto end; goto end;
} }
session->key_object = ExAllocatePool2(POOL_FLAG_NON_PAGED, session->key_object = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
session->key_object_length, session->key_object_length,
POOL_TAG_CRYPT); POOL_TAG_CRYPT);
@ -297,12 +305,13 @@ CryptInitialiseSessionCryptObjects()
goto end; goto end;
} }
DEBUG_INFO("key object: %llx, key_object_length: %lx", DEBUG_INFO(
"key object: %llx, key_object_length: %lx",
session->key_object, session->key_object,
session->key_object_length); session->key_object_length);
status = status = BCryptImportKey(
BCryptImportKey(*handle, *handle,
NULL, NULL,
BCRYPT_KEY_DATA_BLOB, BCRYPT_KEY_DATA_BLOB,
&session->key_handle, &session->key_handle,
@ -331,7 +340,8 @@ CryptInitialiseProvider()
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
BCRYPT_ALG_HANDLE* handle = GetCryptHandle_AES(); BCRYPT_ALG_HANDLE* handle = GetCryptHandle_AES();
status = BCryptOpenAlgorithmProvider(handle, status = BCryptOpenAlgorithmProvider(
handle,
BCRYPT_AES_ALGORITHM, BCRYPT_AES_ALGORITHM,
NULL, NULL,
BCRYPT_PROV_DISPATCH); BCRYPT_PROV_DISPATCH);
@ -441,8 +451,8 @@ TpmExtractInterfaceTypeFromCapabilityAndId(
*/ */
STATIC STATIC
NTSTATUS NTSTATUS
TpmGetPtpInterfaceType(_In_ PVOID Register, TpmGetPtpInterfaceType(
_Out_ TPM2_PTP_INTERFACE_TYPE* InterfaceType) _In_ PVOID Register, _Out_ TPM2_PTP_INTERFACE_TYPE* InterfaceType)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PTP_CRB_INTERFACE_IDENTIFIER identifier = {0}; PTP_CRB_INTERFACE_IDENTIFIER identifier = {0};
@ -512,7 +522,8 @@ TpmExtractEndorsementKey()
} }
NTSTATUS NTSTATUS
CryptHashBuffer_sha256(_In_ PVOID Buffer, CryptHashBuffer_sha256(
_In_ PVOID Buffer,
_In_ ULONG BufferSize, _In_ ULONG BufferSize,
_Out_ PVOID* HashResult, _Out_ PVOID* HashResult,
_Out_ PULONG HashResultSize) _Out_ PULONG HashResultSize)
@ -536,7 +547,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
* the buffer that will store the resulting hash, instead this will be * the buffer that will store the resulting hash, instead this will be
* used to store the hash object used to create the hash. * used to store the hash object used to create the hash.
*/ */
status = BCryptGetProperty(*algo_handle, status = BCryptGetProperty(
*algo_handle,
BCRYPT_OBJECT_LENGTH, BCRYPT_OBJECT_LENGTH,
(PCHAR)&hash_object_size, (PCHAR)&hash_object_size,
sizeof(ULONG), sizeof(ULONG),
@ -548,7 +560,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
goto end; goto end;
} }
hash_object = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, hash_object = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
hash_object_size, hash_object_size,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -561,7 +574,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
* This call gets the size of the resulting hash, which we will use to * This call gets the size of the resulting hash, which we will use to
* allocate the resulting hash buffer. * allocate the resulting hash buffer.
*/ */
status = BCryptGetProperty(*algo_handle, status = BCryptGetProperty(
*algo_handle,
BCRYPT_HASH_LENGTH, BCRYPT_HASH_LENGTH,
(PCHAR)&resulting_hash_size, (PCHAR)&resulting_hash_size,
sizeof(ULONG), sizeof(ULONG),
@ -573,7 +587,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
goto end; goto end;
} }
resulting_hash = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, resulting_hash = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
resulting_hash_size, resulting_hash_size,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -586,7 +601,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
* Here we create our hash object and store it in the hash_object * Here we create our hash object and store it in the hash_object
* buffer. * buffer.
*/ */
status = BCryptCreateHash(*algo_handle, status = BCryptCreateHash(
*algo_handle,
&hash_handle, &hash_handle,
hash_object, hash_object,
hash_object_size, hash_object_size,
@ -615,7 +631,8 @@ CryptHashBuffer_sha256(_In_ PVOID Buffer,
* As said in the previous comment, this is where we retrieve the final * As said in the previous comment, this is where we retrieve the final
* hash and store it in our output buffer. * hash and store it in our output buffer.
*/ */
status = BCryptFinishHash(hash_handle, status = BCryptFinishHash(
hash_handle,
resulting_hash, resulting_hash,
resulting_hash_size, resulting_hash_size,
NULL); NULL);

View file

@ -1,18 +1,18 @@
#include "driver.h" #include "driver.h"
#include "common.h"
#include "io.h"
#include "callbacks.h"
#include "hv.h"
#include "pool.h"
#include "thread.h"
#include "modules.h"
#include "integrity.h"
#include "imports.h"
#include "apc.h" #include "apc.h"
#include "callbacks.h"
#include "common.h"
#include "crypt.h" #include "crypt.h"
#include "session.h" #include "hv.h"
#include "hw.h" #include "hw.h"
#include "imports.h"
#include "integrity.h"
#include "io.h"
#include "modules.h"
#include "pool.h"
#include "session.h"
#include "thread.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -24,12 +24,13 @@ DriverUnload(_In_ PDRIVER_OBJECT DriverObject);
_Function_class_(DRIVER_INITIALIZE) _IRQL_requires_same_ _Function_class_(DRIVER_INITIALIZE) _IRQL_requires_same_
NTSTATUS NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, DriverEntry(
_In_ PUNICODE_STRING RegistryPath); _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
STATIC STATIC
NTSTATUS NTSTATUS
RegistryPathQueryCallbackRoutine(IN PWSTR ValueName, RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType, IN ULONG ValueType,
IN PVOID ValueData, IN PVOID ValueData,
IN ULONG ValueLength, IN ULONG ValueLength,
@ -58,8 +59,8 @@ DrvLoadEnableNotifyRoutines();
STATIC STATIC
NTSTATUS NTSTATUS
DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, DrvLoadInitialiseDriverConfig(
_In_ PUNICODE_STRING RegistryPath); _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
# pragma alloc_text(INIT, DriverEntry) # pragma alloc_text(INIT, DriverEntry)
@ -218,7 +219,8 @@ BOOLEAN
IsNmiInProgress() IsNmiInProgress()
{ {
PAGED_CODE(); PAGED_CODE();
return InterlockedCompareExchange(&GetDecryptedDriverConfig()->nmi_status, return InterlockedCompareExchange(
&GetDecryptedDriverConfig()->nmi_status,
TRUE, TRUE,
FALSE) != 0; FALSE) != 0;
} }
@ -255,7 +257,8 @@ BOOLEAN
IsDriverUnloading() IsDriverUnloading()
{ {
PAGED_CODE(); PAGED_CODE();
return InterlockedExchange(&GetDecryptedDriverConfig()->unload_in_progress, return InterlockedExchange(
&GetDecryptedDriverConfig()->unload_in_progress,
GetDecryptedDriverConfig()->unload_in_progress); GetDecryptedDriverConfig()->unload_in_progress);
} }
@ -492,7 +495,8 @@ DrvLoadEnableNotifyRoutines()
status = PsSetLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback); status = PsSetLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("PsSetLoadImageNotifyRoutine failed with status %x", DEBUG_ERROR(
"PsSetLoadImageNotifyRoutine failed with status %x",
status); status);
return status; return status;
} }
@ -500,7 +504,8 @@ DrvLoadEnableNotifyRoutines()
status = ImpPsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine); status = ImpPsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("PsSetCreateThreadNotifyRoutine failed with status %x", DEBUG_ERROR(
"PsSetCreateThreadNotifyRoutine failed with status %x",
status); status);
PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback); PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
return status; return status;
@ -510,7 +515,8 @@ DrvLoadEnableNotifyRoutines()
ImpPsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, FALSE); ImpPsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, FALSE);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", DEBUG_ERROR(
"PsSetCreateProcessNotifyRoutine failed with status %x",
status); status);
ImpPsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine); ImpPsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback); PsRemoveLoadImageNotifyRoutine(ImageLoadNotifyRoutineCallback);
@ -571,7 +577,8 @@ DrvLoadSetupDriverLists()
STATIC STATIC
NTSTATUS NTSTATUS
RegistryPathQueryCallbackRoutine(IN PWSTR ValueName, RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType, IN ULONG ValueType,
IN PVOID ValueData, IN PVOID ValueData,
IN ULONG ValueLength, IN ULONG ValueLength,
@ -606,7 +613,8 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName,
if (ImpRtlCompareUnicodeString(&value_name, &display_name, FALSE) == if (ImpRtlCompareUnicodeString(&value_name, &display_name, FALSE) ==
FALSE) { FALSE) {
temp_buffer = ImpExAllocatePool2(POOL_FLAG_PAGED, temp_buffer = ImpExAllocatePool2(
POOL_FLAG_PAGED,
ValueLength + 20, ValueLength + 20,
POOL_TAG_STRINGS); POOL_TAG_STRINGS);
@ -614,7 +622,8 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName,
return STATUS_MEMORY_NOT_ALLOCATED; return STATUS_MEMORY_NOT_ALLOCATED;
IntCopyMemory(temp_buffer, ValueData, ValueLength); IntCopyMemory(temp_buffer, ValueData, ValueLength);
IntWideStringCopy((PWCH)((UINT64)temp_buffer + ValueLength - 2), IntWideStringCopy(
(PWCH)((UINT64)temp_buffer + ValueLength - 2),
L".sys"); L".sys");
cfg->unicode_driver_name.Buffer = (PWCH)temp_buffer; cfg->unicode_driver_name.Buffer = (PWCH)temp_buffer;
@ -649,7 +658,8 @@ GetSystemProcessorType()
__cpuid(cpuid, 0); __cpuid(cpuid, 0);
DEBUG_VERBOSE("Cpuid: EBX: %lx, ECX: %lx, EDX: %lx", DEBUG_VERBOSE(
"Cpuid: EBX: %lx, ECX: %lx, EDX: %lx",
cpuid[1], cpuid[1],
cpuid[2], cpuid[2],
cpuid[3]); cpuid[3]);
@ -660,7 +670,8 @@ GetSystemProcessorType()
cfg->system_information.processor = AuthenticAmd; cfg->system_information.processor = AuthenticAmd;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (cpuid[EBX_REGISTER] == CPUID_GENUINE_INTEL_EBX && else if (
cpuid[EBX_REGISTER] == CPUID_GENUINE_INTEL_EBX &&
cpuid[ECX_REGISTER] == CPUID_GENUINE_INTEL_ECX && cpuid[ECX_REGISTER] == CPUID_GENUINE_INTEL_ECX &&
cpuid[EDX_REGISTER] == CPUID_GENUINE_INTEL_EDX) { cpuid[EDX_REGISTER] == CPUID_GENUINE_INTEL_EDX) {
cfg->system_information.processor = GenuineIntel; cfg->system_information.processor = GenuineIntel;
@ -684,7 +695,8 @@ ParseSmbiosForGivenSystemEnvironment()
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PDRIVER_CONFIG cfg = GetDecryptedDriverConfig(); PDRIVER_CONFIG cfg = GetDecryptedDriverConfig();
status = ParseSMBIOSTable(&cfg->system_information.vendor, status = ParseSMBIOSTable(
&cfg->system_information.vendor,
VENDOR_STRING_MAX_LENGTH, VENDOR_STRING_MAX_LENGTH,
SmbiosInformation, SmbiosInformation,
SMBIOS_VENDOR_STRING_SUB_INDEX); SMBIOS_VENDOR_STRING_SUB_INDEX);
@ -703,14 +715,16 @@ ParseSmbiosForGivenSystemEnvironment()
switch (cfg->system_information.environment) { switch (cfg->system_information.environment) {
case NativeWindows: { case NativeWindows: {
status = ParseSMBIOSTable(&cfg->system_information.motherboard_serial, status = ParseSMBIOSTable(
&cfg->system_information.motherboard_serial,
MOTHERBOARD_SERIAL_CODE_LENGTH, MOTHERBOARD_SERIAL_CODE_LENGTH,
VendorSpecificInformation, VendorSpecificInformation,
SMBIOS_NATIVE_SERIAL_NUMBER_SUB_INDEX); SMBIOS_NATIVE_SERIAL_NUMBER_SUB_INDEX);
break; break;
} }
case Vmware: { case Vmware: {
status = ParseSMBIOSTable(&cfg->system_information.motherboard_serial, status = ParseSMBIOSTable(
&cfg->system_information.motherboard_serial,
MOTHERBOARD_SERIAL_CODE_LENGTH, MOTHERBOARD_SERIAL_CODE_LENGTH,
SystemInformation, SystemInformation,
SMBIOS_VMWARE_SERIAL_NUMBER_SUB_INDEX); SMBIOS_VMWARE_SERIAL_NUMBER_SUB_INDEX);
@ -768,7 +782,8 @@ DrvLoadGatherSystemEnvironmentSettings()
sizeof(cfg->system_information.drive_0_serial)); sizeof(cfg->system_information.drive_0_serial));
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GetHardDiskDriverSerialNumber failed with status %x", DEBUG_ERROR(
"GetHardDiskDriverSerialNumber failed with status %x",
status); status);
return status; return status;
} }
@ -780,7 +795,8 @@ DrvLoadGatherSystemEnvironmentSettings()
cfg->system_information.os_information.dwBuildNumber); cfg->system_information.os_information.dwBuildNumber);
DEBUG_VERBOSE("Environment type: %lx", cfg->system_information.environment); DEBUG_VERBOSE("Environment type: %lx", cfg->system_information.environment);
DEBUG_VERBOSE("Processor type: %lx", cfg->system_information.processor); DEBUG_VERBOSE("Processor type: %lx", cfg->system_information.processor);
DEBUG_VERBOSE("Motherboard serial: %s", DEBUG_VERBOSE(
"Motherboard serial: %s",
cfg->system_information.motherboard_serial); cfg->system_information.motherboard_serial);
DEBUG_VERBOSE("Drive 0 serial: %s", cfg->system_information.drive_0_serial); DEBUG_VERBOSE("Drive 0 serial: %s", cfg->system_information.drive_0_serial);
@ -811,7 +827,8 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath)
query[1].EntryContext = NULL; query[1].EntryContext = NULL;
query[1].QueryRoutine = RegistryPathQueryCallbackRoutine; query[1].QueryRoutine = RegistryPathQueryCallbackRoutine;
status = RtlxQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, status = RtlxQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
RegistryPath->Buffer, RegistryPath->Buffer,
&query, &query,
NULL, NULL,
@ -828,12 +845,14 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath)
* name since we need the .sys extension when querying the system * name since we need the .sys extension when querying the system
* modules for our driver. * modules for our driver.
*/ */
status = ImpRtlUnicodeStringToAnsiString(&cfg->ansi_driver_name, status = ImpRtlUnicodeStringToAnsiString(
&cfg->ansi_driver_name,
&cfg->unicode_driver_name, &cfg->unicode_driver_name,
TRUE); TRUE);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("RtlUnicodeStringToAnsiString failed with status %x", DEBUG_ERROR(
"RtlUnicodeStringToAnsiString failed with status %x",
status); status);
} }
@ -842,8 +861,8 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath)
STATIC STATIC
NTSTATUS NTSTATUS
DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, DrvLoadInitialiseDriverConfig(
_In_ PUNICODE_STRING RegistryPath) _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{ {
PAGED_CODE(); PAGED_CODE();
DEBUG_VERBOSE("Initialising driver configuration"); DEBUG_VERBOSE("Initialising driver configuration");
@ -873,7 +892,8 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject,
status = DrvLoadGatherSystemEnvironmentSettings(); status = DrvLoadGatherSystemEnvironmentSettings();
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GatherSystemEnvironmentSettings failed with status %x", DEBUG_ERROR(
"GatherSystemEnvironmentSettings failed with status %x",
status); status);
return status; return status;
} }
@ -903,7 +923,8 @@ InitialiseHashingAlgorithmProvider()
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
BCRYPT_ALG_HANDLE* handle = GetCryptHandle_Sha256(); BCRYPT_ALG_HANDLE* handle = GetCryptHandle_Sha256();
status = BCryptOpenAlgorithmProvider(handle, status = BCryptOpenAlgorithmProvider(
handle,
BCRYPT_SHA256_ALGORITHM, BCRYPT_SHA256_ALGORITHM,
NULL, NULL,
BCRYPT_PROV_DISPATCH); BCRYPT_PROV_DISPATCH);
@ -934,7 +955,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
DEBUG_VERBOSE("Beginning driver entry routine..."); DEBUG_VERBOSE("Beginning driver entry routine...");
status = ImpIoCreateDevice(DriverObject, status = ImpIoCreateDevice(
DriverObject,
sizeof(DRIVER_CONFIG), sizeof(DRIVER_CONFIG),
&g_DeviceName, &g_DeviceName,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_UNKNOWN,
@ -958,7 +980,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
status = DrvLoadInitialiseDriverConfig(DriverObject, RegistryPath); status = DrvLoadInitialiseDriverConfig(DriverObject, RegistryPath);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("InitialiseDriverConfigOnDriverEntry failed with status %x", DEBUG_ERROR(
"InitialiseDriverConfigOnDriverEntry failed with status %x",
status); status);
DrvUnloadFreeConfigStrings(); DrvUnloadFreeConfigStrings();
ImpIoDeleteDevice(GetDecryptedDriverConfig()->device_object); ImpIoDeleteDevice(GetDecryptedDriverConfig()->device_object);
@ -975,8 +998,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
return status; return status;
} }
status = status = IoCreateSymbolicLink(
IoCreateSymbolicLink(GetDecryptedDriverConfig()->device_symbolic_link, GetDecryptedDriverConfig()->device_symbolic_link,
GetDecryptedDriverConfig()->device_name); GetDecryptedDriverConfig()->device_name);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
@ -1001,7 +1024,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
status = InitialiseHashingAlgorithmProvider(); status = InitialiseHashingAlgorithmProvider();
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("InitialiseHashingAlgorithmProvider failed with status %x", DEBUG_ERROR(
"InitialiseHashingAlgorithmProvider failed with status %x",
status); status);
DrvUnloadFreeConfigStrings(); DrvUnloadFreeConfigStrings();
DrvUnloadFreeTimerObject(); DrvUnloadFreeTimerObject();

View file

@ -1,9 +1,9 @@
#include "hv.h" #include "hv.h"
#include <intrin.h>
#include "imports.h"
#include "common.h" #include "common.h"
#include "imports.h"
#include "io.h" #include "io.h"
#include <intrin.h>
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -103,7 +103,8 @@ PerformVirtualizationDetection(_Inout_ PIRP Irp)
Irp->IoStatus.Information = sizeof(HYPERVISOR_DETECTION_REPORT); Irp->IoStatus.Information = sizeof(HYPERVISOR_DETECTION_REPORT);
IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, IntCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&report, &report,
sizeof(HYPERVISOR_DETECTION_REPORT)); sizeof(HYPERVISOR_DETECTION_REPORT));

View file

@ -1,8 +1,8 @@
#include "hw.h" #include "hw.h"
#include "modules.h"
#include "crypt.h" #include "crypt.h"
#include "imports.h" #include "imports.h"
#include "modules.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -15,8 +15,8 @@ USHORT FLAGGED_DEVICE_IDS[FLAGGED_DEVICE_ID_COUNT] = {
0x0666, // default PCIe Squirrel DeviceID (used by PCI Leech) 0x0666, // default PCIe Squirrel DeviceID (used by PCI Leech)
0xffff}; 0xffff};
typedef NTSTATUS (*PCI_DEVICE_CALLBACK)(_In_ PDEVICE_OBJECT DeviceObject, typedef NTSTATUS (*PCI_DEVICE_CALLBACK)(
_In_opt_ PVOID Context); _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context);
/* /*
* Every PCI device has a set of registers commonly referred to as the PCI * Every PCI device has a set of registers commonly referred to as the PCI
@ -66,7 +66,8 @@ typedef NTSTATUS (*PCI_DEVICE_CALLBACK)(_In_ PDEVICE_OBJECT DeviceObject,
*/ */
STATIC STATIC
NTSTATUS NTSTATUS
QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject, QueryPciDeviceConfigurationSpace(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ UINT32 Offset, _In_ UINT32 Offset,
_Out_opt_ PVOID Buffer, _Out_opt_ PVOID Buffer,
_In_ UINT32 BufferLength) _In_ UINT32 BufferLength)
@ -87,7 +88,13 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
* request is completed * request is completed
*/ */
irp = IoBuildSynchronousFsdRequest( irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP, DeviceObject, NULL, 0, NULL, &event, &io); IRP_MJ_PNP,
DeviceObject,
NULL,
0,
NULL,
&event,
&io);
if (!irp) { if (!irp) {
DEBUG_ERROR("IoBuildSynchronousFsdRequest failed with no status."); DEBUG_ERROR("IoBuildSynchronousFsdRequest failed with no status.");
@ -109,7 +116,8 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
} }
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("Failed to read configuration space with status %x", DEBUG_ERROR(
"Failed to read configuration space with status %x",
status); status);
return status; return status;
@ -120,7 +128,8 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
*/ */
STATIC STATIC
NTSTATUS NTSTATUS
EnumerateDriverObjectDeviceObjects(_In_ PDRIVER_OBJECT DriverObject, EnumerateDriverObjectDeviceObjects(
_In_ PDRIVER_OBJECT DriverObject,
_Out_ PDEVICE_OBJECT** DeviceObjectArray, _Out_ PDEVICE_OBJECT** DeviceObjectArray,
_Out_ PUINT32 ArrayEntries) _Out_ PUINT32 ArrayEntries)
{ {
@ -135,7 +144,8 @@ EnumerateDriverObjectDeviceObjects(_In_ PDRIVER_OBJECT DriverObject,
status = IoEnumerateDeviceObjectList(DriverObject, NULL, 0, &object_count); status = IoEnumerateDeviceObjectList(DriverObject, NULL, 0, &object_count);
if (status != STATUS_BUFFER_TOO_SMALL) { if (status != STATUS_BUFFER_TOO_SMALL) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x", DEBUG_ERROR(
"IoEnumerateDeviceObjectList failed with status %x",
status); status);
return status; return status;
} }
@ -147,16 +157,21 @@ EnumerateDriverObjectDeviceObjects(_In_ PDRIVER_OBJECT DriverObject,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
status = IoEnumerateDeviceObjectList( status = IoEnumerateDeviceObjectList(
DriverObject, buffer, buffer_size, &object_count); DriverObject,
buffer,
buffer_size,
&object_count);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x", DEBUG_ERROR(
"IoEnumerateDeviceObjectList failed with status %x",
status); status);
ExFreePoolWithTag(buffer, POOL_TAG_HW); ExFreePoolWithTag(buffer, POOL_TAG_HW);
return status; return status;
} }
DEBUG_VERBOSE("EnumerateDriverObjectDeviceObjects: Object Count: %lx", DEBUG_VERBOSE(
"EnumerateDriverObjectDeviceObjects: Object Count: %lx",
object_count); object_count);
*DeviceObjectArray = buffer; *DeviceObjectArray = buffer;
@ -195,8 +210,8 @@ IsDeviceObjectValidPdo(_In_ PDEVICE_OBJECT DeviceObject)
* given the PCI FDO which is called pci.sys. * given the PCI FDO which is called pci.sys.
*/ */
NTSTATUS NTSTATUS
EnumeratePciDeviceObjects(_In_ PCI_DEVICE_CALLBACK CallbackRoutine, EnumeratePciDeviceObjects(
_In_opt_ PVOID Context) _In_ PCI_DEVICE_CALLBACK CallbackRoutine, _In_opt_ PVOID Context)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
UNICODE_STRING pci = RTL_CONSTANT_STRING(L"\\Driver\\pci"); UNICODE_STRING pci = RTL_CONSTANT_STRING(L"\\Driver\\pci");
@ -208,16 +223,20 @@ EnumeratePciDeviceObjects(_In_ PCI_DEVICE_CALLBACK CallbackRoutine,
status = GetDriverObjectByDriverName(&pci, &pci_driver_object); status = GetDriverObjectByDriverName(&pci, &pci_driver_object);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GetDriverObjectByDriverName failed with status %x", DEBUG_ERROR(
"GetDriverObjectByDriverName failed with status %x",
status); status);
return status; return status;
} }
status = EnumerateDriverObjectDeviceObjects( status = EnumerateDriverObjectDeviceObjects(
pci_driver_object, &pci_device_objects, &pci_device_objects_count); pci_driver_object,
&pci_device_objects,
&pci_device_objects_count);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("EnumerateDriverObjectDeviceObjects failed with status %x", DEBUG_ERROR(
"EnumerateDriverObjectDeviceObjects failed with status %x",
status); status);
return status; return status;
} }
@ -260,8 +279,8 @@ IsPciConfigurationSpaceFlagged(_In_ PPCI_COMMON_HEADER Configuration)
STATIC STATIC
VOID VOID
ReportBlacklistedPcieDevice(_In_ PDEVICE_OBJECT DeviceObject, ReportBlacklistedPcieDevice(
_In_ PPCI_COMMON_HEADER Header) _In_ PDEVICE_OBJECT DeviceObject, _In_ PPCI_COMMON_HEADER Header)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 packet_size = CryptRequestRequiredBufferLength( UINT32 packet_size = CryptRequestRequiredBufferLength(
@ -300,22 +319,28 @@ PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
PCI_COMMON_HEADER header = {0}; PCI_COMMON_HEADER header = {0};
status = QueryPciDeviceConfigurationSpace( status = QueryPciDeviceConfigurationSpace(
DeviceObject, PCI_VENDOR_ID_OFFSET, &header, sizeof(PCI_COMMON_HEADER)); DeviceObject,
PCI_VENDOR_ID_OFFSET,
&header,
sizeof(PCI_COMMON_HEADER));
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("QueryPciDeviceConfigurationSpace failed with status %x", DEBUG_ERROR(
"QueryPciDeviceConfigurationSpace failed with status %x",
status); status);
return status; return status;
} }
if (IsPciConfigurationSpaceFlagged(&header)) { if (IsPciConfigurationSpaceFlagged(&header)) {
DEBUG_VERBOSE("Flagged DeviceID found. Device: %llx, DeviceId: %lx", DEBUG_VERBOSE(
"Flagged DeviceID found. Device: %llx, DeviceId: %lx",
(UINT64)DeviceObject, (UINT64)DeviceObject,
header.DeviceID); header.DeviceID);
ReportBlacklistedPcieDevice(DeviceObject, &header); ReportBlacklistedPcieDevice(DeviceObject, &header);
} }
else { else {
DEBUG_VERBOSE("Device: %llx, DeviceID: %lx, VendorID: %lx", DEBUG_VERBOSE(
"Device: %llx, DeviceID: %lx, VendorID: %lx",
DeviceObject, DeviceObject,
header.DeviceID, header.DeviceID,
header.VendorID); header.VendorID);

View file

@ -1,21 +1,21 @@
#include "integrity.h" #include "integrity.h"
#include "common.h"
#include "driver.h"
#include "modules.h"
#include "callbacks.h" #include "callbacks.h"
#include "io.h" #include "common.h"
#include "crypt.h"
#include "driver.h"
#include "imports.h" #include "imports.h"
#include "io.h"
#include "modules.h"
#include "pe.h"
#include "session.h" #include "session.h"
#include "util.h" #include "util.h"
#include "pe.h"
#include "crypt.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
#include <bcrypt.h> #include <bcrypt.h>
#include <initguid.h>
#include <devpkey.h> #include <devpkey.h>
#include <initguid.h>
/* Header for a buffer that contains an array of sections copied from a module /* Header for a buffer that contains an array of sections copied from a module
*/ */
@ -165,7 +165,8 @@ GetDriverImageSize(_Inout_ PIRP Irp)
Irp->IoStatus.Information = sizeof(ULONG); Irp->IoStatus.Information = sizeof(ULONG);
IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, IntCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&driver_info->ImageSize, &driver_info->ImageSize,
sizeof(ULONG)); sizeof(ULONG));
@ -179,8 +180,8 @@ end:
STATIC STATIC
NTSTATUS NTSTATUS
GetModuleInformationByName(_Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo, GetModuleInformationByName(
_In_ LPCSTR ModuleName) _Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo, _In_ LPCSTR ModuleName)
{ {
PAGED_CODE(); PAGED_CODE();
@ -210,7 +211,8 @@ GetModuleInformationByName(_Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo,
ModuleInfo->ImageBase = driver_info->ImageBase; ModuleInfo->ImageBase = driver_info->ImageBase;
ModuleInfo->ImageSize = driver_info->ImageSize; ModuleInfo->ImageSize = driver_info->ImageSize;
IntCopyMemory(ModuleInfo->FullPathName, IntCopyMemory(
ModuleInfo->FullPathName,
driver_info->FullPathName, driver_info->FullPathName,
sizeof(ModuleInfo->FullPathName)); sizeof(ModuleInfo->FullPathName));
@ -249,7 +251,8 @@ GetSectionTotalPacketSize(_In_ PIMAGE_SECTION_HEADER Section)
FORCEINLINE FORCEINLINE
STATIC STATIC
VOID VOID
InitIntegrityCheckHeader(_Out_ PINTEGRITY_CHECK_HEADER Header, InitIntegrityCheckHeader(
_Out_ PINTEGRITY_CHECK_HEADER Header,
_In_ UINT32 SectionCount, _In_ UINT32 SectionCount,
_In_ UINT32 TotalSize) _In_ UINT32 TotalSize)
{ {
@ -259,7 +262,8 @@ InitIntegrityCheckHeader(_Out_ PINTEGRITY_CHECK_HEADER Header,
STATIC STATIC
NTSTATUS NTSTATUS
StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer, StoreModuleExecutableRegionsInBuffer(
_Out_ PVOID* Buffer,
_In_ PVOID ModuleBase, _In_ PVOID ModuleBase,
_In_ SIZE_T ModuleSize, _In_ SIZE_T ModuleSize,
_Out_ PSIZE_T BytesWritten, _Out_ PSIZE_T BytesWritten,
@ -292,7 +296,8 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
* the file. * the file.
*/ */
*BytesWritten = 0; *BytesWritten = 0;
*Buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, *Buffer = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
ModuleSize + sizeof(INTEGRITY_CHECK_HEADER), ModuleSize + sizeof(INTEGRITY_CHECK_HEADER),
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -324,7 +329,8 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
} }
address.VirtualAddress = section; address.VirtualAddress = section;
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size, status = ImpMmCopyMemory(
(UINT64)buffer_base + total_packet_size,
address, address,
sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER),
MM_COPY_MEMORY_VIRTUAL, MM_COPY_MEMORY_VIRTUAL,
@ -337,7 +343,8 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
} }
address.VirtualAddress = (UINT64)ModuleBase + section->PointerToRawData; address.VirtualAddress = (UINT64)ModuleBase + section->PointerToRawData;
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size + status = ImpMmCopyMemory(
(UINT64)buffer_base + total_packet_size +
sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER),
address, address,
section->SizeOfRawData, section->SizeOfRawData,
@ -355,7 +362,8 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
section++; section++;
} }
InitIntegrityCheckHeader(&header, InitIntegrityCheckHeader(
&header,
num_executable_sections, num_executable_sections,
total_packet_size); total_packet_size);
@ -366,7 +374,8 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
STATIC STATIC
NTSTATUS NTSTATUS
MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE SectionHandle, MapDiskImageIntoVirtualAddressSpace(
_Inout_ PHANDLE SectionHandle,
_Out_ PVOID* Section, _Out_ PVOID* Section,
_In_ PUNICODE_STRING Path, _In_ PUNICODE_STRING Path,
_Out_ PSIZE_T Size) _Out_ PSIZE_T Size)
@ -399,7 +408,8 @@ MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE SectionHandle,
* Its important that we set the SEC_IMAGE flag with the PAGE_READONLY * Its important that we set the SEC_IMAGE flag with the PAGE_READONLY
* flag as we are mapping an executable image. * flag as we are mapping an executable image.
*/ */
status = ImpZwCreateSection(SectionHandle, status = ImpZwCreateSection(
SectionHandle,
SECTION_ALL_ACCESS, SECTION_ALL_ACCESS,
&oa, &oa,
NULL, NULL,
@ -425,7 +435,8 @@ MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE SectionHandle,
* for us, meaning the mapped image will be identical to the in memory * for us, meaning the mapped image will be identical to the in memory
* image. * image.
*/ */
status = ImpZwMapViewOfSection(*SectionHandle, status = ImpZwMapViewOfSection(
*SectionHandle,
ZwCurrentProcess(), ZwCurrentProcess(),
Section, Section,
NULL, NULL,
@ -466,14 +477,16 @@ RetrieveInMemoryModuleExecutableSections(_Inout_ PIRP Irp)
return status; return status;
} }
status = StoreModuleExecutableRegionsInBuffer(&buffer, status = StoreModuleExecutableRegionsInBuffer(
&buffer,
module_info.ImageBase, module_info.ImageBase,
module_info.ImageSize, module_info.ImageSize,
&bytes_written, &bytes_written,
FALSE); FALSE);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("StoreModuleExecutableRegionsInBuffe failed with status %x", DEBUG_ERROR(
"StoreModuleExecutableRegionsInBuffe failed with status %x",
status); status);
return status; return status;
} }
@ -553,7 +566,8 @@ GetNextSMBIOSStructureInTable(_Inout_ PSMBIOS_TABLE_HEADER* CurrentStructure)
*/ */
STATIC STATIC
NTSTATUS NTSTATUS
GetStringAtIndexFromSMBIOSTable(_In_ PSMBIOS_TABLE_HEADER Table, GetStringAtIndexFromSMBIOSTable(
_In_ PSMBIOS_TABLE_HEADER Table,
_In_ UINT32 Index, _In_ UINT32 Index,
_In_ PVOID Buffer, _In_ PVOID Buffer,
_In_ SIZE_T BufferSize) _In_ SIZE_T BufferSize)
@ -614,7 +628,8 @@ GetSmbiosTableHeader(_In_ PRAW_SMBIOS_DATA Data)
} }
NTSTATUS NTSTATUS
ParseSMBIOSTable(_Out_ PVOID Buffer, ParseSMBIOSTable(
_Out_ PVOID Buffer,
_In_ SIZE_T BufferSize, _In_ SIZE_T BufferSize,
_In_ SMBIOS_TABLE_INDEX TableIndex, _In_ SMBIOS_TABLE_INDEX TableIndex,
_In_ ULONG TableSubIndex) _In_ ULONG TableSubIndex)
@ -644,21 +659,24 @@ ParseSMBIOSTable(_Out_ PVOID Buffer,
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
buffer_size, buffer_size,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
if (!buffer) if (!buffer)
return STATUS_MEMORY_NOT_ALLOCATED; return STATUS_MEMORY_NOT_ALLOCATED;
status = ImpExGetSystemFirmwareTable(SMBIOS_TABLE, status = ImpExGetSystemFirmwareTable(
SMBIOS_TABLE,
NULL, NULL,
buffer, buffer,
buffer_size, buffer_size,
&bytes_copied); &bytes_copied);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ExGetSystemFirmwareTable call 2 failed with status %x", DEBUG_ERROR(
"ExGetSystemFirmwareTable call 2 failed with status %x",
status); status);
goto end; goto end;
} }
@ -678,13 +696,15 @@ ParseSMBIOSTable(_Out_ PVOID Buffer,
while (header->Type != TableIndex) while (header->Type != TableIndex)
GetNextSMBIOSStructureInTable(&header); GetNextSMBIOSStructureInTable(&header);
status = GetStringAtIndexFromSMBIOSTable(header, status = GetStringAtIndexFromSMBIOSTable(
header,
TableSubIndex, TableSubIndex,
Buffer, Buffer,
BufferSize); BufferSize);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GetStringAtIndexFromSMBIOSTable failed with status %x", DEBUG_ERROR(
"GetStringAtIndexFromSMBIOSTable failed with status %x",
status); status);
goto end; goto end;
} }
@ -699,7 +719,8 @@ end:
STATIC STATIC
NTSTATUS NTSTATUS
ComputeHashOfSections(_In_ PIMAGE_SECTION_HEADER DiskSection, ComputeHashOfSections(
_In_ PIMAGE_SECTION_HEADER DiskSection,
_In_ PIMAGE_SECTION_HEADER MemorySection, _In_ PIMAGE_SECTION_HEADER MemorySection,
_Out_ PVOID* DiskHash, _Out_ PVOID* DiskHash,
_Out_ PULONG DiskHashSize, _Out_ PULONG DiskHashSize,
@ -767,7 +788,8 @@ ReportInvalidProcessModule(_In_ PPROCESS_MODULE_INFORMATION Module)
report->image_base = Module->module_base; report->image_base = Module->module_base;
report->image_size = Module->module_size; report->image_size = Module->module_size;
IntCopyMemory(report->module_path, IntCopyMemory(
report->module_path,
Module->module_path, Module->module_path,
sizeof(report->module_path)); sizeof(report->module_path));
@ -842,7 +864,8 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
*/ */
ImpKeStackAttachProcess(process, &apc_state); ImpKeStackAttachProcess(process, &apc_state);
status = StoreModuleExecutableRegionsInBuffer(&memory_buffer, status = StoreModuleExecutableRegionsInBuffer(
&memory_buffer,
module_info->module_base, module_info->module_base,
module_info->module_size, module_info->module_size,
&bytes_written, &bytes_written,
@ -857,18 +880,21 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
goto end; goto end;
} }
status = MapDiskImageIntoVirtualAddressSpace(&section_handle, status = MapDiskImageIntoVirtualAddressSpace(
&section_handle,
&section, &section,
&module_path, &module_path,
&section_size); &section_size);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("MapDiskImageIntoVirtualAddressSpace failed with status %x", DEBUG_ERROR(
"MapDiskImageIntoVirtualAddressSpace failed with status %x",
status); status);
goto end; goto end;
} }
status = StoreModuleExecutableRegionsInBuffer(&disk_buffer, status = StoreModuleExecutableRegionsInBuffer(
&disk_buffer,
section, section,
section_size, section_size,
&bytes_written, &bytes_written,
@ -881,7 +907,8 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp)
goto end; goto end;
} }
status = ComputeHashOfSections(&memory_buffer->section_header, status = ComputeHashOfSections(
&memory_buffer->section_header,
&disk_buffer->section_header, &disk_buffer->section_header,
&disk_hash, &disk_hash,
&disk_hash_size, &disk_hash_size,
@ -920,7 +947,8 @@ end:
} }
NTSTATUS NTSTATUS
HashUserModule(_In_ PPROCESS_MAP_MODULE_ENTRY Entry, HashUserModule(
_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
_Out_ PVOID OutBuffer, _Out_ PVOID OutBuffer,
_In_ UINT32 OutBufferSize) _In_ UINT32 OutBufferSize)
{ {
@ -939,7 +967,8 @@ HashUserModule(_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
*/ */
ImpKeStackAttachProcess(session->process, &apc_state); ImpKeStackAttachProcess(session->process, &apc_state);
status = StoreModuleExecutableRegionsInBuffer(&memory_buffer, status = StoreModuleExecutableRegionsInBuffer(
&memory_buffer,
Entry->base, Entry->base,
Entry->size, Entry->size,
&bytes_written, &bytes_written,
@ -954,7 +983,8 @@ HashUserModule(_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
goto end; goto end;
} }
status = CryptHashBuffer_sha256(memory_buffer->section_base, status = CryptHashBuffer_sha256(
memory_buffer->section_base,
memory_buffer->section_header.SizeOfRawData, memory_buffer->section_header.SizeOfRawData,
&memory_hash, &memory_hash,
&memory_hash_size); &memory_hash_size);
@ -1001,7 +1031,8 @@ GetStorageDescriptorSerialLength(_In_ PCHAR SerialNumber)
FORCEINLINE FORCEINLINE
STATIC STATIC
VOID VOID
InitStorageProperties(_Out_ PSTORAGE_PROPERTY_QUERY Query, InitStorageProperties(
_Out_ PSTORAGE_PROPERTY_QUERY Query,
_In_ STORAGE_PROPERTY_ID PropertyId, _In_ STORAGE_PROPERTY_ID PropertyId,
_In_ STORAGE_QUERY_TYPE QueryType) _In_ STORAGE_QUERY_TYPE QueryType)
{ {
@ -1014,8 +1045,8 @@ InitStorageProperties(_Out_ PSTORAGE_PROPERTY_QUERY Query,
* use the command "wmic diskdrive" check in console. * use the command "wmic diskdrive" check in console.
*/ */
NTSTATUS NTSTATUS
GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, GetHardDiskDriveSerialNumber(
_In_ SIZE_T ConfigDrive0MaxSize) _Inout_ PVOID ConfigDrive0Serial, _In_ SIZE_T ConfigDrive0MaxSize)
{ {
PAGED_CODE(); PAGED_CODE();
@ -1036,13 +1067,15 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial,
* No need to use the flag OBJ_FORCE_ACCESS_CHECK since we arent passing * No need to use the flag OBJ_FORCE_ACCESS_CHECK since we arent passing
* a handle given to us from usermode. * a handle given to us from usermode.
*/ */
InitializeObjectAttributes(&attributes, InitializeObjectAttributes(
&attributes,
&path, &path,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL,
NULL); NULL);
status = ImpZwOpenFile(&handle, status = ImpZwOpenFile(
&handle,
GENERIC_READ, GENERIC_READ,
&attributes, &attributes,
&status_block, &status_block,
@ -1050,14 +1083,16 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial,
NULL); NULL);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ZwOpenFile on PhysicalDrive0 failed with status %x", DEBUG_ERROR(
"ZwOpenFile on PhysicalDrive0 failed with status %x",
status); status);
goto end; goto end;
} }
InitStorageProperties(&query, StorageDeviceProperty, PropertyStandardQuery); InitStorageProperties(&query, StorageDeviceProperty, PropertyStandardQuery);
status = ImpZwDeviceIoControlFile(handle, status = ImpZwDeviceIoControlFile(
handle,
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -1069,12 +1104,14 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial,
sizeof(STORAGE_DESCRIPTOR_HEADER)); sizeof(STORAGE_DESCRIPTOR_HEADER));
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ZwDeviceIoControlFile first call failed with status %x", DEBUG_ERROR(
"ZwDeviceIoControlFile first call failed with status %x",
status); status);
goto end; goto end;
} }
descriptor = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, descriptor = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
header.Size, header.Size,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -1083,7 +1120,8 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial,
goto end; goto end;
} }
status = ImpZwDeviceIoControlFile(handle, status = ImpZwDeviceIoControlFile(
handle,
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -1095,7 +1133,8 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial,
header.Size); header.Size);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ZwDeviceIoControlFile second call failed with status %x", DEBUG_ERROR(
"ZwDeviceIoControlFile second call failed with status %x",
status); status);
goto end; goto end;
} }
@ -1124,7 +1163,8 @@ end:
return status; return status;
} }
PVOID PVOID
ScanForSignature(_In_ PVOID BaseAddress, ScanForSignature(
_In_ PVOID BaseAddress,
_In_ SIZE_T MaxLength, _In_ SIZE_T MaxLength,
_In_ LPCSTR Signature, _In_ LPCSTR Signature,
_In_ SIZE_T SignatureLength) _In_ SIZE_T SignatureLength)
@ -1210,8 +1250,8 @@ MeasureReads(_In_ PVOID Address, _In_ ULONG Count)
*/ */
STATIC STATIC
NTSTATUS NTSTATUS
GetAverageReadTimeAtRoutine(_In_ PVOID RoutineAddress, GetAverageReadTimeAtRoutine(
_Out_ PUINT64 AverageTime) _In_ PVOID RoutineAddress, _Out_ PUINT64 AverageTime)
{ {
if (!RoutineAddress || !AverageTime) if (!RoutineAddress || !AverageTime)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
@ -1302,7 +1342,8 @@ InitiateEptFunctionAddressArrays()
STATIC STATIC
VOID VOID
ReportEptHook(_In_ UINT64 ControlAverage, ReportEptHook(
_In_ UINT64 ControlAverage,
_In_ UINT64 ReadAverage, _In_ UINT64 ReadAverage,
_In_ WCHAR FunctionName) _In_ WCHAR FunctionName)
{ {
@ -1324,7 +1365,8 @@ ReportEptHook(_In_ UINT64 ControlAverage,
RtlInitUnicodeString(&string, FunctionName); RtlInitUnicodeString(&string, FunctionName);
status = UnicodeToCharBufString(&string, status = UnicodeToCharBufString(
&string,
report->function_name, report->function_name,
sizeof(report->function_name)); sizeof(report->function_name));
@ -1358,17 +1400,20 @@ DetectEptHooksInKeyFunctions()
status = InitiateEptFunctionAddressArrays(); status = InitiateEptFunctionAddressArrays();
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("InitiateEptFunctionAddressArrays failed with status %x", DEBUG_ERROR(
"InitiateEptFunctionAddressArrays failed with status %x",
status); status);
return status; return status;
} }
for (UINT32 index = 0; index < EPT_CONTROL_FUNCTIONS_COUNT; index++) { for (UINT32 index = 0; index < EPT_CONTROL_FUNCTIONS_COUNT; index++) {
status = GetAverageReadTimeAtRoutine(CONTROL_FUNCTION_ADDRESSES[index], status = GetAverageReadTimeAtRoutine(
CONTROL_FUNCTION_ADDRESSES[index],
&instruction_time); &instruction_time);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("DetectEptPresentOnFunction failed with status %x", DEBUG_ERROR(
"DetectEptPresentOnFunction failed with status %x",
status); status);
control_fails += 1; control_fails += 1;
continue; continue;
@ -1387,12 +1432,13 @@ DetectEptHooksInKeyFunctions()
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
for (UINT32 index = 0; index < EPT_PROTECTED_FUNCTIONS_COUNT; index++) { for (UINT32 index = 0; index < EPT_PROTECTED_FUNCTIONS_COUNT; index++) {
status = status = GetAverageReadTimeAtRoutine(
GetAverageReadTimeAtRoutine(PROTECTED_FUNCTION_ADDRESSES[index], PROTECTED_FUNCTION_ADDRESSES[index],
&instruction_time); &instruction_time);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("DetectEptPresentOnFunction failed with status %x", DEBUG_ERROR(
"DetectEptPresentOnFunction failed with status %x",
status); status);
continue; continue;
} }
@ -1405,7 +1451,8 @@ DetectEptHooksInKeyFunctions()
"EPT hook detected at function: %llx with execution time of: %llx", "EPT hook detected at function: %llx with execution time of: %llx",
PROTECTED_FUNCTION_ADDRESSES[index], PROTECTED_FUNCTION_ADDRESSES[index],
instruction_time); instruction_time);
ReportEptHook(control_average, ReportEptHook(
control_average,
instruction_time, instruction_time,
PROTECTED_FUNCTION_ADDRESSES[index]); PROTECTED_FUNCTION_ADDRESSES[index]);
} }
@ -1431,7 +1478,8 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context)
STATIC STATIC
NTSTATUS NTSTATUS
StoreModuleExecutableRegionsx86(_In_ PRTL_MODULE_EXTENDED_INFO Module, StoreModuleExecutableRegionsx86(
_In_ PRTL_MODULE_EXTENDED_INFO Module,
_In_ PVOID* Buffer, _In_ PVOID* Buffer,
_In_ PULONG BufferSize) _In_ PULONG BufferSize)
{ {
@ -1446,7 +1494,8 @@ StoreModuleExecutableRegionsx86(_In_ PRTL_MODULE_EXTENDED_INFO Module,
ImpKeStackAttachProcess(process, &apc_state); ImpKeStackAttachProcess(process, &apc_state);
status = StoreModuleExecutableRegionsInBuffer(Buffer, status = StoreModuleExecutableRegionsInBuffer(
Buffer,
Module->ImageBase, Module->ImageBase,
Module->ImageSize, Module->ImageSize,
BufferSize, BufferSize,
@ -1471,8 +1520,8 @@ Enablex86Hashing(_In_ PDRIVER_LIST_HEAD Head)
} }
VOID VOID
DeferredModuleHashingCallback(_In_ PDEVICE_OBJECT DeviceObject, DeferredModuleHashingCallback(
_In_opt_ PVOID Context) _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
{ {
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(DeviceObject);
@ -1541,7 +1590,8 @@ HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash)
status = ImpRtlAnsiStringToUnicodeString(&path, &ansi_string, TRUE); status = ImpRtlAnsiStringToUnicodeString(&path, &ansi_string, TRUE);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("RtlAnsiStringToUnicodeString failed with status %x", DEBUG_ERROR(
"RtlAnsiStringToUnicodeString failed with status %x",
status); status);
return status; return status;
} }
@ -1568,12 +1618,14 @@ HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash)
* Once the WinLogon process has started, we can then hash new * Once the WinLogon process has started, we can then hash new
* x86 modules. * x86 modules.
*/ */
status = StoreModuleExecutableRegionsx86(Module, status = StoreModuleExecutableRegionsx86(
Module,
(PVOID)&memory_buffer, (PVOID)&memory_buffer,
&memory_buffer_size); &memory_buffer_size);
} }
else { else {
status = StoreModuleExecutableRegionsInBuffer((PVOID)&memory_buffer, status = StoreModuleExecutableRegionsInBuffer(
(PVOID)&memory_buffer,
Module->ImageBase, Module->ImageBase,
Module->ImageSize, Module->ImageSize,
&memory_buffer_size, &memory_buffer_size,
@ -1587,7 +1639,8 @@ HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash)
goto end; goto end;
} }
status = CryptHashBuffer_sha256(memory_buffer->section_base, status = CryptHashBuffer_sha256(
memory_buffer->section_base,
memory_buffer->section_header.SizeOfRawData, memory_buffer->section_header.SizeOfRawData,
&memory_hash, &memory_hash,
&memory_hash_size); &memory_hash_size);
@ -1639,7 +1692,8 @@ ReportModifiedSystemImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
report->image_base = Module->ImageBase; report->image_base = Module->ImageBase;
report->image_size = Module->ImageSize; report->image_size = Module->ImageSize;
IntCopyMemory(report->path_name, IntCopyMemory(
report->path_name,
Module->FullPathName, Module->FullPathName,
sizeof(report->path_name)); sizeof(report->path_name));
@ -1661,7 +1715,8 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
PDRIVER_LIST_ENTRY entry = NULL; PDRIVER_LIST_ENTRY entry = NULL;
PVOID hash = NULL; PVOID hash = NULL;
hash = ExAllocatePool2(POOL_FLAG_NON_PAGED, hash = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
SHA_256_HASH_LENGTH, SHA_256_HASH_LENGTH,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -1698,11 +1753,13 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
} }
if (CompareHashes(hash, entry->text_hash, SHA_256_HASH_LENGTH)) { if (CompareHashes(hash, entry->text_hash, SHA_256_HASH_LENGTH)) {
DEBUG_VERBOSE("Module: %s text regions are valid.", DEBUG_VERBOSE(
"Module: %s text regions are valid.",
Module->FullPathName); Module->FullPathName);
} }
else { else {
DEBUG_WARNING("**!!** Module: %s text regions are NOT valid **!!**", DEBUG_WARNING(
"**!!** Module: %s text regions are NOT valid **!!**",
Module->FullPathName); Module->FullPathName);
ReportModifiedSystemImage(Module); ReportModifiedSystemImage(Module);
} }
@ -1734,7 +1791,8 @@ ReportModifiedSelfDriverImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
packet->image_base = Module->ImageBase; packet->image_base = Module->ImageBase;
packet->image_size = Module->ImageSize; packet->image_size = Module->ImageSize;
IntCopyMemory(packet->path_name, IntCopyMemory(
packet->path_name,
Module->FullPathName, Module->FullPathName,
sizeof(packet->path_name)); sizeof(packet->path_name));
@ -1775,7 +1833,8 @@ ValidateOurDriverImage()
goto end; goto end;
} }
memory_hash = ExAllocatePool2(POOL_FLAG_NON_PAGED, memory_hash = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
SHA_256_HASH_LENGTH, SHA_256_HASH_LENGTH,
POOL_TAG_INTEGRITY); POOL_TAG_INTEGRITY);
@ -1861,8 +1920,8 @@ GetCurrentVerificationIndex(_In_ PSYS_MODULE_VAL_CONTEXT Context)
FORCEINLINE FORCEINLINE
STATIC STATIC
UINT32 UINT32
GetCurrentVerificationMaxIndex(_In_ PSYS_MODULE_VAL_CONTEXT Context, GetCurrentVerificationMaxIndex(
_In_ UINT32 Count) _In_ PSYS_MODULE_VAL_CONTEXT Context, _In_ UINT32 Count)
{ {
return Count + Context->block_size; return Count + Context->block_size;
} }
@ -1870,16 +1929,16 @@ GetCurrentVerificationMaxIndex(_In_ PSYS_MODULE_VAL_CONTEXT Context,
FORCEINLINE FORCEINLINE
STATIC STATIC
VOID VOID
UpdateCurrentVerificationIndex(_In_ PSYS_MODULE_VAL_CONTEXT Context, UpdateCurrentVerificationIndex(
_In_ UINT32 Count) _In_ PSYS_MODULE_VAL_CONTEXT Context, _In_ UINT32 Count)
{ {
InterlockedExchange(&Context->current_count, Count); InterlockedExchange(&Context->current_count, Count);
} }
STATIC STATIC
VOID VOID
SystemModuleVerificationDispatchFunction(_In_ PDEVICE_OBJECT DeviceObject, SystemModuleVerificationDispatchFunction(
_In_ PSYS_MODULE_VAL_CONTEXT Context) _In_ PDEVICE_OBJECT DeviceObject, _In_ PSYS_MODULE_VAL_CONTEXT Context)
{ {
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(DeviceObject);
@ -1920,7 +1979,8 @@ SystemModuleVerificationDispatchFunction(_In_ PDEVICE_OBJECT DeviceObject,
FORCEINLINE FORCEINLINE
STATIC STATIC
VOID VOID
InitSysModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT Context, InitSysModuleValidationContext(
_Out_ PSYS_MODULE_VAL_CONTEXT Context,
_In_ PMODULE_DISPATCHER_HEADER DispatcherArray, _In_ PMODULE_DISPATCHER_HEADER DispatcherArray,
_In_ PSYSTEM_MODULES SystemModules) _In_ PSYSTEM_MODULES SystemModules)
{ {
@ -2030,7 +2090,8 @@ DispatchVerificationWorkerThreads(_In_ PSYS_MODULE_VAL_CONTEXT Context)
if (!Context->work_items[index]) if (!Context->work_items[index])
continue; continue;
ImpIoQueueWorkItem(Context->work_items[index], ImpIoQueueWorkItem(
Context->work_items[index],
SystemModuleVerificationDispatchFunction, SystemModuleVerificationDispatchFunction,
DelayedWorkQueue, DelayedWorkQueue,
Context); Context);
@ -2102,7 +2163,8 @@ GetOsVersionInformation(_Out_ PRTL_OSVERSIONINFOW VersionInfo)
VersionInfo->dwOSVersionInfoSize = info.dwOSVersionInfoSize; VersionInfo->dwOSVersionInfoSize = info.dwOSVersionInfoSize;
VersionInfo->dwPlatformId = info.dwPlatformId; VersionInfo->dwPlatformId = info.dwPlatformId;
IntCopyMemory(VersionInfo->szCSDVersion, IntCopyMemory(
VersionInfo->szCSDVersion,
info.szCSDVersion, info.szCSDVersion,
sizeof(VersionInfo->szCSDVersion)); sizeof(VersionInfo->szCSDVersion));
@ -2138,7 +2200,8 @@ CalculateCpuCoreUsage(_In_ UINT32 Core)
kernel_time = *(UINT32*)((UINT64)kpcrb + KPCRB_KERNEL_TIME_OFFSET); kernel_time = *(UINT32*)((UINT64)kpcrb + KPCRB_KERNEL_TIME_OFFSET);
user_time = *(UINT32*)((UINT64)kpcrb + KPCRB_USER_TIME_OFFSET); user_time = *(UINT32*)((UINT64)kpcrb + KPCRB_USER_TIME_OFFSET);
return (100 - (UINT32)(UInt32x32To64(idle_time, 100) / return (
100 - (UINT32)(UInt32x32To64(idle_time, 100) /
(UINT64)(kernel_time + user_time))); (UINT64)(kernel_time + user_time)));
} }
@ -2177,14 +2240,16 @@ STATIC
NTSTATUS NTSTATUS
AllocateHeartbeatObjects(_Inout_ PHEARTBEAT_CONFIGURATION Configuration) AllocateHeartbeatObjects(_Inout_ PHEARTBEAT_CONFIGURATION Configuration)
{ {
Configuration->dpc = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, Configuration->dpc = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(KDPC), sizeof(KDPC),
POOL_TAG_HEARTBEAT); POOL_TAG_HEARTBEAT);
if (!Configuration->dpc) if (!Configuration->dpc)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
Configuration->timer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, Configuration->timer = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(KTIMER), sizeof(KTIMER),
POOL_TAG_HEARTBEAT); POOL_TAG_HEARTBEAT);
@ -2350,7 +2415,8 @@ queue_next:
STATIC STATIC
VOID VOID
HeartbeatDpcRoutine(_In_ PKDPC Dpc, HeartbeatDpcRoutine(
_In_ PKDPC Dpc,
_In_opt_ PVOID DeferredContext, _In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2) _In_opt_ PVOID SystemArgument2)
@ -2364,7 +2430,8 @@ HeartbeatDpcRoutine(_In_ PKDPC Dpc,
PHEARTBEAT_CONFIGURATION config = (PHEARTBEAT_CONFIGURATION)DeferredContext; PHEARTBEAT_CONFIGURATION config = (PHEARTBEAT_CONFIGURATION)DeferredContext;
IoQueueWorkItem(config->work_item, IoQueueWorkItem(
config->work_item,
HeartbeatWorkItem, HeartbeatWorkItem,
NormalWorkQueue, NormalWorkQueue,
config); config);

View file

@ -1,18 +1,18 @@
#include "io.h" #include "io.h"
#include "modules.h"
#include "driver.h"
#include "callbacks.h" #include "callbacks.h"
#include "pool.h" #include "driver.h"
#include "integrity.h" #include "integrity.h"
#include "modules.h"
#include "pool.h"
#include "thread.h" #include "thread.h"
#include "hv.h" #include "hv.h"
#include "imports.h" #include "imports.h"
#include "session.h"
#include "hw.h"
#include "containers/map.h" #include "containers/map.h"
#include "hw.h"
#include "session.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -181,7 +181,9 @@ IrpQueueCompleteDeferredPacket(_In_ PDEFERRED_REPORT Report, _In_ PIRP Irp)
IncrementPacketMetics(queue, type); IncrementPacketMetics(queue, type);
IntCopyMemory( IntCopyMemory(
Irp->AssociatedIrp.SystemBuffer, Report->buffer, Report->buffer_size); Irp->AssociatedIrp.SystemBuffer,
Report->buffer,
Report->buffer_size);
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Report->buffer_size; Irp->IoStatus.Information = Report->buffer_size;
@ -252,7 +254,9 @@ PDEFERRED_REPORT
IrpQueueAllocateDeferredPacket(_In_ PVOID Buffer, _In_ UINT32 BufferSize) IrpQueueAllocateDeferredPacket(_In_ PVOID Buffer, _In_ UINT32 BufferSize)
{ {
PDEFERRED_REPORT report = ImpExAllocatePool2( PDEFERRED_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(DEFERRED_REPORT), REPORT_POOL_TAG); POOL_FLAG_NON_PAGED,
sizeof(DEFERRED_REPORT),
REPORT_POOL_TAG);
if (!report) if (!report)
return NULL; return NULL;
@ -266,9 +270,8 @@ IrpQueueAllocateDeferredPacket(_In_ PVOID Buffer, _In_ UINT32 BufferSize)
STATIC STATIC
VOID VOID
IrpQueueDeferPacket(_In_ PIRP_QUEUE_HEAD Queue, IrpQueueDeferPacket(
_In_ PVOID Buffer, _In_ PIRP_QUEUE_HEAD Queue, _In_ PVOID Buffer, _In_ UINT32 BufferSize)
_In_ UINT32 BufferSize)
{ {
PDEFERRED_REPORT report = NULL; PDEFERRED_REPORT report = NULL;
/* /*
@ -383,7 +386,8 @@ IrpQueueInitialise()
InitializeListHead(&queue->queue); InitializeListHead(&queue->queue);
InitializeListHead(&queue->deferred_reports.head); InitializeListHead(&queue->deferred_reports.head);
status = IoCsqInitialize(&queue->csq, status = IoCsqInitialize(
&queue->csq,
IrpQueueInsert, IrpQueueInsert,
IrpQueueRemove, IrpQueueRemove,
IrpQueuePeekNextEntry, IrpQueuePeekNextEntry,
@ -398,8 +402,8 @@ IrpQueueInitialise()
} }
VOID VOID
SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject, SharedMappingWorkRoutine(
_In_opt_ PVOID Context) _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
HANDLE handle = NULL; HANDLE handle = NULL;
@ -407,7 +411,8 @@ SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject,
InterlockedIncrement(&state->work_item_status); InterlockedIncrement(&state->work_item_status);
DEBUG_VERBOSE("SharedMapping work routine called. OperationId: %lx", DEBUG_VERBOSE(
"SharedMapping work routine called. OperationId: %lx",
state->kernel_buffer->operation_id); state->kernel_buffer->operation_id);
switch (state->kernel_buffer->operation_id) { switch (state->kernel_buffer->operation_id) {
@ -427,7 +432,8 @@ SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject,
DEBUG_INFO( DEBUG_INFO(
"SHARED_STATE_OPERATION_ID: ValidateDriverObjects Received."); "SHARED_STATE_OPERATION_ID: ValidateDriverObjects Received.");
status = ImpPsCreateSystemThread(&handle, status = ImpPsCreateSystemThread(
&handle,
PROCESS_ALL_ACCESS, PROCESS_ALL_ACCESS,
NULL, NULL,
NULL, NULL,
@ -473,7 +479,8 @@ SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject,
status = ValidateOurDriverImage(); status = ValidateOurDriverImage();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("VerifyInMemoryImageVsDiskImage failed with status %x", DEBUG_ERROR(
"VerifyInMemoryImageVsDiskImage failed with status %x",
status); status);
break; break;
@ -494,7 +501,8 @@ SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject,
status = DetectEptHooksInKeyFunctions(); status = DetectEptHooksInKeyFunctions();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("DetectEpthooksInKeyFunctions failed with status %x", DEBUG_ERROR(
"DetectEpthooksInKeyFunctions failed with status %x",
status); status);
break; break;
@ -531,7 +539,8 @@ SharedMappingWorkRoutine(_In_ PDEVICE_OBJECT DeviceObject,
status = ValidateWin32kDispatchTables(); status = ValidateWin32kDispatchTables();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateWin32kDispatchTables failed with status %x", DEBUG_ERROR(
"ValidateWin32kDispatchTables failed with status %x",
status); status);
break; break;
@ -545,7 +554,8 @@ end:
/* again, we want to run our routine at apc level not dispatch level */ /* again, we want to run our routine at apc level not dispatch level */
VOID VOID
SharedMappingDpcRoutine(_In_ PKDPC Dpc, SharedMappingDpcRoutine(
_In_ PKDPC Dpc,
_In_opt_ PVOID DeferredContext, _In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2) _In_opt_ PVOID SystemArgument2)
@ -556,7 +566,10 @@ SharedMappingDpcRoutine(_In_ PKDPC Dpc,
return; return;
IoQueueWorkItem( IoQueueWorkItem(
mapping->work_item, SharedMappingWorkRoutine, NormalWorkQueue, mapping); mapping->work_item,
SharedMappingWorkRoutine,
NormalWorkQueue,
mapping);
} }
#define REPEAT_TIME_15_SEC 30000 #define REPEAT_TIME_15_SEC 30000
@ -603,7 +616,10 @@ SharedMappingInitialiseTimer(_In_ PSHARED_MAPPING Mapping)
KeInitializeDpc(&Mapping->timer_dpc, SharedMappingDpcRoutine, Mapping); KeInitializeDpc(&Mapping->timer_dpc, SharedMappingDpcRoutine, Mapping);
KeInitializeTimer(&Mapping->timer); KeInitializeTimer(&Mapping->timer);
KeSetTimerEx( KeSetTimerEx(
&Mapping->timer, due_time, REPEAT_TIME_15_SEC, &Mapping->timer_dpc); &Mapping->timer,
due_time,
REPEAT_TIME_15_SEC,
&Mapping->timer_dpc);
DEBUG_VERBOSE("Initialised shared mapping event timer."); DEBUG_VERBOSE("Initialised shared mapping event timer.");
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -611,7 +627,8 @@ SharedMappingInitialiseTimer(_In_ PSHARED_MAPPING Mapping)
STATIC STATIC
VOID VOID
InitSharedMappingStructure(_Out_ PSHARED_MAPPING Mapping, InitSharedMappingStructure(
_Out_ PSHARED_MAPPING Mapping,
_In_ PVOID KernelBuffer, _In_ PVOID KernelBuffer,
_In_ PVOID UserBuffer, _In_ PVOID UserBuffer,
_In_ PMDL Mdl) _In_ PMDL Mdl)
@ -667,17 +684,18 @@ SharedMappingInitialise(_In_ PIRP Irp)
MmBuildMdlForNonPagedPool(mdl); MmBuildMdlForNonPagedPool(mdl);
__try { __try {
user_buffer = MmMapLockedPagesSpecifyCache(mdl, user_buffer = MmMapLockedPagesSpecifyCache(
mdl,
UserMode, UserMode,
MmCached, MmCached,
NULL, NULL,
FALSE, FALSE,
NormalPagePriority | NormalPagePriority | MdlMappingNoExecute);
MdlMappingNoExecute);
} }
__except (EXCEPTION_EXECUTE_HANDLER) { __except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode(); status = GetExceptionCode();
DEBUG_ERROR("MmMapLockedPagesSpecifyCache failed with status %x", DEBUG_ERROR(
"MmMapLockedPagesSpecifyCache failed with status %x",
status); status);
IoFreeMdl(mdl); IoFreeMdl(mdl);
ExFreePoolWithTag(buffer, POOL_TAG_INTEGRITY); ExFreePoolWithTag(buffer, POOL_TAG_INTEGRITY);
@ -707,13 +725,15 @@ DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation)
switch (Operation->operation_id) { switch (Operation->operation_id) {
case APC_OPERATION_STACKWALK: case APC_OPERATION_STACKWALK:
DEBUG_INFO("Initiating APC stackwalk operation with operation id %i", DEBUG_INFO(
"Initiating APC stackwalk operation with operation id %i",
Operation->operation_id); Operation->operation_id);
status = ValidateThreadsViaKernelApc(); status = ValidateThreadsViaKernelApc();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateThreadsViaKernelApc failed with status %x", DEBUG_ERROR(
"ValidateThreadsViaKernelApc failed with status %x",
status); status);
return status; return status;
@ -835,7 +855,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
* bug check under windows driver verifier. * bug check under windows driver verifier.
*/ */
status = ImpPsCreateSystemThread(&handle, status = ImpPsCreateSystemThread(
&handle,
PROCESS_ALL_ACCESS, PROCESS_ALL_ACCESS,
NULL, NULL,
NULL, NULL,
@ -889,7 +910,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = PerformVirtualizationDetection(Irp); status = PerformVirtualizationDetection(Irp);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("PerformVirtualizationDetection failed with status %x", DEBUG_ERROR(
"PerformVirtualizationDetection failed with status %x",
status); status);
break; break;
@ -908,8 +930,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
DEBUG_VERBOSE("IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS Received"); DEBUG_VERBOSE("IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS Received");
status = status = ImpPsCreateSystemThread(
ImpPsCreateSystemThread(&handle, &handle,
PROCESS_ALL_ACCESS, PROCESS_ALL_ACCESS,
NULL, NULL,
NULL, NULL,
@ -922,7 +944,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
goto end; goto end;
} }
status = ImpObReferenceObjectByHandle(handle, status = ImpObReferenceObjectByHandle(
handle,
THREAD_ALL_ACCESS, THREAD_ALL_ACCESS,
*PsThreadType, *PsThreadType,
KernelMode, KernelMode,
@ -930,7 +953,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
NULL); NULL);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ObReferenceObjectbyhandle failed with status %lx", DEBUG_ERROR(
"ObReferenceObjectbyhandle failed with status %lx",
status); status);
ImpZwClose(handle); ImpZwClose(handle);
goto end; goto end;
@ -982,7 +1006,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = ValidateOurDriverImage(); status = ValidateOurDriverImage();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("VerifyInMemoryImageVsDiskImage failed with status %x", DEBUG_ERROR(
"VerifyInMemoryImageVsDiskImage failed with status %x",
status); status);
break; break;
@ -1002,7 +1027,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = ValidateProcessLoadedModule(Irp); status = ValidateProcessLoadedModule(Irp);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateProcessLoadedModule failed with status %x", DEBUG_ERROR(
"ValidateProcessLoadedModule failed with status %x",
status); status);
break; break;
@ -1017,14 +1043,16 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = ValidateIrpOutputBuffer(Irp, sizeof(SYSTEM_INFORMATION)); status = ValidateIrpOutputBuffer(Irp, sizeof(SYSTEM_INFORMATION));
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpOutputBuffer failed with status %x", DEBUG_ERROR(
"ValidateIrpOutputBuffer failed with status %x",
status); status);
goto end; goto end;
} }
Irp->IoStatus.Information = sizeof(SYSTEM_INFORMATION); Irp->IoStatus.Information = sizeof(SYSTEM_INFORMATION);
IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, IntCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
system_information, system_information,
sizeof(SYSTEM_INFORMATION)); sizeof(SYSTEM_INFORMATION));
@ -1051,7 +1079,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = DetectEptHooksInKeyFunctions(); status = DetectEptHooksInKeyFunctions();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("DetectEpthooksInKeyFunctions failed with status %x", DEBUG_ERROR(
"DetectEpthooksInKeyFunctions failed with status %x",
status); status);
break; break;
@ -1120,7 +1149,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = SharedMappingInitialise(Irp); status = SharedMappingInitialise(Irp);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("SharedMappingInitialise failed with status %x", DEBUG_ERROR(
"SharedMappingInitialise failed with status %x",
status); status);
break; break;
@ -1129,7 +1159,8 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
DEBUG_INFO("IOCTL_VALIDATE_PCI_DEVICES Received"); DEBUG_INFO("IOCTL_VALIDATE_PCI_DEVICES Received");
status = ImpPsCreateSystemThread(&handle, status = ImpPsCreateSystemThread(
&handle,
PROCESS_ALL_ACCESS, PROCESS_ALL_ACCESS,
NULL, NULL,
NULL, NULL,
@ -1152,13 +1183,15 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
status = ValidateWin32kDispatchTables(); status = ValidateWin32kDispatchTables();
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateWin32kDispatchTables failed with status %x", DEBUG_ERROR(
"ValidateWin32kDispatchTables failed with status %x",
status); status);
break; break;
default: default:
DEBUG_WARNING("Invalid IOCTL passed to driver: %lx", DEBUG_WARNING(
"Invalid IOCTL passed to driver: %lx",
stack_location->Parameters.DeviceIoControl.IoControlCode); stack_location->Parameters.DeviceIoControl.IoControlCode);
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;

View file

@ -160,8 +160,8 @@ ValidateThreadViaKernelApcCallback(
* are done using it. * are done using it.
*/ */
PRTL_MODULE_EXTENDED_INFO PRTL_MODULE_EXTENDED_INFO
FindSystemModuleByName(_In_ LPCSTR ModuleName, FindSystemModuleByName(
_In_ PSYSTEM_MODULES SystemModules) _In_ LPCSTR ModuleName, _In_ PSYSTEM_MODULES SystemModules)
{ {
PAGED_CODE(); PAGED_CODE();
@ -182,8 +182,8 @@ FindSystemModuleByName(_In_ LPCSTR ModuleName,
STATIC STATIC
VOID VOID
PopulateWhitelistedModuleBuffer(_Inout_ PWHITELISTED_REGIONS Whitelist, PopulateWhitelistedModuleBuffer(
_In_ PSYSTEM_MODULES SystemModules) _Inout_ PWHITELISTED_REGIONS Whitelist, _In_ PSYSTEM_MODULES SystemModules)
{ {
PAGED_CODE(); PAGED_CODE();
@ -214,7 +214,8 @@ GetDriverMajorDispatchFunction(_In_ PDRIVER_OBJECT Driver)
STATIC STATIC
BOOLEAN BOOLEAN
DoesDriverHaveInvalidDispatchRoutine(_In_ PDRIVER_OBJECT Driver, DoesDriverHaveInvalidDispatchRoutine(
_In_ PDRIVER_OBJECT Driver,
_In_ PSYSTEM_MODULES Modules, _In_ PSYSTEM_MODULES Modules,
_In_ PWHITELISTED_REGIONS Regions) _In_ PWHITELISTED_REGIONS Regions)
{ {
@ -270,7 +271,8 @@ DoesDriverHaveInvalidDispatchRoutine(_In_ PDRIVER_OBJECT Driver,
return FALSE; return FALSE;
} }
DEBUG_WARNING("Driver with invalid dispatch routine found: %s", DEBUG_WARNING(
"Driver with invalid dispatch routine found: %s",
module[index].FullPathName); module[index].FullPathName);
return TRUE; return TRUE;
@ -281,8 +283,8 @@ DoesDriverHaveInvalidDispatchRoutine(_In_ PDRIVER_OBJECT Driver,
STATIC STATIC
BOOLEAN BOOLEAN
DoesDriverObjectHaveBackingModule(_In_ PSYSTEM_MODULES ModuleInformation, DoesDriverObjectHaveBackingModule(
_In_ PDRIVER_OBJECT DriverObject) _In_ PSYSTEM_MODULES ModuleInformation, _In_ PDRIVER_OBJECT DriverObject)
{ {
PAGED_CODE(); PAGED_CODE();
@ -302,7 +304,8 @@ DoesDriverObjectHaveBackingModule(_In_ PSYSTEM_MODULES ModuleInformation,
} }
} }
DEBUG_WARNING("Driver found with no backing system image at address: %llx", DEBUG_WARNING(
"Driver found with no backing system image at address: %llx",
(UINT64)DriverObject->DriverStart); (UINT64)DriverObject->DriverStart);
return FALSE; return FALSE;
@ -311,9 +314,8 @@ DoesDriverObjectHaveBackingModule(_In_ PSYSTEM_MODULES ModuleInformation,
FORCEINLINE FORCEINLINE
STATIC STATIC
VOID VOID
InitSystemModulesStructure(_Out_ PSYSTEM_MODULES Modules, InitSystemModulesStructure(
_In_ PVOID Buffer, _Out_ PSYSTEM_MODULES Modules, _In_ PVOID Buffer, _In_ INT Count)
_In_ INT Count)
{ {
Modules->address = Buffer; Modules->address = Buffer;
Modules->module_count = Count; Modules->module_count = Count;
@ -332,7 +334,8 @@ GetSystemModuleInformation(_Out_ PSYSTEM_MODULES ModuleInformation)
if (!ModuleInformation) if (!ModuleInformation)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
status = RtlQueryModuleInformation(&size, status = RtlQueryModuleInformation(
&size,
sizeof(RTL_MODULE_EXTENDED_INFO), sizeof(RTL_MODULE_EXTENDED_INFO),
NULL); NULL);
@ -348,18 +351,21 @@ GetSystemModuleInformation(_Out_ PSYSTEM_MODULES ModuleInformation)
return STATUS_MEMORY_NOT_ALLOCATED; return STATUS_MEMORY_NOT_ALLOCATED;
} }
status = RtlQueryModuleInformation(&size, status = RtlQueryModuleInformation(
&size,
sizeof(RTL_MODULE_EXTENDED_INFO), sizeof(RTL_MODULE_EXTENDED_INFO),
buffer); buffer);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("RtlQueryModuleInformation 2 failed with status %x", DEBUG_ERROR(
"RtlQueryModuleInformation 2 failed with status %x",
status); status);
ExFreePoolWithTag(buffer, SYSTEM_MODULES_POOL); ExFreePoolWithTag(buffer, SYSTEM_MODULES_POOL);
return STATUS_ABANDONED; return STATUS_ABANDONED;
} }
InitSystemModulesStructure(ModuleInformation, InitSystemModulesStructure(
ModuleInformation,
buffer, buffer,
ARRAYLEN(size, RTL_MODULE_EXTENDED_INFO)); ARRAYLEN(size, RTL_MODULE_EXTENDED_INFO));
@ -422,7 +428,8 @@ GetObjectFromDirectory(_In_ POBJECT_DIRECTORY_ENTRY Entry)
STATIC STATIC
VOID VOID
ValidateDriverObjects(_In_ PSYSTEM_MODULES Modules, ValidateDriverObjects(
_In_ PSYSTEM_MODULES Modules,
_In_ POBJECT_DIRECTORY_ENTRY Entry, _In_ POBJECT_DIRECTORY_ENTRY Entry,
_In_ PWHITELISTED_REGIONS Whitelist) _In_ PWHITELISTED_REGIONS Whitelist)
{ {
@ -466,7 +473,8 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
ImpRtlInitUnicodeString(&dir_name, L"\\Driver"); ImpRtlInitUnicodeString(&dir_name, L"\\Driver");
InitializeObjectAttributes(&oa, InitializeObjectAttributes(
&oa,
&dir_name, &dir_name,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
NULL, NULL,
@ -479,7 +487,8 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
return status; return status;
} }
status = ImpObReferenceObjectByHandle(handle, status = ImpObReferenceObjectByHandle(
handle,
DIRECTORY_ALL_ACCESS, DIRECTORY_ALL_ACCESS,
NULL, NULL,
KernelMode, KernelMode,
@ -520,7 +529,8 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
PopulateWhitelistedModuleBuffer(wl, SystemModules); PopulateWhitelistedModuleBuffer(wl, SystemModules);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("PopulateWhitelistedModuleBuffer failed with status %x", DEBUG_ERROR(
"PopulateWhitelistedModuleBuffer failed with status %x",
status); status);
goto end; goto end;
} }
@ -585,8 +595,8 @@ end:
* boolean and remove the out variable. * boolean and remove the out variable.
*/ */
BOOLEAN BOOLEAN
IsInstructionPointerInInvalidRegion(_In_ UINT64 Rip, IsInstructionPointerInInvalidRegion(
_In_ PSYSTEM_MODULES SystemModules) _In_ UINT64 Rip, _In_ PSYSTEM_MODULES SystemModules)
{ {
PAGED_CODE(); PAGED_CODE();
@ -607,8 +617,8 @@ IsInstructionPointerInInvalidRegion(_In_ UINT64 Rip,
} }
BOOLEAN BOOLEAN
IsInstructionPointerInsideSpecifiedModule(_In_ UINT64 Rip, IsInstructionPointerInsideSpecifiedModule(
_In_ PRTL_MODULE_EXTENDED_INFO Module) _In_ UINT64 Rip, _In_ PRTL_MODULE_EXTENDED_INFO Module)
{ {
UINT64 base = (UINT64)Module->ImageBase; UINT64 base = (UINT64)Module->ImageBase;
UINT64 end = base + Module->ImageSize; UINT64 end = base + Module->ImageSize;
@ -686,8 +696,8 @@ ReportMissingCidTableEntry(_In_ PNMI_CONTEXT Context)
STATIC STATIC
VOID VOID
ReportInvalidRipFoundDuringNmi(_In_ PNMI_CONTEXT Context, ReportInvalidRipFoundDuringNmi(
_In_ UINT32 ReportSubCode) _In_ PNMI_CONTEXT Context, _In_ UINT32 ReportSubCode)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 len = 0; UINT32 len = 0;
@ -811,7 +821,8 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES Modules)
if (!DoesThreadHaveValidCidEntry(context->kthread)) if (!DoesThreadHaveValidCidEntry(context->kthread))
ReportMissingCidTableEntry(context); ReportMissingCidTableEntry(context);
if (IsInstructionPointerInInvalidRegion(context->interrupted_rip, if (IsInstructionPointerInInvalidRegion(
context->interrupted_rip,
Modules)) Modules))
ReportInvalidRipFoundDuringNmi(context, 0); ReportInvalidRipFoundDuringNmi(context, 0);
@ -895,7 +906,8 @@ LaunchNonMaskableInterrupt()
PKAFFINITY_EX affinity = NULL; PKAFFINITY_EX affinity = NULL;
LARGE_INTEGER delay = {0}; LARGE_INTEGER delay = {0};
affinity = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, affinity = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(KAFFINITY_EX), sizeof(KAFFINITY_EX),
PROC_AFFINITY_POOL); PROC_AFFINITY_POOL);
@ -1051,7 +1063,8 @@ ReportApcStackwalkViolation(_In_ UINT64 Rip)
*/ */
STATIC STATIC
VOID VOID
ApcKernelRoutine(_In_ PRKAPC Apc, ApcKernelRoutine(
_In_ PRKAPC Apc,
_Inout_ _Deref_pre_maybenull_ PKNORMAL_ROUTINE* NormalRoutine, _Inout_ _Deref_pre_maybenull_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ _Deref_pre_maybenull_ PVOID* NormalContext, _Inout_ _Deref_pre_maybenull_ PVOID* NormalContext,
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument1, _Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument1,
@ -1073,15 +1086,16 @@ ApcKernelRoutine(_In_ PRKAPC Apc,
if (!entry) if (!entry)
return; return;
buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
STACK_FRAME_POOL_SIZE, STACK_FRAME_POOL_SIZE,
POOL_TAG_APC); POOL_TAG_APC);
if (!buffer) if (!buffer)
goto free; goto free;
frames_captured = frames_captured = ImpRtlCaptureStackBackTrace(
ImpRtlCaptureStackBackTrace(NULL, NULL,
STACK_FRAME_POOL_SIZE / sizeof(UINT64), STACK_FRAME_POOL_SIZE / sizeof(UINT64),
buffer, buffer,
NULL); NULL);
@ -1118,7 +1132,8 @@ free:
*/ */
STATIC STATIC
VOID VOID
ApcNormalRoutine(_In_opt_ PVOID NormalContext, ApcNormalRoutine(
_In_opt_ PVOID NormalContext,
_In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2) _In_opt_ PVOID SystemArgument2)
{ {
@ -1131,8 +1146,8 @@ ApcNormalRoutine(_In_opt_ PVOID NormalContext,
STATIC STATIC
VOID VOID
ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY Entry, ValidateThreadViaKernelApcCallback(
_Inout_opt_ PVOID Context) _In_ PTHREAD_LIST_ENTRY Entry, _Inout_opt_ PVOID Context)
{ {
PAGED_CODE(); PAGED_CODE();
@ -1186,7 +1201,8 @@ ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY Entry,
if (!apc) if (!apc)
return; return;
ImpKeInitializeApc(apc, ImpKeInitializeApc(
apc,
Entry->thread, Entry->thread,
OriginalApcEnvironment, OriginalApcEnvironment,
ApcKernelRoutine, ApcKernelRoutine,
@ -1246,7 +1262,8 @@ ValidateThreadsViaKernelApc()
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, context = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(APC_STACKWALK_CONTEXT), sizeof(APC_STACKWALK_CONTEXT),
POOL_TAG_APC); POOL_TAG_APC);
@ -1254,7 +1271,8 @@ ValidateThreadsViaKernelApc()
return STATUS_MEMORY_NOT_ALLOCATED; return STATUS_MEMORY_NOT_ALLOCATED;
context->header.context_id = APC_CONTEXT_ID_STACKWALK; context->header.context_id = APC_CONTEXT_ID_STACKWALK;
context->modules = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, context->modules = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(SYSTEM_MODULES), sizeof(SYSTEM_MODULES),
POOL_TAG_APC); POOL_TAG_APC);
@ -1290,7 +1308,8 @@ FreeApcStackwalkApcContextInformation(_Inout_ PAPC_STACKWALK_CONTEXT Context)
} }
VOID VOID
DpcStackwalkCallbackRoutine(_In_ PKDPC Dpc, DpcStackwalkCallbackRoutine(
_In_ PKDPC Dpc,
_In_opt_ PVOID DeferredContext, _In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2) _In_opt_ PVOID SystemArgument2)
@ -1305,8 +1324,8 @@ DpcStackwalkCallbackRoutine(_In_ PKDPC Dpc,
context = &((PDPC_CONTEXT)DeferredContext)[KeGetCurrentProcessorNumber()]; context = &((PDPC_CONTEXT)DeferredContext)[KeGetCurrentProcessorNumber()];
context->frames_captured = context->frames_captured = ImpRtlCaptureStackBackTrace(
ImpRtlCaptureStackBackTrace(DPC_STACKWALK_FRAMES_TO_SKIP, DPC_STACKWALK_FRAMES_TO_SKIP,
DPC_STACKWALK_STACKFRAME_COUNT, DPC_STACKWALK_STACKFRAME_COUNT,
&context->stack_frame, &context->stack_frame,
NULL); NULL);
@ -1318,16 +1337,16 @@ DpcStackwalkCallbackRoutine(_In_ PKDPC Dpc,
ImpKeSignalCallDpcDone(SystemArgument1); ImpKeSignalCallDpcDone(SystemArgument1);
#pragma warning(pop) #pragma warning(pop)
DEBUG_VERBOSE("Executed DPC on core: %lx, with %lx frames captured.", DEBUG_VERBOSE(
"Executed DPC on core: %lx, with %lx frames captured.",
KeGetCurrentProcessorNumber(), KeGetCurrentProcessorNumber(),
context->frames_captured); context->frames_captured);
} }
STATIC STATIC
VOID VOID
ReportDpcStackwalkViolation(_In_ PDPC_CONTEXT Context, ReportDpcStackwalkViolation(
_In_ UINT64 Frame, _In_ PDPC_CONTEXT Context, _In_ UINT64 Frame, _In_ UINT32 ReportSubtype)
_In_ UINT32 ReportSubtype)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 len = 0; UINT32 len = 0;
@ -1370,7 +1389,8 @@ ValidateDpcStackFrame(_In_ PDPC_CONTEXT Context, _In_ PSYSTEM_MODULES Modules)
/* With regards to this, lets only check the interrupted rip */ /* With regards to this, lets only check the interrupted rip */
if (DoesRetInstructionCauseException(Context->stack_frame[0])) if (DoesRetInstructionCauseException(Context->stack_frame[0]))
ReportDpcStackwalkViolation(Context, ReportDpcStackwalkViolation(
Context,
Context->stack_frame[0], Context->stack_frame[0],
REPORT_SUBTYPE_EXCEPTION_THROWING_RET); REPORT_SUBTYPE_EXCEPTION_THROWING_RET);
@ -1384,8 +1404,8 @@ ValidateDpcStackFrame(_In_ PDPC_CONTEXT Context, _In_ PSYSTEM_MODULES Modules)
STATIC STATIC
VOID VOID
ValidateDpcCapturedStack(_In_ PSYSTEM_MODULES Modules, ValidateDpcCapturedStack(
_In_ PDPC_CONTEXT Context) _In_ PSYSTEM_MODULES Modules, _In_ PDPC_CONTEXT Context)
{ {
BOOLEAN flag = FALSE; BOOLEAN flag = FALSE;
PDPC_CONTEXT context = NULL; PDPC_CONTEXT context = NULL;
@ -1395,7 +1415,8 @@ ValidateDpcCapturedStack(_In_ PSYSTEM_MODULES Modules,
context = &Context[core]; context = &Context[core];
if (!context->executed) if (!context->executed)
DEBUG_WARNING("DPC Stackwalk routine not executed. Core: %lx", DEBUG_WARNING(
"DPC Stackwalk routine not executed. Core: %lx",
core); core);
ValidateDpcStackFrame(&Context[core], Modules); ValidateDpcStackFrame(&Context[core], Modules);
@ -1453,7 +1474,8 @@ end:
/* todo: walk the chain of pointers to prevent jmp chaining */ /* todo: walk the chain of pointers to prevent jmp chaining */
STATIC STATIC
VOID VOID
ValidateTableDispatchRoutines(_In_ PVOID* Base, ValidateTableDispatchRoutines(
_In_ PVOID* Base,
_In_ UINT32 Entries, _In_ UINT32 Entries,
_In_ PSYSTEM_MODULES Modules, _In_ PSYSTEM_MODULES Modules,
_Out_ PVOID* Routine) _Out_ PVOID* Routine)
@ -1490,8 +1512,8 @@ GetHalPrivateDispatchTableRoutineCount(_In_ PRTL_OSVERSIONINFOW VersionInfo)
STATIC STATIC
NTSTATUS NTSTATUS
ValidateHalPrivateDispatchTable(_Out_ PVOID* Routine, ValidateHalPrivateDispatchTable(
_In_ PSYSTEM_MODULES Modules) _Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID table = NULL; PVOID table = NULL;
@ -1537,7 +1559,8 @@ ValidateHalDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
* What if there are 2 invalid routines? hmm.. tink. * What if there are 2 invalid routines? hmm.. tink.
*/ */
if (IsInstructionPointerInInvalidRegion(HalQuerySystemInformation, if (IsInstructionPointerInInvalidRegion(
HalQuerySystemInformation,
Modules)) { Modules)) {
*Routine = HalQuerySystemInformation; *Routine = HalQuerySystemInformation;
goto end; goto end;
@ -1553,7 +1576,8 @@ ValidateHalDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
goto end; goto end;
} }
if (IsInstructionPointerInInvalidRegion(HalReferenceHandlerForBus, if (IsInstructionPointerInInvalidRegion(
HalReferenceHandlerForBus,
Modules)) { Modules)) {
*Routine = HalReferenceHandlerForBus; *Routine = HalReferenceHandlerForBus;
goto end; goto end;
@ -1564,7 +1588,8 @@ ValidateHalDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
goto end; goto end;
} }
if (IsInstructionPointerInInvalidRegion(HalDereferenceBusHandler, if (IsInstructionPointerInInvalidRegion(
HalDereferenceBusHandler,
Modules)) { Modules)) {
*Routine = HalDereferenceBusHandler; *Routine = HalDereferenceBusHandler;
goto end; goto end;
@ -1585,7 +1610,8 @@ ValidateHalDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
goto end; goto end;
} }
if (IsInstructionPointerInInvalidRegion(HalGetInterruptTranslator, if (IsInstructionPointerInInvalidRegion(
HalGetInterruptTranslator,
Modules)) { Modules)) {
*Routine = HalGetInterruptTranslator; *Routine = HalGetInterruptTranslator;
goto end; goto end;
@ -1621,7 +1647,8 @@ ValidateHalDispatchTable(_Out_ PVOID* Routine, _In_ PSYSTEM_MODULES Modules)
goto end; goto end;
} }
if (IsInstructionPointerInInvalidRegion(HalSetPciErrorHandlerCallback, if (IsInstructionPointerInInvalidRegion(
HalSetPciErrorHandlerCallback,
Modules)) { Modules)) {
*Routine = HalSetPciErrorHandlerCallback; *Routine = HalSetPciErrorHandlerCallback;
goto end; goto end;
@ -1650,7 +1677,8 @@ ReportDataTableInvalidRoutine(_In_ TABLE_ID TableId, _In_ UINT64 Address)
if (!report) if (!report)
return; return;
DEBUG_WARNING("Invalid data table routine found. Table: %lx, Address: %llx", DEBUG_WARNING(
"Invalid data table routine found. Table: %lx, Address: %llx",
TableId, TableId,
Address); Address);
@ -1698,7 +1726,8 @@ ValidateHalDispatchTables()
status = ValidateHalPrivateDispatchTable(&routine2, &modules); status = ValidateHalPrivateDispatchTable(&routine2, &modules);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateHalPrivateDispatchTable failed with status %x", DEBUG_ERROR(
"ValidateHalPrivateDispatchTable failed with status %x",
status); status);
goto end; goto end;
} }
@ -1716,8 +1745,8 @@ end:
} }
NTSTATUS NTSTATUS
GetDriverObjectByDriverName(_In_ PUNICODE_STRING DriverName, GetDriverObjectByDriverName(
_Out_ PDRIVER_OBJECT* DriverObject) _In_ PUNICODE_STRING DriverName, _Out_ PDRIVER_OBJECT* DriverObject)
{ {
HANDLE handle = NULL; HANDLE handle = NULL;
OBJECT_ATTRIBUTES attributes = {0}; OBJECT_ATTRIBUTES attributes = {0};
@ -1733,7 +1762,8 @@ GetDriverObjectByDriverName(_In_ PUNICODE_STRING DriverName,
ImpRtlInitUnicodeString(&dir_name, L"\\Driver"); ImpRtlInitUnicodeString(&dir_name, L"\\Driver");
InitializeObjectAttributes(&attributes, InitializeObjectAttributes(
&attributes,
&dir_name, &dir_name,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
NULL, NULL,
@ -1747,7 +1777,8 @@ GetDriverObjectByDriverName(_In_ PUNICODE_STRING DriverName,
return status; return status;
} }
status = ImpObReferenceObjectByHandle(handle, status = ImpObReferenceObjectByHandle(
handle,
DIRECTORY_ALL_ACCESS, DIRECTORY_ALL_ACCESS,
NULL, NULL,
KernelMode, KernelMode,
@ -1775,7 +1806,8 @@ GetDriverObjectByDriverName(_In_ PUNICODE_STRING DriverName,
while (sub_entry) { while (sub_entry) {
driver = GetObjectFromDirectory(sub_entry); driver = GetObjectFromDirectory(sub_entry);
if (!RtlCompareUnicodeString(DriverName, if (!RtlCompareUnicodeString(
DriverName,
&driver->DriverName, &driver->DriverName,
FALSE)) { FALSE)) {
*DriverObject = driver; *DriverObject = driver;
@ -1985,8 +2017,8 @@ FindChainedPointerEnding(_In_ PVOID* Start)
STATIC STATIC
VOID VOID
ReportWin32kBase_DxgInterfaceViolation(_In_ UINT32 TableIndex, ReportWin32kBase_DxgInterfaceViolation(
_In_ UINT64 Address) _In_ UINT32 TableIndex, _In_ UINT64 Address)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 len = 0; UINT32 len = 0;

View file

@ -55,19 +55,21 @@ PeGetExportDataDirectorySafe(_In_ PVOID Image)
} }
PIMAGE_EXPORT_DIRECTORY PIMAGE_EXPORT_DIRECTORY
PeGetExportDirectory(_In_ PVOID Image, PeGetExportDirectory(
_In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory) _In_ PVOID Image, _In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory)
{ {
if (!ExportDataDirectory->VirtualAddress || !ExportDataDirectory->Size) if (!ExportDataDirectory->VirtualAddress || !ExportDataDirectory->Size)
return NULL; return NULL;
return RVA( return RVA(
PIMAGE_EXPORT_DIRECTORY, Image, ExportDataDirectory->VirtualAddress); PIMAGE_EXPORT_DIRECTORY,
Image,
ExportDataDirectory->VirtualAddress);
} }
PIMAGE_EXPORT_DIRECTORY PIMAGE_EXPORT_DIRECTORY
PeGetExportDirectorySafe(_In_ PVOID Image, PeGetExportDirectorySafe(
_In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory) _In_ PVOID Image, _In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory)
{ {
if (!MmIsAddressValid(Image)) if (!MmIsAddressValid(Image))
return NULL; return NULL;
@ -76,7 +78,9 @@ PeGetExportDirectorySafe(_In_ PVOID Image,
return NULL; return NULL;
return RVA( return RVA(
PIMAGE_EXPORT_DIRECTORY, Image, ExportDataDirectory->VirtualAddress); PIMAGE_EXPORT_DIRECTORY,
Image,
ExportDataDirectory->VirtualAddress);
} }
UINT32 UINT32
@ -119,18 +123,14 @@ PeFindExportByName(_In_ PVOID Image, _In_ PCHAR Name)
if (!export) if (!export)
return NULL; return NULL;
PUINT32 functions = PUINT32 functions = RVA(PUINT32, Image, export->AddressOfFunctions);
RVA(PUINT32, Image, export->AddressOfFunctions); PUINT32 names = RVA(PUINT32, Image, export->AddressOfNames);
PUINT32 names = PUINT16 ordinals = RVA(PUINT16, Image, export->AddressOfNameOrdinals);
RVA(PUINT32, Image, export->AddressOfNames);
PUINT16 ordinals =
RVA(PUINT16, Image, export->AddressOfNameOrdinals);
for (UINT32 index = 0; index < export->NumberOfNames; index++) { for (UINT32 index = 0; index < export->NumberOfNames; index++) {
PCHAR export = RVA(PCHAR, Image, names[index]); PCHAR export = RVA(PCHAR, Image, names[index]);
if (!IntCompareString(Name, export)) if (!IntCompareString(Name, export))
return RVA( return RVA(PVOID, Image, functions[ordinals[index]]);
PVOID, Image, functions[ordinals[index]]);
} }
return NULL; return NULL;

View file

@ -4,9 +4,9 @@
#include "callbacks.h" #include "callbacks.h"
#include "crypt.h"
#include "ia32.h" #include "ia32.h"
#include "imports.h" #include "imports.h"
#include "crypt.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -56,25 +56,27 @@ typedef struct _PROCESS_SCAN_CONTEXT {
STATIC STATIC
BOOLEAN BOOLEAN
ValidateIfAddressIsProcessStructure(_In_ PVOID Address, ValidateIfAddressIsProcessStructure(
_In_ PPOOL_HEADER PoolHeader); _In_ PVOID Address, _In_ PPOOL_HEADER PoolHeader);
STATIC STATIC
VOID VOID
ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase, ScanPageForKernelObjectAllocation(
_In_ UINT64 PageBase,
_In_ ULONG PageSize, _In_ ULONG PageSize,
_In_ ULONG ObjectIndex, _In_ ULONG ObjectIndex,
_Inout_ PPROCESS_SCAN_CONTEXT Context); _Inout_ PPROCESS_SCAN_CONTEXT Context);
STATIC STATIC
BOOLEAN BOOLEAN
IsPhysicalAddressInPhysicalMemoryRange(_In_ UINT64 PhysicalAddress, IsPhysicalAddressInPhysicalMemoryRange(
_In_ PPHYSICAL_MEMORY_RANGE _In_ UINT64 PhysicalAddress,
PhysicalMemoryRanges); _In_ PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges);
STATIC STATIC
VOID VOID
EnumerateKernelLargePages(_In_ UINT64 PageBase, EnumerateKernelLargePages(
_In_ UINT64 PageBase,
_In_ ULONG PageSize, _In_ ULONG PageSize,
_In_ PPROCESS_SCAN_CONTEXT Context, _In_ PPROCESS_SCAN_CONTEXT Context,
_In_ ULONG ObjectIndex); _In_ ULONG ObjectIndex);
@ -89,8 +91,8 @@ IncrementProcessCounter(_In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context);
STATIC STATIC
VOID VOID
CheckIfProcessAllocationIsInProcessList(_In_ PPROCESS_LIST_ENTRY Node, CheckIfProcessAllocationIsInProcessList(
_In_opt_ PVOID Context); _In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
# pragma alloc_text(PAGE, GetGlobalDebuggerData) # pragma alloc_text(PAGE, GetGlobalDebuggerData)
@ -115,21 +117,33 @@ GetGlobalDebuggerData()
RtlCaptureContext(&context); RtlCaptureContext(&context);
dump_header = ImpExAllocatePool2( dump_header = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, DUMP_BLOCK_SIZE, POOL_DUMP_BLOCK_TAG); POOL_FLAG_NON_PAGED,
DUMP_BLOCK_SIZE,
POOL_DUMP_BLOCK_TAG);
if (!dump_header) if (!dump_header)
goto end; goto end;
KeCapturePersistentThreadState( KeCapturePersistentThreadState(
&context, NULL, NULL, NULL, NULL, NULL, NULL, dump_header); &context,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
dump_header);
debugger_data = (PKDDEBUGGER_DATA64)ExAllocatePool2( debugger_data = (PKDDEBUGGER_DATA64)ExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(KDDEBUGGER_DATA64), POOL_DEBUGGER_DATA_TAG); POOL_FLAG_NON_PAGED,
sizeof(KDDEBUGGER_DATA64),
POOL_DEBUGGER_DATA_TAG);
if (!debugger_data) if (!debugger_data)
goto end; goto end;
IntCopyMemory(debugger_data, IntCopyMemory(
debugger_data,
dump_header->KdDebuggerDataBlock, dump_header->KdDebuggerDataBlock,
sizeof(KDDEBUGGER_DATA64)); sizeof(KDDEBUGGER_DATA64));
@ -200,8 +214,8 @@ GetPsActiveProcessHead(_Out_ PUINT64 Address)
*/ */
STATIC STATIC
BOOLEAN BOOLEAN
ValidateIfAddressIsProcessStructure(_In_ PVOID Address, ValidateIfAddressIsProcessStructure(
_In_ PPOOL_HEADER PoolHeader) _In_ PVOID Address, _In_ PPOOL_HEADER PoolHeader)
{ {
UINT64 peak_virtual_size = 0; UINT64 peak_virtual_size = 0;
UINT64 dir_table_base = 0; UINT64 dir_table_base = 0;
@ -212,13 +226,13 @@ ValidateIfAddressIsProcessStructure(_In_ PVOID Address,
BOOLEAN object_table_test = FALSE; BOOLEAN object_table_test = FALSE;
UINT64 allocation_size_test = 0; UINT64 allocation_size_test = 0;
if (ImpMmIsAddressValid((UINT64)Address + if (ImpMmIsAddressValid(
KPROCESS_DIRECTORY_TABLE_BASE_OFFSET)) (UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET))
dir_table_base = dir_table_base =
*(UINT64*)((UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET); *(UINT64*)((UINT64)Address + KPROCESS_DIRECTORY_TABLE_BASE_OFFSET);
if (ImpMmIsAddressValid((UINT64)Address + if (ImpMmIsAddressValid(
EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET)) (UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET))
peak_virtual_size = peak_virtual_size =
*(UINT64*)((UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET); *(UINT64*)((UINT64)Address + EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET);
@ -278,7 +292,8 @@ ValidateIfAddressIsProcessStructure(_In_ PVOID Address,
*/ */
STATIC STATIC
VOID VOID
ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase, ScanPageForKernelObjectAllocation(
_In_ UINT64 PageBase,
_In_ ULONG PageSize, _In_ ULONG PageSize,
_In_ ULONG ObjectIndex, _In_ ULONG ObjectIndex,
_Inout_ PPROCESS_SCAN_CONTEXT Context) _Inout_ PPROCESS_SCAN_CONTEXT Context)
@ -335,7 +350,8 @@ ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase,
(PEPROCESS)((UINT64)pool_header + sizeof(POOL_HEADER) + (PEPROCESS)((UINT64)pool_header + sizeof(POOL_HEADER) +
header_size); header_size);
if (ValidateIfAddressIsProcessStructure(test_process, if (ValidateIfAddressIsProcessStructure(
test_process,
pool_header)) { pool_header)) {
process = test_process; process = test_process;
break; break;
@ -345,7 +361,8 @@ ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase,
if (!process) if (!process)
break; break;
DEBUG_VERBOSE("Found process via pt walk: %llx", DEBUG_VERBOSE(
"Found process via pt walk: %llx",
(UINT64)process); (UINT64)process);
address_list = (PUINT64)Context->process_buffer; address_list = (PUINT64)Context->process_buffer;
@ -374,9 +391,9 @@ ScanPageForKernelObjectAllocation(_In_ UINT64 PageBase,
*/ */
STATIC STATIC
BOOLEAN BOOLEAN
IsPhysicalAddressInPhysicalMemoryRange(_In_ UINT64 PhysicalAddress, IsPhysicalAddressInPhysicalMemoryRange(
_In_ PPHYSICAL_MEMORY_RANGE _In_ UINT64 PhysicalAddress,
PhysicalMemoryRanges) _In_ PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges)
{ {
ULONG page_index = 0; ULONG page_index = 0;
UINT64 start_address = 0; UINT64 start_address = 0;
@ -398,7 +415,8 @@ IsPhysicalAddressInPhysicalMemoryRange(_In_ UINT64 PhysicalAddress,
STATIC STATIC
VOID VOID
EnumerateKernelLargePages(_In_ UINT64 PageBase, EnumerateKernelLargePages(
_In_ UINT64 PageBase,
_In_ ULONG PageSize, _In_ ULONG PageSize,
_In_ PPROCESS_SCAN_CONTEXT Context, _In_ PPROCESS_SCAN_CONTEXT Context,
_In_ ULONG ObjectIndex) _In_ ULONG ObjectIndex)
@ -409,7 +427,10 @@ EnumerateKernelLargePages(_In_ UINT64 PageBase,
for (UINT64 page_index = 0; page_index < PageSize; page_index++) { for (UINT64 page_index = 0; page_index < PageSize; page_index++) {
UINT64 page_base = PageBase + (page_index * PAGE_SIZE); UINT64 page_base = PageBase + (page_index * PAGE_SIZE);
ScanPageForKernelObjectAllocation( ScanPageForKernelObjectAllocation(
page_base, PAGE_SIZE, ObjectIndex, Context); page_base,
PAGE_SIZE,
ObjectIndex,
Context);
} }
} }
@ -481,8 +502,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
return; return;
for (INT pml4_index = 0; pml4_index < PML4_ENTRY_COUNT; pml4_index++) { for (INT pml4_index = 0; pml4_index < PML4_ENTRY_COUNT; pml4_index++) {
if (!ImpMmIsAddressValid(pml4_base.BitAddress + if (!ImpMmIsAddressValid(
pml4_index * sizeof(UINT64))) pml4_base.BitAddress + pml4_index * sizeof(UINT64)))
continue; continue;
pml4_entry.BitAddress = pml4_entry.BitAddress =
@ -516,7 +537,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
<< PAGE_1GB_SHIFT; << PAGE_1GB_SHIFT;
if (IsPhysicalAddressInPhysicalMemoryRange( if (IsPhysicalAddressInPhysicalMemoryRange(
physical.QuadPart, physical_memory_ranges) == FALSE) physical.QuadPart,
physical_memory_ranges) == FALSE)
continue; continue;
base_1gb_virtual_page = ImpMmGetVirtualForPhysical(physical); base_1gb_virtual_page = ImpMmGetVirtualForPhysical(physical);
@ -525,7 +547,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
!ImpMmIsAddressValid(base_1gb_virtual_page)) !ImpMmIsAddressValid(base_1gb_virtual_page))
continue; continue;
EnumerateKernelLargePages(base_1gb_virtual_page, EnumerateKernelLargePages(
base_1gb_virtual_page,
LARGE_PAGE_1GB_ENTRIES, LARGE_PAGE_1GB_ENTRIES,
Context, Context,
INDEX_PROCESS_POOL_TAG); INDEX_PROCESS_POOL_TAG);
@ -559,7 +582,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
<< PAGE_2MB_SHIFT; << PAGE_2MB_SHIFT;
if (IsPhysicalAddressInPhysicalMemoryRange( if (IsPhysicalAddressInPhysicalMemoryRange(
physical.QuadPart, physical_memory_ranges) == FALSE) physical.QuadPart,
physical_memory_ranges) == FALSE)
continue; continue;
base_2mb_virtual_page = base_2mb_virtual_page =
@ -569,7 +593,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
!ImpMmIsAddressValid(base_2mb_virtual_page)) !ImpMmIsAddressValid(base_2mb_virtual_page))
continue; continue;
EnumerateKernelLargePages(base_2mb_virtual_page, EnumerateKernelLargePages(
base_2mb_virtual_page,
LARGE_PAGE_2MB_ENTRIES, LARGE_PAGE_2MB_ENTRIES,
Context, Context,
INDEX_PROCESS_POOL_TAG); INDEX_PROCESS_POOL_TAG);
@ -589,8 +614,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
continue; continue;
for (INT pt_index = 0; pt_index < PT_ENTRY_COUNT; pt_index++) { for (INT pt_index = 0; pt_index < PT_ENTRY_COUNT; pt_index++) {
if (!ImpMmIsAddressValid(pt_base + if (!ImpMmIsAddressValid(
pt_index * sizeof(UINT64))) pt_base + pt_index * sizeof(UINT64)))
continue; continue;
pt_entry.BitAddress = pt_entry.BitAddress =
@ -605,7 +630,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
/* if the page base isnt in a legit /* if the page base isnt in a legit
* region, go next */ * region, go next */
if (IsPhysicalAddressInPhysicalMemoryRange( if (IsPhysicalAddressInPhysicalMemoryRange(
physical.QuadPart, physical_memory_ranges) == FALSE) physical.QuadPart,
physical_memory_ranges) == FALSE)
continue; continue;
base_virtual_page = ImpMmGetVirtualForPhysical(physical); base_virtual_page = ImpMmGetVirtualForPhysical(physical);
@ -616,7 +642,8 @@ WalkKernelPageTables(_In_ PPROCESS_SCAN_CONTEXT Context)
!ImpMmIsAddressValid(base_virtual_page)) !ImpMmIsAddressValid(base_virtual_page))
continue; continue;
ScanPageForKernelObjectAllocation(base_virtual_page, ScanPageForKernelObjectAllocation(
base_virtual_page,
PAGE_BASE_SIZE, PAGE_BASE_SIZE,
INDEX_PROCESS_POOL_TAG, INDEX_PROCESS_POOL_TAG,
Context); Context);
@ -646,8 +673,8 @@ IncrementProcessCounter(_In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context)
STATIC STATIC
VOID VOID
CheckIfProcessAllocationIsInProcessList(_In_ PPROCESS_LIST_ENTRY Node, CheckIfProcessAllocationIsInProcessList(
_In_opt_ PVOID Context) _In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context)
{ {
PAGED_CODE(); PAGED_CODE();
@ -664,7 +691,8 @@ CheckIfProcessAllocationIsInProcessList(_In_ PPROCESS_LIST_ENTRY Node,
allocation_address[i] - PROCESS_OBJECT_ALLOCATION_MARGIN && allocation_address[i] - PROCESS_OBJECT_ALLOCATION_MARGIN &&
(UINT64)Node->process <= (UINT64)Node->process <=
allocation_address[i] + PROCESS_OBJECT_ALLOCATION_MARGIN) { allocation_address[i] + PROCESS_OBJECT_ALLOCATION_MARGIN) {
RtlZeroMemory((UINT64)context->process_buffer + i * sizeof(UINT64), RtlZeroMemory(
(UINT64)context->process_buffer + i * sizeof(UINT64),
sizeof(UINT64)); sizeof(UINT64));
} }
} }
@ -693,8 +721,8 @@ FindUnlinkedProcesses()
return STATUS_ABANDONED; return STATUS_ABANDONED;
} }
context.process_buffer = context.process_buffer = ExAllocatePool2(
ExAllocatePool2(POOL_FLAG_NON_PAGED, POOL_FLAG_NON_PAGED,
context.process_count * 2 * sizeof(UINT64), context.process_count * 2 * sizeof(UINT64),
PROCESS_ADDRESS_LIST_TAG); PROCESS_ADDRESS_LIST_TAG);
@ -704,7 +732,9 @@ FindUnlinkedProcesses()
WalkKernelPageTables(&context); WalkKernelPageTables(&context);
RtlHashmapEnumerate( RtlHashmapEnumerate(
GetProcessHashmap(), CheckIfProcessAllocationIsInProcessList, &context); GetProcessHashmap(),
CheckIfProcessAllocationIsInProcessList,
&context);
allocation_address = (PUINT64)context.process_buffer; allocation_address = (PUINT64)context.process_buffer;
@ -727,7 +757,9 @@ FindUnlinkedProcesses()
allocation); allocation);
report = ImpExAllocatePool2( report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG); POOL_FLAG_NON_PAGED,
packet_size,
REPORT_POOL_TAG);
if (!report) if (!report)
continue; continue;
@ -735,7 +767,9 @@ FindUnlinkedProcesses()
INIT_REPORT_PACKET(report, REPORT_INVALID_PROCESS_ALLOCATION, 0); INIT_REPORT_PACKET(report, REPORT_INVALID_PROCESS_ALLOCATION, 0);
IntCopyMemory( IntCopyMemory(
report->process, allocation, REPORT_INVALID_PROCESS_BUFFER_SIZE); report->process,
allocation,
REPORT_INVALID_PROCESS_BUFFER_SIZE);
status = CryptEncryptBuffer(report, packet_size); status = CryptEncryptBuffer(report, packet_size);
@ -778,7 +812,8 @@ EnumerateBigPoolAllocations()
return status; return status;
} }
status = pZwQuerySystemInformation(SYSTEM_BIGPOOL_INFORMATION_ID, status = pZwQuerySystemInformation(
SYSTEM_BIGPOOL_INFORMATION_ID,
&pool_information, &pool_information,
sizeof(pool_information), sizeof(pool_information),
&return_length); &return_length);
@ -791,12 +826,15 @@ EnumerateBigPoolAllocations()
return_length += sizeof(SYSTEM_BIGPOOL_INFORMATION); return_length += sizeof(SYSTEM_BIGPOOL_INFORMATION);
pool_entries = ImpExAllocatePool2( pool_entries = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, return_length, POOL_TAG_INTEGRITY); POOL_FLAG_NON_PAGED,
return_length,
POOL_TAG_INTEGRITY);
if (!pool_entries) if (!pool_entries)
return STATUS_MEMORY_NOT_ALLOCATED; return STATUS_MEMORY_NOT_ALLOCATED;
status = pZwQuerySystemInformation(SYSTEM_BIGPOOL_INFORMATION_ID, status = pZwQuerySystemInformation(
SYSTEM_BIGPOOL_INFORMATION_ID,
pool_entries, pool_entries,
return_length, return_length,
&return_length); &return_length);

View file

@ -1,7 +1,7 @@
#include "session.h" #include "session.h"
#include "imports.h"
#include "crypt.h" #include "crypt.h"
#include "imports.h"
#include "util.h" #include "util.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -92,8 +92,8 @@ SessionTerminate()
/* Return type for this doesnt matter */ /* Return type for this doesnt matter */
STATIC STATIC
BOOLEAN BOOLEAN
HashOurUserModuleOnEntryCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry, HashOurUserModuleOnEntryCallback(
_In_opt_ PVOID Context) _In_ PPROCESS_MAP_MODULE_ENTRY Entry, _In_opt_ PVOID Context)
{ {
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PACTIVE_SESSION session = (PACTIVE_SESSION)Context; PACTIVE_SESSION session = (PACTIVE_SESSION)Context;
@ -101,7 +101,8 @@ HashOurUserModuleOnEntryCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
if (!ARGUMENT_PRESENT(Context)) if (!ARGUMENT_PRESENT(Context))
return FALSE; return FALSE;
status = HashUserModule(Entry, status = HashUserModule(
Entry,
session->module.module_hash, session->module.module_hash,
sizeof(session->module.module_hash)); sizeof(session->module.module_hash));
@ -111,7 +112,8 @@ HashOurUserModuleOnEntryCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry,
} }
DEBUG_VERBOSE("User module hashed!"); DEBUG_VERBOSE("User module hashed!");
DumpBufferToKernelDebugger(session->module.module_hash, DumpBufferToKernelDebugger(
session->module.module_hash,
sizeof(session->module.module_hash)); sizeof(session->module.module_hash));
return TRUE; return TRUE;
@ -129,7 +131,8 @@ SessionInitialise(_In_ PIRP Irp)
DEBUG_VERBOSE("Initialising new session."); DEBUG_VERBOSE("Initialising new session.");
status = ValidateIrpInputBuffer( status = ValidateIrpInputBuffer(
Irp, sizeof(SESSION_INITIATION_PACKET) - SHA_256_HASH_LENGTH); Irp,
sizeof(SESSION_INITIATION_PACKET) - SHA_256_HASH_LENGTH);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x", status); DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x", status);
@ -161,7 +164,9 @@ SessionInitialise(_In_ PIRP Irp)
session->module.size = initiation->module_info.size; session->module.size = initiation->module_info.size;
IntCopyMemory( IntCopyMemory(
session->module.path, initiation->module_info.path, MAX_MODULE_PATH); session->module.path,
initiation->module_info.path,
MAX_MODULE_PATH);
DEBUG_VERBOSE("Module base: %llx", session->module.base_address); DEBUG_VERBOSE("Module base: %llx", session->module.base_address);
DEBUG_VERBOSE("Module size: %lx ", session->module.size); DEBUG_VERBOSE("Module size: %lx ", session->module.size);
@ -205,7 +210,8 @@ SessionTerminateProcess()
/* Make sure we pass a km handle to ZwTerminateProcess and NOT a /* Make sure we pass a km handle to ZwTerminateProcess and NOT a
* usermode handle. */ * usermode handle. */
status = ZwTerminateProcess(process_id, status = ZwTerminateProcess(
process_id,
STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION); STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {

View file

@ -2,14 +2,14 @@
#include <intrin.h> #include <intrin.h>
#include "pool.h"
#include "callbacks.h" #include "callbacks.h"
#include "driver.h" #include "driver.h"
#include "pool.h"
#include "session.h"
#include "imports.h"
#include "containers/tree.h" #include "containers/tree.h"
#include "crypt.h" #include "crypt.h"
#include "imports.h"
#include "session.h"
#include "lib/stdlib.h" #include "lib/stdlib.h"
@ -80,8 +80,8 @@ DoesThreadHaveValidCidEntry(_In_ PETHREAD Thread)
* any APC's queued. * any APC's queued.
*/ */
STATIC VOID STATIC VOID
DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry, DetectAttachedThreadsProcessCallback(
_Inout_opt_ PVOID Context) _In_ PTHREAD_LIST_ENTRY ThreadListEntry, _Inout_opt_ PVOID Context)
{ {
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Context);
@ -110,7 +110,8 @@ DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
return; return;
} }
DEBUG_WARNING("Thread is attached to our protected process: %llx", DEBUG_WARNING(
"Thread is attached to our protected process: %llx",
(UINT64)ThreadListEntry->thread); (UINT64)ThreadListEntry->thread);
PATTACH_PROCESS_REPORT report = PATTACH_PROCESS_REPORT report =
@ -141,5 +142,7 @@ DetectThreadsAttachedToProtectedProcess()
PAGED_CODE(); PAGED_CODE();
DEBUG_VERBOSE("Detecting threads attached to our process..."); DEBUG_VERBOSE("Detecting threads attached to our process...");
RtlRbTreeEnumerate( RtlRbTreeEnumerate(
GetThreadTree(), DetectAttachedThreadsProcessCallback, NULL); GetThreadTree(),
DetectAttachedThreadsProcessCallback,
NULL);
} }

View file

@ -17,7 +17,8 @@ GenerateRandSeed()
} }
NTSTATUS NTSTATUS
MapAndReadPhysical(_In_ UINT64 PhysicalAddress, MapAndReadPhysical(
_In_ UINT64 PhysicalAddress,
_In_ UINT32 ReadLength, _In_ UINT32 ReadLength,
_Out_ PVOID OutputBuffer, _Out_ PVOID OutputBuffer,
_In_ UINT32 OutputBufferLength) _In_ UINT32 OutputBufferLength)
@ -45,7 +46,8 @@ MapAndReadPhysical(_In_ UINT64 PhysicalAddress,
} }
NTSTATUS NTSTATUS
UnicodeToCharBufString(_In_ PUNICODE_STRING UnicodeString, UnicodeToCharBufString(
_In_ PUNICODE_STRING UnicodeString,
_Out_ PVOID OutBuffer, _Out_ PVOID OutBuffer,
_In_ UINT32 OutBufferSize) _In_ UINT32 OutBufferSize)
{ {