mirror-ac/driver/ioctl.c

554 lines
19 KiB
C
Raw Normal View History

2023-08-17 10:45:50 +02:00
#include "ioctl.h"
2023-08-19 04:52:57 +02:00
#include "modules.h"
2023-08-20 16:12:04 +02:00
#include "driver.h"
2023-08-20 17:04:53 +02:00
#include "callbacks.h"
2023-08-26 14:07:06 +02:00
#include "pool.h"
2023-08-22 19:32:25 +02:00
#include "integrity.h"
2023-08-30 13:15:57 +02:00
#include "thread.h"
2023-09-02 10:54:04 +02:00
#include "queue.h"
2023-08-21 14:40:40 +02:00
#include "hv.h"
#include "imports.h"
2024-01-15 02:01:14 +01:00
#include "list.h"
2023-08-21 14:40:40 +02:00
2023-12-13 05:06:27 +01:00
STATIC
NTSTATUS
DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation);
2023-10-06 13:08:30 +02:00
#ifdef ALLOC_PRAGMA
2023-12-13 05:06:27 +01:00
# pragma alloc_text(PAGE, DispatchApcOperation)
# pragma alloc_text(PAGE, DeviceControl)
# pragma alloc_text(PAGE, DeviceClose)
# pragma alloc_text(PAGE, DeviceCreate)
2023-10-06 13:08:30 +02:00
#endif
#define IOCTL_RUN_NMI_CALLBACKS \
2023-12-13 05:06:27 +01:00
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20001, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_DRIVER_OBJECTS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20002, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20004, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20005, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PERFORM_VIRTUALIZATION_CHECK \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20006, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_ENUMERATE_HANDLE_TABLES \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20007, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20008, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_TOTAL_MODULE_SIZE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20009, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20010, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCAN_FOR_UNLINKED_PROCESS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20011, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PERFORM_INTEGRITY_CHECK \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DETECT_ATTACHED_THREADS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20014, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_PROCESS_LOADED_MODULE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20015, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_HARDWARE_INFORMATION \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20016, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_INITIATE_APC_OPERATION \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20017, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_CHECK_FOR_EPT_HOOK \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20018, METHOD_BUFFERED, FILE_ANY_ACCESS)
2023-12-29 17:20:32 +01:00
#define IOCTL_LAUNCH_DPC_STACKWALK \
2023-12-13 05:06:27 +01:00
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20019, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_SYSTEM_MODULES \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20020, METHOD_BUFFERED, FILE_ANY_ACCESS)
2024-01-11 10:16:55 +01:00
#define IOCTL_INSERT_IRP_INTO_QUEUE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20021, METHOD_BUFFERED, FILE_ANY_ACCESS)
2023-09-28 18:10:01 +02:00
#define APC_OPERATION_STACKWALK 0x1
2024-01-11 10:16:55 +01:00
VOID
IrpQueueMarkIrpCompleteCallback(_In_ PIRP_QUEUE_ENTRY Entry)
{
ImpIofCompleteRequest(Entry->irp, IO_NO_INCREMENT);
}
VOID
IrpQueueDequeue(PVOID Callback)
{
PIRP_QUEUE_HEAD queue = GetIrpQueueHead();
ListFreeFirstEntry(&queue->start, &queue->lock, Callback);
}
VOID
IrpQueueInitialise()
{
PIRP_QUEUE_HEAD queue = GetIrpQueueHead();
queue->count = 0;
ImpKeInitializeGuardedMutex(&queue->lock);
ListInit(&queue->start, &queue->lock);
}
VOID
IrpQueueInsert(PIRP Irp)
{
PIRP_QUEUE_HEAD queue = GetIrpQueueHead();
PIRP_QUEUE_ENTRY entry = NULL;
entry = ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(IRP_QUEUE_ENTRY), POOL_TAG_IRP_QUEUE);
if (!entry)
return;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
entry->irp = Irp;
queue->count++;
ListInsert(&queue->start, &entry->entry, &queue->lock);
IrpQueueDequeue(IrpQueueMarkIrpCompleteCallback);
}
2023-09-28 18:10:01 +02:00
STATIC
2023-10-05 08:27:17 +02:00
NTSTATUS
2023-12-13 05:06:27 +01:00
DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation)
2023-09-28 18:10:01 +02:00
{
2023-12-13 05:06:27 +01:00
PAGED_CODE();
2023-10-09 20:19:51 +02:00
2023-12-23 19:52:55 +01:00
NTSTATUS status = STATUS_UNSUCCESSFUL;
DEBUG_VERBOSE("Dispatching APC Operation...");
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
switch (Operation->operation_id)
{
case APC_OPERATION_STACKWALK:
2023-09-28 18:10:01 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("Initiating APC stackwalk operation with operation id %i",
Operation->operation_id);
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
status = ValidateThreadsViaKernelApc();
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateThreadsViaKernelApc failed with status %x", status);
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
return status;
2023-09-28 18:10:01 +02:00
2023-12-23 19:52:55 +01:00
default: DEBUG_WARNING("Invalid operation ID passed"); return STATUS_INVALID_PARAMETER;
2023-12-13 05:06:27 +01:00
}
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
return status;
2023-09-28 18:10:01 +02:00
}
2023-09-27 15:10:12 +02:00
2023-11-09 08:30:59 +01:00
/*
2023-12-13 05:06:27 +01:00
* Obviously, its important we check that the input and output buffer sizes for each IRP is big
* enough to hold the incoming and outgoing information.
*
* Another important thing to note is that the windows IO manager will only zero out the size
* of the input buffer. Given that we use METHOD_BUFFERED for all communication, the input
* and output buffer are the same, with the size used being that of the greatest buffer passed
* to DeviceIoControl. The IO manager will then zero our the buffer to the size of the input
* buffer, so if the output buffer is larger then the input buffer there will be uninitialised
* memory in the buffer so we must zero out the buffer to the length of the output buffer.
*
* We then set the IoStatus.Information field to the size of the buffer we are passing back.
* If we don't do this and we allocate an output buffer of size 0x1000, yet only use 0x100 bytes,
* the user mode apps output buffer will receive 0x100 bytes + 0x900 bytes of uninitialised memory
* which is an information leak.
*/
2023-11-09 08:30:59 +01:00
NTSTATUS
2023-12-13 05:06:27 +01:00
ValidateIrpOutputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize)
2023-11-09 08:30:59 +01:00
{
2023-12-13 05:06:27 +01:00
if (!Irp || !RequiredSize)
return STATUS_INVALID_PARAMETER;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
PIO_STACK_LOCATION io = IoGetCurrentIrpStackLocation(Irp);
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
if (!io)
return STATUS_UNSUCCESSFUL;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
if (io->Parameters.DeviceIoControl.OutputBufferLength < RequiredSize)
return STATUS_BUFFER_TOO_SMALL;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
RtlSecureZeroMemory(Irp->AssociatedIrp.SystemBuffer, RequiredSize);
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
Irp->IoStatus.Information = RequiredSize;
2023-11-09 12:11:02 +01:00
2023-12-13 05:06:27 +01:00
return STATUS_SUCCESS;
2023-11-09 08:30:59 +01:00
}
/*
2023-12-13 05:06:27 +01:00
* Here we just check that the input buffers size matches the expected size..
* It isnt a very secure check but we can work on that later...
*/
2023-11-09 08:30:59 +01:00
NTSTATUS
2023-12-13 05:06:27 +01:00
ValidateIrpInputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize)
2023-11-09 08:30:59 +01:00
{
2023-12-13 05:06:27 +01:00
if (!Irp || !RequiredSize)
return STATUS_INVALID_PARAMETER;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
PIO_STACK_LOCATION io = IoGetCurrentIrpStackLocation(Irp);
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
if (!io)
return STATUS_UNSUCCESSFUL;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
if (io->Parameters.DeviceIoControl.InputBufferLength != RequiredSize)
return STATUS_INVALID_BUFFER_SIZE;
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
return STATUS_SUCCESS;
2023-11-09 08:30:59 +01:00
}
2023-10-05 08:27:17 +02:00
NTSTATUS
2024-01-13 22:33:57 +01:00
DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
2023-08-17 10:45:50 +02:00
{
2023-12-13 05:06:27 +01:00
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(Irp);
HANDLE handle = NULL;
PKTHREAD thread = NULL;
BOOLEAN security_flag = FALSE;
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
/*
* LMAO
*/
ReadProcessInitialisedConfigFlag(&security_flag);
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
if (security_flag == FALSE && stack_location->Parameters.DeviceIoControl.IoControlCode !=
IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH)
{
status = STATUS_ACCESS_DENIED;
goto end;
}
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
switch (stack_location->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_RUN_NMI_CALLBACKS:
2023-08-19 04:52:57 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_RUN_NMI_CALLBACKS Received.");
2023-12-13 05:06:27 +01:00
status = HandleNmiIOCTL(Irp);
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("RunNmiCallbacks failed with status %lx", status);
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-20 07:46:02 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_VALIDATE_DRIVER_OBJECTS:
2023-08-19 04:52:57 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_VALIDATE_DRIVER_OBJECTS Received.");
2023-12-13 05:06:27 +01:00
/*
* The reason this function is run in a new thread and not the thread
* issuing the IOCTL is because ZwOpenDirectoryObject issues a
* user mode handle if called on the user mode thread calling DeviceIoControl.
* This is a problem because when we pass said handle to ObReferenceObjectByHandle
* it will issue a bug check under windows driver verifier.
*/
2023-08-19 08:06:51 +02:00
status = ImpPsCreateSystemThread(
2023-12-13 05:06:27 +01:00
&handle, PROCESS_ALL_ACCESS, NULL, NULL, NULL, HandleValidateDriversIOCTL, Irp);
2023-08-21 11:45:00 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("PsCreateSystemThread failed with status %x", status);
2023-12-13 05:06:27 +01:00
goto end;
}
2023-08-19 08:06:51 +02:00
2023-12-13 05:06:27 +01:00
/*
* Thread objects are a type of dispatcher object, meaning when they are freed
* its set to the signal state and any waiters will be signalled. This allows
* us to wait til our threads terminated and the IRP buffer has been either filled
* or left empty and then from there we can complete the IRP and return.
*/
status = ImpObReferenceObjectByHandle(
2023-12-13 05:06:27 +01:00
handle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &thread, NULL);
2023-08-19 04:52:57 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectByHandle failed with status %lx", status);
ImpZwClose(handle);
2023-12-13 05:06:27 +01:00
goto end;
}
2023-08-20 16:12:04 +02:00
ImpKeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
2023-08-24 15:12:49 +02:00
ImpZwClose(handle);
ImpObDereferenceObject(thread);
2023-08-24 15:12:49 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-24 15:12:49 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH:;
2023-10-05 08:27:17 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH Received");
2024-01-11 10:16:55 +01:00
2023-12-13 05:06:27 +01:00
status = ProcLoadInitialiseProcessConfig(Irp);
2024-01-11 10:16:55 +01:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("InitialiseProcessConfig failed with status %x", status);
2023-12-13 05:06:27 +01:00
goto end;
}
2024-01-11 10:16:55 +01:00
2024-01-15 02:01:14 +01:00
status = RegisterProcessObCallbacks();
2023-09-27 06:22:14 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("EnableObCallbacks failed with status %x", status);
2023-09-27 06:22:14 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-20 17:04:53 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
2023-08-20 17:04:53 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE Received");
2023-12-13 05:06:27 +01:00
status = QueryActiveApcContextsForCompletion();
2023-08-20 16:12:04 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("QueryActiveApcContextsForCompletion failed with status %x",
2023-12-13 05:06:27 +01:00
status);
2023-08-21 17:48:34 +02:00
2023-12-13 05:06:27 +01:00
status = HandlePeriodicGlobalReportQueueQuery(Irp);
2023-08-21 17:48:34 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("HandlePeriodicGlobalReportQueueQuery failed with status %x",
status);
2023-08-21 17:48:34 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-21 17:48:34 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_PERFORM_VIRTUALIZATION_CHECK:
2023-10-05 08:27:17 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_PERFORM_VIRTUALIZATION_CHECK Received");
2023-12-13 05:06:27 +01:00
status = PerformVirtualizationDetection(Irp);
2023-08-22 10:51:52 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("PerformVirtualizationDetection failed with status %x", status);
2023-08-22 10:51:52 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-22 19:32:25 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_ENUMERATE_HANDLE_TABLES:
2023-08-31 18:42:38 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_ENUMERATE_HANDLE_TABLES Received");
2023-12-13 05:06:27 +01:00
/* can maybe implement this better so we can extract a status value */
EnumerateProcessListWithCallbackRoutine(EnumerateProcessHandles, NULL);
2023-08-31 18:42:38 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-31 18:42:38 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS:
2023-08-31 18:42:38 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_VERBOSE("IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS Received");
status = ImpPsCreateSystemThread(&handle,
2024-01-11 10:16:55 +01:00
PROCESS_ALL_ACCESS,
NULL,
NULL,
NULL,
RetrieveInMemoryModuleExecutableSections,
Irp);
2023-08-31 18:42:38 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("PsCreateSystemThread failed with status %x", status);
2023-12-13 05:06:27 +01:00
goto end;
}
2023-08-31 18:42:38 +02:00
status = ImpObReferenceObjectByHandle(
2023-12-13 05:06:27 +01:00
handle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &thread, NULL);
2023-08-22 19:32:25 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ObReferenceObjectbyhandle failed with status %lx", status);
ImpZwClose(handle);
2023-12-13 05:06:27 +01:00
goto end;
}
2023-08-22 19:32:25 +02:00
ImpKeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
2023-08-23 14:14:20 +02:00
ImpZwClose(handle);
ImpObDereferenceObject(thread);
2023-08-23 14:14:20 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-23 14:14:20 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_REQUEST_TOTAL_MODULE_SIZE:
2023-08-24 15:12:49 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_REQUEST_TOTAL_MODULE_SIZE Received");
2023-12-13 05:06:27 +01:00
status = GetDriverImageSize(Irp);
2023-08-24 15:12:49 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("GetDriverImageSize failed with status %x", status);
2023-08-24 15:12:49 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-28 17:00:52 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION:
2023-08-28 17:00:52 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION Received");
2023-12-13 05:06:27 +01:00
ProcCloseClearProcessConfiguration();
2024-01-15 02:01:14 +01:00
UnregisterProcessObCallbacks();
2023-08-28 17:00:52 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-08-28 17:00:52 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_SCAN_FOR_UNLINKED_PROCESS:
2023-08-30 13:15:57 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_SCAN_FOR_UNLINKED_PROCESS Received");
2023-12-13 05:06:27 +01:00
status = FindUnlinkedProcesses();
2023-08-30 13:15:57 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("FindUnlinkedProcesses failed with status %x", status);
2023-08-30 13:15:57 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-01 13:46:31 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_PERFORM_INTEGRITY_CHECK:
2023-09-01 13:46:31 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_PERFORM_INTEGRITY_CHECK Received");
2024-01-02 23:29:23 +01:00
status = ValidateOurDriverImage();
2023-09-01 13:46:31 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("VerifyInMemoryImageVsDiskImage failed with status %x", status);
2023-09-02 15:47:15 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-02 15:47:15 +02:00
2023-12-23 19:52:55 +01:00
case IOCTL_DETECT_ATTACHED_THREADS:
DEBUG_INFO("IOCTL_DETECT_ATTACHED_THREADS Received");
DetectThreadsAttachedToProtectedProcess();
break;
2023-09-02 15:47:15 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_VALIDATE_PROCESS_LOADED_MODULE:
2023-09-05 11:16:32 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_VALIDATE_PROCESS_LOADED_MODULE Received");
2023-12-13 05:06:27 +01:00
status = ValidateProcessLoadedModule(Irp);
2023-09-05 11:16:32 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateProcessLoadedModule failed with status %x", status);
2023-09-05 11:16:32 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-05 11:16:32 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_REQUEST_HARDWARE_INFORMATION:;
2023-09-07 19:49:36 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_REQUEST_HARDWARE_INFORMATION Received");
2023-12-13 05:06:27 +01:00
PSYSTEM_INFORMATION system_information = NULL;
2023-12-23 19:52:55 +01:00
2023-12-13 05:06:27 +01:00
GetDriverConfigSystemInformation(&system_information);
2023-09-07 19:49:36 +02:00
2023-12-23 19:52:55 +01:00
if (!system_information)
2023-12-13 05:06:27 +01:00
{
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("GetDriverConfigSystemInformation failed with no status.");
2023-12-13 05:06:27 +01:00
goto end;
}
2023-09-07 19:49:36 +02:00
2023-12-13 05:06:27 +01:00
status = ValidateIrpOutputBuffer(Irp, sizeof(SYSTEM_INFORMATION));
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
{
2023-12-23 19:52:55 +01:00
DEBUG_ERROR("ValidateIrpOutputBuffer failed with status %x", status);
2023-12-13 05:06:27 +01:00
goto end;
}
2023-11-09 08:30:59 +01:00
2023-12-13 05:06:27 +01:00
Irp->IoStatus.Information = sizeof(SYSTEM_INFORMATION);
2023-09-07 19:49:36 +02:00
2023-12-13 05:06:27 +01:00
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
system_information,
sizeof(SYSTEM_INFORMATION));
2023-09-07 19:49:36 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-07 19:49:36 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_INITIATE_APC_OPERATION:;
2023-09-28 18:10:01 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_INITIATE_APC_OPERATION Received");
2023-12-13 05:06:27 +01:00
PAPC_OPERATION_ID operation = (PAPC_OPERATION_ID)Irp->AssociatedIrp.SystemBuffer;
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
status = DispatchApcOperation(operation);
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("DispatchApcOperation failed with status %x", status);
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_CHECK_FOR_EPT_HOOK:
2023-10-06 09:02:10 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_CHECK_FOR_EPT_HOOK Received");
2023-12-13 05:06:27 +01:00
status = DetectEptHooksInKeyFunctions();
2023-10-06 09:02:10 +02:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("DetectEpthooksInKeyFunctions failed with status %x", status);
2023-10-06 09:02:10 +02:00
2023-12-13 05:06:27 +01:00
break;
2023-09-28 18:10:01 +02:00
2023-12-13 05:06:27 +01:00
case IOCTL_VALIDATE_SYSTEM_MODULES:
2023-10-30 12:57:24 +01:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("IOCTL_VALIDATE_SYSTEM_MODULES Received");
2023-12-31 15:06:24 +01:00
status = SystemModuleVerificationDispatcher();
2023-10-30 12:57:24 +01:00
2023-12-13 05:06:27 +01:00
if (!NT_SUCCESS(status))
DEBUG_ERROR("ValidateSystemModules failed with status %x", status);
2023-10-30 12:57:24 +01:00
2023-12-13 05:06:27 +01:00
break;
2023-10-30 12:57:24 +01:00
2023-12-29 17:20:32 +01:00
case IOCTL_LAUNCH_DPC_STACKWALK:
DEBUG_INFO("IOCTL_LAUNCH_DPC_STACKWALK Received");
status = DispatchStackwalkToEachCpuViaDpc();
if (!NT_SUCCESS(status))
DEBUG_ERROR("DispatchStackwalkToEachCpuViaDpc failed with status %x",
status);
break;
2024-01-11 10:16:55 +01:00
case IOCTL_INSERT_IRP_INTO_QUEUE:
DEBUG_INFO("IOCTL_INSERT_IRP_INTO_QUEUE Received");
IrpQueueInsert(Irp);
/* we dont want to complete the request */
return STATUS_SUCCESS;
2023-12-29 17:20:32 +01:00
2023-12-13 05:06:27 +01:00
default:
2023-12-23 19:52:55 +01:00
DEBUG_WARNING("Invalid IOCTL passed to driver: %lx",
2024-01-11 10:16:55 +01:00
stack_location->Parameters.DeviceIoControl.IoControlCode);
2023-12-23 19:52:55 +01:00
2023-12-13 05:06:27 +01:00
status = STATUS_INVALID_PARAMETER;
break;
}
2023-08-19 04:52:57 +02:00
2023-08-19 08:06:51 +02:00
end:
2023-12-23 19:52:55 +01:00
DEBUG_VERBOSE("Completing IRP with status %x", status);
2023-12-13 05:06:27 +01:00
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
2023-08-17 10:45:50 +02:00
}
2024-01-11 10:16:55 +01:00
NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
2023-08-17 10:45:50 +02:00
{
2023-12-13 05:06:27 +01:00
PAGED_CODE();
UNREFERENCED_PARAMETER(DeviceObject);
2023-10-07 17:37:47 +02:00
2023-12-23 19:52:55 +01:00
DEBUG_INFO("Handle to driver closed.");
2023-08-30 15:23:04 +02:00
2023-12-13 05:06:27 +01:00
/* we also lose reports here, so sohuld pass em into the irp before freeing */
FreeGlobalReportQueueObjects();
ProcCloseClearProcessConfiguration();
2024-01-15 02:01:14 +01:00
UnregisterProcessObCallbacks();
2023-08-30 15:23:04 +02:00
2023-12-13 05:06:27 +01:00
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
2023-08-17 10:45:50 +02:00
}
2024-01-11 10:16:55 +01:00
NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
2023-08-17 10:45:50 +02:00
{
2023-12-13 05:06:27 +01:00
PAGED_CODE();
2023-12-23 19:52:55 +01:00
DEBUG_INFO("Handle to driver opened.");
2023-12-13 05:06:27 +01:00
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
2023-08-17 10:45:50 +02:00
}