bed time c:

This commit is contained in:
lhodges1 2023-10-11 04:49:17 +11:00
parent 3ff97ceae9
commit 012e9e5116
9 changed files with 322 additions and 110 deletions

View file

@ -22,6 +22,16 @@ typedef struct _THREAD_LIST
/* todo: maybe put this in the global config? hmm.. I kinda like how its encapsulated here tho hm.. */
PTHREAD_LIST thread_list = NULL;
typedef struct _PROCESS_LIST
{
SINGLE_LIST_ENTRY start;
volatile BOOLEAN active;
KSPIN_LOCK lock;
}PROCESS_LIST, *PPROCESS_LIST;
PPROCESS_LIST process_list = NULL;
STATIC
BOOLEAN
EnumHandleCallback(
@ -35,11 +45,26 @@ EnumHandleCallback(
#pragma alloc_text(PAGE, ObPreOpCallbackRoutine)
#pragma alloc_text(PAGE, EnumHandleCallback)
#pragma alloc_text(PAGE, EnumerateProcessHandles)
#pragma alloc_text(PAGE, EnumerateProcessListWithCallbackFunction)
#pragma alloc_text(PAGE, InitialiseThreadList)
#pragma alloc_text(PAGE, ExUnlockHandleTableEntry)
#endif
VOID
CleanupProcessListOnDriverUnload()
{
InterlockedExchange(&process_list->active, FALSE);
PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, TRUE);
for (;;)
{
if (!ListFreeFirstEntry(&process_list->start, &process_list->lock))
{
ExFreePoolWithTag(process_list, POOL_TAG_THREAD_LIST);
return;
}
}
}
VOID
CleanupThreadListOnDriverUnload()
{
@ -87,6 +112,50 @@ unlock:
KeReleaseSpinLock(&thread_list->lock, irql);
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
EnumerateProcessListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
_In_opt_ PVOID Context
)
{
KIRQL irql = KeGetCurrentIrql();
KeAcquireSpinLock(&process_list->lock, &irql);
if (!CallbackRoutine)
goto unlock;
PPROCESS_LIST_ENTRY entry = process_list->start.Next;
while (entry)
{
VOID(*callback_function_ptr)(PPROCESS_LIST_ENTRY, PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry, Context);
entry = entry->list.Next;
}
unlock:
KeReleaseSpinLock(&process_list->lock, irql);
}
NTSTATUS
InitialiseProcessList()
{
PAGED_CODE();
process_list =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(PROCESS_LIST), POOL_TAG_THREAD_LIST);
if (!process_list)
return STATUS_MEMORY_NOT_ALLOCATED;
InterlockedExchange(&process_list->active, TRUE);
ListInit(&process_list->start, &process_list->lock);
return STATUS_SUCCESS;
}
NTSTATUS
InitialiseThreadList()
{
@ -104,6 +173,34 @@ InitialiseThreadList()
return STATUS_SUCCESS;
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
FindProcessListEntryByProcess(
_In_ PKPROCESS Process,
_Inout_ PPROCESS_LIST_ENTRY* Entry
)
{
KIRQL irql = KeGetCurrentIrql();
*Entry = NULL;
KeAcquireSpinLock(&process_list->lock, &irql);
PPROCESS_LIST_ENTRY entry = (PPROCESS_LIST_ENTRY)process_list->start.Next;
while (entry)
{
if (entry->process == Process)
{
*Entry = entry;
goto unlock;
}
entry = entry->list.Next;
}
unlock:
KeReleaseSpinLock(&process_list->lock, irql);
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
@ -132,6 +229,49 @@ unlock:
KeReleaseSpinLock(&thread_list->lock, irql);
}
VOID
ProcessCreateNotifyRoutine(
_In_ HANDLE ParentId,
_In_ HANDLE ProcessID,
_In_ BOOLEAN Create
)
{
PPROCESS_LIST_ENTRY entry = NULL;
PKPROCESS parent = NULL;
PKPROCESS process = NULL;
if (InterlockedExchange(&process_list->active, process_list->active) == FALSE)
return;
PsLookupProcessByProcessId(ParentId, &parent);
PsLookupProcessByProcessId(ProcessID, &process);
if (!parent || !process)
return;
if (Create)
{
entry = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(PROCESS_LIST_ENTRY), POOL_TAG_THREAD_LIST);
if (!entry)
return;
entry->parent = parent;
entry->process = process;
ListInit(&process_list->start, &process_list->lock);
}
else
{
FindProcessListEntryByProcess(process, &entry);
if (!entry)
return;
ListRemoveEntry(&process_list->start, entry, &process_list->lock);
}
}
VOID
ThreadCreateNotifyRoutine(
_In_ HANDLE ProcessId,
@ -185,6 +325,9 @@ ObPostOpCallbackRoutine(
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistrationContext);
UNREFERENCED_PARAMETER(OperationInformation);
}
_IRQL_requires_max_(APC_LEVEL)
@ -203,9 +346,6 @@ ObPreOpCallbackRoutine(
/* access mask to completely strip permissions */
ACCESS_MASK deny_access = SYNCHRONIZE | PROCESS_TERMINATE;
/* Access mask to be used for crss / lsass */
ACCESS_MASK downgrade_access = 0;
/*
* This callback routine is executed in the context of the thread that
* is requesting to open said handle
@ -213,9 +353,8 @@ ObPreOpCallbackRoutine(
PEPROCESS process_creator = PsGetCurrentProcess();
PEPROCESS protected_process;
PEPROCESS target_process = (PEPROCESS)OperationInformation->Object;
LONG target_process_id = PsGetProcessId(target_process);
LONG process_creator_id = PsGetProcessId(process_creator);
LONG protected_process_id = NULL;
HANDLE process_creator_id = PsGetProcessId(process_creator);
LONG protected_process_id = 0;
LPCSTR process_creator_name;
LPCSTR target_process_name;
LPCSTR protected_process_name;
@ -499,9 +638,9 @@ EnumHandleCallback(
* rare.
*/
report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
report->is_kernel_handle = NULL;
report->is_kernel_handle = 0;
report->process_id = PsGetProcessId(process);
report->thread_id = NULL;
report->thread_id = 0;
report->access = handle_access_mask;
RtlCopyMemory(&report->process_name, process_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH);
@ -515,19 +654,23 @@ end:
NTSTATUS
EnumerateProcessHandles(
_In_ PEPROCESS Process
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_In_opt_ PVOID Context
)
{
/* Handles are paged out so we need to be at an IRQL that allows paging */
PAGED_CODE();
if (!Process)
UNREFERENCED_PARAMETER(Context);
if (!ProcessListEntry)
return STATUS_INVALID_PARAMETER;
if (Process == PsInitialSystemProcess)
if (ProcessListEntry->process == PsInitialSystemProcess)
return STATUS_SUCCESS;
PHANDLE_TABLE handle_table = *(PHANDLE_TABLE*)((uintptr_t)Process + EPROCESS_HANDLE_TABLE_OFFSET);
PHANDLE_TABLE handle_table =
*(PHANDLE_TABLE*)((uintptr_t)ProcessListEntry->process + EPROCESS_HANDLE_TABLE_OFFSET);
if (!handle_table)
return STATUS_INVALID_ADDRESS;
@ -559,36 +702,36 @@ EnumerateProcessHandles(
* The Context argument is simply a pointer to a user designed context structure
* which is passed to the callback function.
*/
VOID
EnumerateProcessListWithCallbackFunction(
_In_ PVOID Function,
_In_opt_ PVOID Context
)
{
PAGED_CODE();
UINT64 current_process;
PLIST_ENTRY process_list_head = NULL;
PLIST_ENTRY process_list_entry = NULL;
PEPROCESS base_process = PsInitialSystemProcess;
if (!base_process)
return;
process_list_head = (UINT64)((UINT64)base_process + EPROCESS_PLIST_ENTRY_OFFSET);
process_list_entry = process_list_head;
do
{
current_process = (PEPROCESS)((UINT64)process_list_entry - EPROCESS_PLIST_ENTRY_OFFSET);
if (!current_process)
return;
VOID(*callback_function_ptr)(PEPROCESS, PVOID) = Function;
(*callback_function_ptr)(current_process, Context);
process_list_entry = process_list_entry->Flink;
} while (process_list_entry != process_list_head->Blink);
}
//VOID
//EnumerateProcessListWithCallbackFunction(
// _In_ PVOID Function,
// _In_opt_ PVOID Context
//)
//{
// PAGED_CODE();
//
// UINT64 current_process = 0;
// PLIST_ENTRY process_list_head = NULL;
// PLIST_ENTRY process_list_entry = NULL;
// PEPROCESS base_process = PsInitialSystemProcess;
//
// if (!base_process)
// return;
//
// process_list_head = (UINT64)((UINT64)base_process + EPROCESS_PLIST_ENTRY_OFFSET);
// process_list_entry = process_list_head;
//
// do
// {
// current_process = (PEPROCESS)((UINT64)process_list_entry - EPROCESS_PLIST_ENTRY_OFFSET);
//
// if (!current_process)
// return;
//
// VOID(*callback_function_ptr)(PEPROCESS, PVOID) = Function;
// (*callback_function_ptr)(current_process, Context);
//
// process_list_entry = process_list_entry->Flink;
//
// } while (process_list_entry != process_list_head->Blink);
//}

View file

@ -54,6 +54,14 @@ typedef struct _THREAD_LIST_ENTRY
}THREAD_LIST_ENTRY, * PTHREAD_LIST_ENTRY;
typedef struct _PROCESS_LIST_ENTRY
{
SINGLE_LIST_ENTRY list;
PKPROCESS process;
PKPROCESS parent;
}PROCESS_LIST_ENTRY, *PPROCESS_LIST_ENTRY;
VOID
NTAPI
ExUnlockHandleTableEntry(
@ -82,20 +90,24 @@ ObPreOpCallbackRoutine(
// _In_ BOOLEAN Create
//);
VOID
EnumerateProcessListWithCallbackFunction(
_In_ PVOID Function,
_In_opt_ PVOID Context
);
//VOID
//EnumerateProcessListWithCallbackFunction(
// _In_ PVOID Function,
// _In_opt_ PVOID Context
//);
NTSTATUS
EnumerateProcessHandles(
_In_ PEPROCESS Process
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_In_opt_ PVOID Context
);
NTSTATUS
InitialiseThreadList();
NTSTATUS
InitialiseProcessList();
VOID
ThreadCreateNotifyRoutine(
_In_ HANDLE ProcessId,
@ -103,6 +115,13 @@ ThreadCreateNotifyRoutine(
_In_ BOOLEAN Create
);
VOID
ProcessCreateNotifyRoutine(
_In_ HANDLE ParentId,
_In_ HANDLE ProcessID,
_In_ BOOLEAN Create
);
VOID
CleanupThreadListOnDriverUnload();
@ -114,6 +133,14 @@ FindThreadListEntryByThreadAddress(
_Inout_ PTHREAD_LIST_ENTRY* Entry
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
FindProcessListEntryByProcess(
_In_ PKPROCESS Process,
_Inout_ PPROCESS_LIST_ENTRY* Entry
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
@ -122,4 +149,15 @@ EnumerateThreadListWithCallbackRoutine(
_In_opt_ PVOID Context
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
EnumerateProcessListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
_In_opt_ PVOID Context
);
VOID
CleanupProcessListOnDriverUnload();
#endif

View file

@ -51,6 +51,10 @@ STATIC
VOID
DrvUnloadFreeThreadList();
STATIC
VOID
DrvUnloadFreeProcessList();
STATIC
NTSTATUS
DrvLoadEnableNotifyRoutines();
@ -97,6 +101,7 @@ DrvLoadInitialiseDriverConfig(
#pragma alloc_text(PAGE, DrvUnloadFreeGlobalReportQueue)
#pragma alloc_text(PAGE, DrvUnloadFreeThreadList)
#pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
#pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
#pragma alloc_text(PAGE, DrvLoadInitialiseObCbConfig)
#pragma alloc_text(PAGE, DrvLoadInitialiseReportQueue)
#pragma alloc_text(PAGE, DrvLoadInitialiseProcessConfig)
@ -917,6 +922,15 @@ DrvUnloadFreeThreadList()
CleanupThreadListOnDriverUnload();
}
STATIC
VOID
DrvUnloadFreeProcessList()
{
PAGED_CODE();
CleanupProcessListOnDriverUnload();
}
STATIC
VOID
DriverUnload(
@ -933,6 +947,7 @@ DriverUnload(
DrvUnloadUnregisterObCallbacks();
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
DrvUnloadFreeConfigStrings();
DrvUnloadFreeGlobalReportQueue();
DrvUnloadFreeSymbolicLink();
@ -964,10 +979,24 @@ DrvLoadEnableNotifyRoutines()
return status;
}
status = InitialiseProcessList();
if (!NT_SUCCESS(status))
{
DrvUnloadFreeThreadList();
DEBUG_ERROR("InitialiseProcessList failed with status %x", status);
return status;
}
status = PsSetCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", status);
DrvUnloadFreeThreadList();
DrvUnloadFreeProcessList();
return status;
}
return status;
}

View file

@ -79,7 +79,8 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>

View file

@ -21,6 +21,7 @@
* reference: https://secret.club/2020/01/12/battleye-hypervisor-detection.html
*/
_IRQL_always_function_max_(HIGH_LEVEL)
STATIC
INT
APERFMsrTimingCheck()
@ -34,7 +35,7 @@ APERFMsrTimingCheck()
* First thing we do is we lock the current thread to the logical processor
* its executing on.
*/
new_affinity = (KAFFINITY)(1ul << KeGetCurrentProcessorNumber());
new_affinity = (KAFFINITY)(1ull << KeGetCurrentProcessorNumber());
old_affinity = KeSetSystemAffinityThreadEx(new_affinity);
/*

View file

@ -72,7 +72,7 @@ DispatchApcOperation(
return status;
}
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
//_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
@ -91,14 +91,14 @@ DeviceControl(
/*
* LMAO
*/
ReadProcessInitialisedConfigFlag(&security_flag);
//ReadProcessInitialisedConfigFlag(&security_flag);
if (security_flag == FALSE &&
stack_location->Parameters.DeviceIoControl.IoControlCode != IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH)
{
status = STATUS_ACCESS_DENIED;
goto end;
}
//if (security_flag == FALSE &&
// stack_location->Parameters.DeviceIoControl.IoControlCode != IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH)
//{
// status = STATUS_ACCESS_DENIED;
// goto end;
//}
switch (stack_location->Parameters.DeviceIoControl.IoControlCode)
{
@ -209,7 +209,7 @@ DeviceControl(
case IOCTL_ENUMERATE_HANDLE_TABLES:
/* can maybe implement this better so we can extract a status value */
EnumerateProcessListWithCallbackFunction(
EnumerateProcessListWithCallbackRoutine(
EnumerateProcessHandles,
NULL
);

View file

@ -12,7 +12,7 @@ typedef struct _DRIVER_INITIATION_INFORMATION
} DRIVER_INITIATION_INFORMATION, * PDRIVER_INITIATION_INFORMATION;
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
//_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,

View file

@ -87,13 +87,13 @@ WalkKernelPageTables(
STATIC
VOID
IncrementProcessCounter(
_In_ PEPROCESS Process,
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_Inout_opt_ PVOID Context);
STATIC
VOID
CheckIfProcessAllocationIsInProcessList(
_In_ PEPROCESS Process,
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_Inout_opt_ PVOID Context);
#ifdef ALLOC_PRAGMA
@ -617,12 +617,14 @@ WalkKernelPageTables(
STATIC
VOID
IncrementProcessCounter(
_In_ PEPROCESS Process,
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_Inout_opt_ PVOID Context
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(ProcessListEntry);
PPROCESS_SCAN_CONTEXT context = (PPROCESS_SCAN_CONTEXT)Context;
if (!context)
@ -634,7 +636,7 @@ IncrementProcessCounter(
STATIC
VOID
CheckIfProcessAllocationIsInProcessList(
_In_ PEPROCESS Process,
_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_Inout_opt_ PVOID Context
)
{
@ -650,8 +652,8 @@ CheckIfProcessAllocationIsInProcessList(
{
allocation_address = (PUINT64)context->process_buffer;
if ((UINT64)Process >= allocation_address[i] - PROCESS_OBJECT_ALLOCATION_MARGIN &&
(UINT64)Process <= allocation_address[i] + PROCESS_OBJECT_ALLOCATION_MARGIN)
if ((UINT64)ProcessListEntry->process >= allocation_address[i] - PROCESS_OBJECT_ALLOCATION_MARGIN &&
(UINT64)ProcessListEntry->process <= allocation_address[i] + PROCESS_OBJECT_ALLOCATION_MARGIN)
{
RtlZeroMemory((UINT64)context->process_buffer + i * sizeof(UINT64), sizeof(UINT64));
}
@ -669,7 +671,7 @@ FindUnlinkedProcesses(
PROCESS_SCAN_CONTEXT context = { 0 };
PINVALID_PROCESS_ALLOCATION_REPORT report_buffer = NULL;
EnumerateProcessListWithCallbackFunction(
EnumerateProcessListWithCallbackRoutine(
IncrementProcessCounter,
&context
);
@ -688,16 +690,16 @@ FindUnlinkedProcesses(
WalkKernelPageTables(&context);
EnumerateProcessListWithCallbackFunction(
EnumerateProcessListWithCallbackRoutine(
CheckIfProcessAllocationIsInProcessList,
&context
);
allocation_address = (PUINT64)context.process_buffer;
for (INT i = 0; i < context.process_count; i++)
for (INT index = 0; index < context.process_count; index++)
{
if (allocation_address[i] == NULL)
if (allocation_address[index] == NULL)
continue;
/*
@ -717,7 +719,7 @@ FindUnlinkedProcesses(
RtlCopyMemory(
report_buffer->process,
(UINT64)allocation_address[i] - OBJECT_HEADER_SIZE,
(UINT64)allocation_address[index] - OBJECT_HEADER_SIZE,
REPORT_INVALID_PROCESS_BUFFER_SIZE
);

View file

@ -47,43 +47,41 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
std::cout << "Seed: " << seed << std::endl;
//switch (seed)
//{
//case 0:
// kmanager.EnumerateHandleTables();
// break;
//case 1:
// kmanager.PerformIntegrityCheck();
// break;
//case 2:
// kmanager.ScanPoolsForUnlinkedProcesses();
// break;
//case 3:
// kmanager.VerifySystemModules();
// break;
//case 4:
// kmanager.ValidateProcessModules();
// break;
//case 5:
// kmanager.RunNmiCallbacks();
// break;
//case 6:
// kmanager.CheckForAttachedThreads();
// break;
//case 7:
// kmanager.InitiateApcStackwalkOperation();
// break;
//case 8:
// kmanager.CheckForHiddenThreads();
// break;
//case 9:
// kmanager.CheckForEptHooks();
// break;
//}
switch (seed)
{
case 0:
kmanager.EnumerateHandleTables();
break;
case 1:
kmanager.PerformIntegrityCheck();
break;
case 2:
kmanager.ScanPoolsForUnlinkedProcesses();
break;
case 3:
kmanager.VerifySystemModules();
break;
case 4:
kmanager.ValidateProcessModules();
break;
case 5:
kmanager.RunNmiCallbacks();
break;
case 6:
kmanager.CheckForAttachedThreads();
break;
case 7:
kmanager.InitiateApcStackwalkOperation();
break;
case 8:
kmanager.CheckForHiddenThreads();
break;
case 9:
kmanager.CheckForEptHooks();
break;
}
kmanager.InitiateApcStackwalkOperation();
kmanager.MonitorCallbackReports();
std::this_thread::sleep_for(std::chrono::seconds(10));
}