some stuf

This commit is contained in:
lhodges1 2024-01-11 20:16:55 +11:00
parent 602496062c
commit 2a4a5e344d
32 changed files with 325 additions and 207 deletions

View file

@ -12,21 +12,22 @@ open source anti cheat (lol) which I made for fun.
- Handle stripping via obj callbacks
- Process handle table enumeration
- System module device object verification
- System module .text integrity checks (see known issues)
- System module .text integrity checks
- Unlinked process detection
- Removed thread PspCidTable entry detection
- Dispatch routine validation
- Extraction of hardware identifiers
- EPT hook detection (currently detects hyperdbg and DdiMon)
- EPT hook detection
- Driver integrity checks both locally and over server
- Hypervisor detection
- HalDispatch and HalPrivateDispatch routine validation
- Dynamic import resolving
# planned features
- Heartbeat
- optimise stuff
- ntoskrnl integrity checks, or atleast a small subset of the kernel encompasing critical functions
- ntoskrnl integrity checks
- spoofed stack identifier
- process module inline hook detection (this would include checking whether the hook is valid, as many legimate programs hook user mode modules such as discord, nvidia overlay etc.)
- cr3 protection
@ -37,6 +38,7 @@ open source anti cheat (lol) which I made for fun.
- testing program to test the features
- simple user mode logger + usermode logging overhaul
- data ptr detction (+ chained data ptr walking)
- lots more which I cant think of
# example

28
ac.sln
View file

@ -11,9 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "service", "service\service.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "server", "server\server.csproj", "{4D0777F0-2D3D-4FD7-9C0F-CD4DEC1A99E9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdrv", "testdrv\testdrv.vcxproj", "{3CE9C9B1-1FB1-4770-ABBB-EE4E6AA949B0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testcli", "testcli\testcli.vcxproj", "{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdrv", "test\driver\testdrv.vcxproj", "{3CE9C9B1-1FB1-4770-ABBB-EE4E6AA949B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -175,30 +173,6 @@ Global
{3CE9C9B1-1FB1-4770-ABBB-EE4E6AA949B0}.Release|x86.ActiveCfg = Release|x64
{3CE9C9B1-1FB1-4770-ABBB-EE4E6AA949B0}.Release|x86.Build.0 = Release|x64
{3CE9C9B1-1FB1-4770-ABBB-EE4E6AA949B0}.Release|x86.Deploy.0 = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|Any CPU.ActiveCfg = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|Any CPU.Build.0 = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|ARM64.ActiveCfg = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|ARM64.Build.0 = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|x64.ActiveCfg = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|x64.Build.0 = Debug|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|x86.ActiveCfg = Debug|Win32
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Debug|x86.Build.0 = Debug|Win32
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|Any CPU.ActiveCfg = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|Any CPU.Build.0 = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|ARM64.ActiveCfg = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|ARM64.Build.0 = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|x64.ActiveCfg = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|x64.Build.0 = Release - No Server|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|x86.ActiveCfg = Release - No Server|Win32
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release - No Server|x86.Build.0 = Release - No Server|Win32
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|Any CPU.ActiveCfg = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|Any CPU.Build.0 = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|ARM64.ActiveCfg = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|ARM64.Build.0 = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|x64.ActiveCfg = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|x64.Build.0 = Release|x64
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|x86.ActiveCfg = Release|Win32
{BB9E4B6E-81E3-4D39-8928-0BA3F947C479}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -280,7 +280,7 @@ ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName,
if (ImageInfo->SystemModeImage == FALSE)
return;
FindDriverEntryByBaseAddress(ImageInfo->ImageBase, &entry);
if (entry)

View file

@ -68,6 +68,7 @@
#define POOL_TAG_LIST_ITEM 'tsil'
#define POOL_TAG_THREAD_LIST 'list'
#define POOL_TAG_DRIVER_LIST 'drvl'
#define POOL_TAG_IRP_QUEUE 'irpp'
#define IA32_APERF_MSR 0x000000E8

View file

@ -119,6 +119,7 @@ typedef struct _DRIVER_CONFIG
volatile BOOLEAN unload_in_progress;
KGUARDED_MUTEX lock;
SYS_MODULE_VAL_CONTEXT sys_val_context;
IRP_QUEUE_HEAD irp_queue;
} DRIVER_CONFIG, *PDRIVER_CONFIG;
@ -511,6 +512,12 @@ GetDriverObject()
return driver_config.driver_object;
}
PIRP_QUEUE_HEAD
GetIrpQueueHead()
{
return &driver_config.irp_queue;
}
GetSystemModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT* Context)
{
PAGED_CODE();
@ -1136,10 +1143,9 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath)
&driver_config.ansi_driver_name, &driver_config.unicode_driver_name, TRUE);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("RtlUnicodeStringToAnsiString failed with status %x", status);
return status;
}
return status;
}
STATIC
@ -1154,6 +1160,8 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST
ImpKeInitializeGuardedMutex(&driver_config.lock);
IrpQueueInitialise();
driver_config.unload_in_progress = FALSE;
driver_config.system_information.virtualised_environment = FALSE;
driver_config.sys_val_context.active = FALSE;
@ -1194,7 +1202,6 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST
return status;
}
_Function_class_(DRIVER_INITIALIZE) _IRQL_requires_same_
NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{

View file

@ -59,6 +59,21 @@ typedef struct _OB_CALLBACKS_CONFIG
} OB_CALLBACKS_CONFIG, *POB_CALLBACKS_CONFIG;
typedef struct _IRP_QUEUE_HEAD
{
SINGLE_LIST_ENTRY start;
volatile INT count;
KGUARDED_MUTEX lock;
} IRP_QUEUE_HEAD, *PIRP_QUEUE_HEAD;
typedef struct _IRP_QUEUE_ENTRY
{
SINGLE_LIST_ENTRY entry;
PIRP irp;
} IRP_QUEUE_ENTRY, *PIRP_QUEUE_ENTRY;
NTSTATUS
ProcLoadInitialiseProcessConfig(_In_ PIRP Irp);
@ -133,4 +148,7 @@ GetSystemModuleValidationContext(_Out_ PSYS_MODULE_VAL_CONTEXT* Context);
PDRIVER_OBJECT
GetDriverObject();
PIRP_QUEUE_HEAD
GetIrpQueueHead();
#endif

View file

@ -1558,7 +1558,7 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
if (CompareHashes(hash, entry->text_hash, SHA_256_HASH_LENGTH))
DEBUG_VERBOSE("Module: %s text regions are valid.", Module->FullPathName);
else
DEBUG_WARNING("**!!** Module: %s text regions are not valid **!!**", Module->FullPathName);
DEBUG_WARNING("**!!** Module: %s text regions are NOT valid **!!**", Module->FullPathName);
end:
if (hash)
@ -1927,4 +1927,5 @@ CalculateCpuCoreUsage(_In_ UINT32 Core)
user_time = *(UINT32*)((UINT64)kpcrb + KPCRB_USER_TIME_OFFSET);
return (100 - (UINT32)(UInt32x32To64(idle_time, 100) / (UINT64)(kernel_time + user_time)));
}
}

View file

@ -57,9 +57,53 @@ DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation);
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)
#define IOCTL_INSERT_IRP_INTO_QUEUE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20021, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define APC_OPERATION_STACKWALK 0x1
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);
}
STATIC
NTSTATUS
DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation)
@ -233,15 +277,15 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH:;
DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH Received");
status = ProcLoadInitialiseProcessConfig(Irp);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("InitialiseProcessConfig failed with status %x", status);
goto end;
}
status = ProcLoadEnableObCallbacks();
if (!NT_SUCCESS(status))
@ -292,12 +336,12 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
DEBUG_VERBOSE("IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS Received");
status = ImpPsCreateSystemThread(&handle,
PROCESS_ALL_ACCESS,
NULL,
NULL,
NULL,
RetrieveInMemoryModuleExecutableSections,
Irp);
PROCESS_ALL_ACCESS,
NULL,
NULL,
NULL,
RetrieveInMemoryModuleExecutableSections,
Irp);
if (!NT_SUCCESS(status))
{
@ -441,11 +485,6 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
DEBUG_INFO("IOCTL_VALIDATE_SYSTEM_MODULES Received");
/*
* Currently the validation is buggy, once the validation is better will
* probably bugcheck the system.
*/
//status = ValidateSystemModules();
status = SystemModuleVerificationDispatcher();
if (!NT_SUCCESS(status))
@ -465,10 +504,18 @@ DeviceControl(_In_ PDRIVER_OBJECT DriverObject, _Inout_ PIRP Irp)
break;
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;
default:
DEBUG_WARNING("Invalid IOCTL passed to driver: %lx",
stack_location->Parameters.DeviceIoControl.IoControlCode);
stack_location->Parameters.DeviceIoControl.IoControlCode);
status = STATUS_INVALID_PARAMETER;
break;
@ -481,11 +528,10 @@ end:
return status;
}
_Dispatch_type_(IRP_MJ_CLOSE) NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(DeviceObject);
DEBUG_INFO("Handle to driver closed.");
@ -499,11 +545,10 @@ _Dispatch_type_(IRP_MJ_CLOSE) NTSTATUS
return Irp->IoStatus.Status;
}
_Dispatch_type_(IRP_MJ_CREATE) NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
PAGED_CODE();
DEBUG_INFO("Handle to driver opened.");
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;

View file

@ -28,4 +28,7 @@ ValidateIrpOutputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize);
NTSTATUS
ValidateIrpInputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize);
VOID
IrpQueueInitialise();
#endif

View file

@ -450,8 +450,8 @@ GetSystemModuleInformation(_Out_ PSYSTEM_MODULES ModuleInformation)
}
/* Query the modules again this time passing a pointer to the allocated buffer */
status = RtlQueryModuleInformation(
&size, sizeof(RTL_MODULE_EXTENDED_INFO), driver_information);
status =
RtlQueryModuleInformation(&size, sizeof(RTL_MODULE_EXTENDED_INFO), driver_information);
if (!NT_SUCCESS(status))
{
@ -525,8 +525,8 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES SystemModules,
whitelisted_regions_buffer =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE,
WHITELISTED_MODULE_TAG);
WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE,
WHITELISTED_MODULE_TAG);
if (!whitelisted_regions_buffer)
goto end;
@ -688,7 +688,8 @@ HandleValidateDriversIOCTL(_Inout_ PIRP Irp)
goto end;
}
buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, MODULES_REPORT_POOL_TAG);
buffer =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, MODULES_REPORT_POOL_TAG);
if (!buffer)
{
@ -832,7 +833,7 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES SystemModules,
if (!NmiContext || !SystemModules)
return STATUS_INVALID_PARAMETER;
for (INT core = 0; core < ImpKeQueryActiveProcessorCount(0); core++)
{
/* Make sure our NMIs were run */
@ -890,8 +891,8 @@ AnalyseNmiData(_In_ PNMI_CONTEXT NmiContext, _In_ PSYSTEM_MODULES SystemModules,
PHIDDEN_SYSTEM_THREAD_REPORT report =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(HIDDEN_SYSTEM_THREAD_REPORT),
REPORT_POOL_TAG);
sizeof(HIDDEN_SYSTEM_THREAD_REPORT),
REPORT_POOL_TAG);
if (!report)
continue;
@ -1063,8 +1064,8 @@ HandleNmiIOCTL(_Inout_ PIRP Irp)
DEBUG_ERROR("ValidateHalDispatchTables failed with status %x", status);
nmi_context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpKeQueryActiveProcessorCount(0) * sizeof(NMI_CONTEXT),
NMI_CONTEXT_POOL);
ImpKeQueryActiveProcessorCount(0) * sizeof(NMI_CONTEXT),
NMI_CONTEXT_POOL);
if (!nmi_context)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -1321,13 +1322,13 @@ ValidateThreadViaKernelApcCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
return;
ImpKeInitializeApc(apc,
ThreadListEntry->thread,
OriginalApcEnvironment,
ApcKernelRoutine,
ApcRundownRoutine,
ApcNormalRoutine,
KernelMode,
Context);
ThreadListEntry->thread,
OriginalApcEnvironment,
ApcKernelRoutine,
ApcRundownRoutine,
ApcNormalRoutine,
KernelMode,
Context);
apc_status = ImpKeInsertQueueApc(apc, NULL, NULL, IO_NO_INCREMENT);
@ -1367,7 +1368,8 @@ ValidateThreadsViaKernelApc()
return STATUS_SUCCESS;
}
context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(APC_STACKWALK_CONTEXT), POOL_TAG_APC);
context =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(APC_STACKWALK_CONTEXT), POOL_TAG_APC);
if (!context)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -1433,9 +1435,9 @@ DpcStackwalkCallbackRoutine(_In_ PKDPC Dpc,
PDPC_CONTEXT context = &((PDPC_CONTEXT)DeferredContext)[KeGetCurrentProcessorNumber()];
context->frames_captured = ImpRtlCaptureStackBackTrace(DPC_STACKWALK_FRAMES_TO_SKIP,
DPC_STACKWALK_STACKFRAME_COUNT,
&context->stack_frame,
NULL);
DPC_STACKWALK_STACKFRAME_COUNT,
&context->stack_frame,
NULL);
InterlockedExchange(&context->executed, TRUE);
ImpKeSignalCallDpcDone(SystemArgument1);
@ -1483,8 +1485,8 @@ ValidateDpcCapturedStack(_In_ PSYSTEM_MODULES Modules, _In_ PDPC_CONTEXT Context
if (!flag)
{
report = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(DPC_STACKWALK_REPORT),
POOL_TAG_DPC);
sizeof(DPC_STACKWALK_REPORT),
POOL_TAG_DPC);
if (!report)
continue;
@ -1521,7 +1523,7 @@ DispatchStackwalkToEachCpuViaDpc()
context = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
ImpKeQueryActiveProcessorCount(0) * sizeof(DPC_CONTEXT),
POOL_TAG_DPC);
POOL_TAG_DPC);
if (!context)
return STATUS_MEMORY_NOT_ALLOCATED;

View file

@ -287,11 +287,9 @@ end:
ImpKeReleaseGuardedMutex(&report_queue_config.lock);
Irp->IoStatus.Information = sizeof(GLOBAL_REPORT_QUEUE_HEADER) + total_size;
header.count = count;
header.count = count;
RtlCopyMemory(report_buffer, &header, sizeof(GLOBAL_REPORT_QUEUE_HEADER));
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
report_buffer,
sizeof(GLOBAL_REPORT_QUEUE_HEADER) + total_size);

View file

@ -117,6 +117,5 @@ VOID
DetectThreadsAttachedToProtectedProcess()
{
PAGED_CODE();
EnumerateThreadListWithCallbackRoutine(DetectAttachedThreadsProcessCallback, NULL);
}

11
test/driver/common.hpp Normal file
View file

@ -0,0 +1,11 @@
#include <ntifs.h>
#define STATIC static
#define VOID void
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
typedef UINT16 uint16_t;
#define DEBUG_LOG(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)

3
test/driver/driver.hpp Normal file
View file

@ -0,0 +1,3 @@
#pragma once
#include "common.hpp"

View file

@ -0,0 +1,9 @@
#include "common.hpp"
namespace framework
{
class state
{
};
}

83
test/driver/main.cpp Normal file
View file

@ -0,0 +1,83 @@
#include "driver.hpp"
UNICODE_STRING DRIVER_NAME = RTL_CONSTANT_STRING(L"donna-ac-test");
UNICODE_STRING DRIVER_LINK = RTL_CONSTANT_STRING(L"donna-ac-test-link");
#define IOCTL_RUN_NMI_CALLBACKS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20001, METHOD_BUFFERED, FILE_ANY_ACCESS)
NTSTATUS
DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(Irp);
switch (stack_location->Parameters.DeviceIoControl.IoControlCode)
{
}
end:
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
STATIC
VOID
DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
{
IoDeleteDevice(DriverObject->DeviceObject);
}
extern "C"
NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
status = IoCreateDevice(DriverObject,
NULL,
&DRIVER_NAME,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DriverObject->DeviceObject);
if (!NT_SUCCESS(status))
{
return STATUS_FAILED_DRIVER_ENTRY;
}
status = IoCreateSymbolicLink(&DRIVER_LINK, &DRIVER_NAME);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

11
test/driver/patch.cpp Normal file
View file

@ -0,0 +1,11 @@
#include "patch.hpp"
namespace framework {
patch::patch(char* image_name)
{
}
patch::~patch()
{
}
}

17
test/driver/patch.hpp Normal file
View file

@ -0,0 +1,17 @@
#include "common.hpp"
namespace framework {
class patch
{
private:
char* image_name;
void* image_base;
void* patch_address;
void* original_bytes;
unsigned long patch_size;
public:
patch(char* image_name);
~patch();
};
}

View file

@ -127,6 +127,7 @@
</DriverSign>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - No Server|x64'">
@ -159,10 +160,14 @@
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="driver.c" />
<ClCompile Include="main.cpp" />
<ClCompile Include="patch.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="driver.h" />
<ClInclude Include="common.hpp" />
<ClInclude Include="driver.hpp" />
<ClInclude Include="framework.hpp" />
<ClInclude Include="patch.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -24,12 +24,24 @@
</Inf>
</ItemGroup>
<ItemGroup>
<ClCompile Include="driver.c">
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="patch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="driver.h">
<ClInclude Include="driver.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="framework.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="common.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="patch.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View file

@ -1,100 +0,0 @@
#include "driver.h"
UNICODE_STRING DRIVER_NAME = RTL_CONSTANT_STRING(L"donna-ac-test");
UNICODE_STRING DRIVER_LINK = RTL_CONSTANT_STRING(L"donna-ac-test-link");
#define IOCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20001, METHOD_BUFFERED, FILE_ANY_ACCESS)
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
_Inout_ PIRP Irp
)
{
UNREFERENCED_PARAMETER(DriverObject);
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(Irp);
switch (stack_location->Parameters.DeviceIoControl.IoControlCode)
{
}
end:
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
DeviceClose(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
)
{
UNREFERENCED_PARAMETER(DeviceObject);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
NTSTATUS
DeviceCreate(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
)
{
UNREFERENCED_PARAMETER(DeviceObject);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
STATIC
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
{
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
status = IoCreateDevice(
DriverObject,
NULL,
&DRIVER_NAME,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DriverObject->DeviceObject
);
if (!NT_SUCCESS(status))
{
return STATUS_FAILED_DRIVER_ENTRY;
}
status = IoCreateSymbolicLink(
&DRIVER_LINK,
&DRIVER_NAME
);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(DriverObject->DeviceObject);
return STATUS_FAILED_DRIVER_ENTRY;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

View file

@ -1,12 +0,0 @@
#ifndef DRIVER_H
#define DRIVER_H
#include <ntifs.h>
#define STATIC static
#define VOID void
#define DEBUG_LOG(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) ImpDbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)
#endif

View file

@ -205,10 +205,7 @@ kernelmode::Driver::QueryReportQueue()
REPORT_QUEUE_HEADER* header = (REPORT_QUEUE_HEADER*)buffer;
if (!header)
goto end;
if (header->count == 0)
if (!header || !header->count)
goto end;
for (INT index = 0; index < header->count; index++)
@ -554,7 +551,8 @@ kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
module_information.module_base = module_entry.modBaseAddr;
module_information.module_size = module_entry.modBaseSize;
status = (*pRtlDosPathNameToNtPathName_U)(module_entry.szExePath, &nt_path_name, NULL, NULL);
status = (*pRtlDosPathNameToNtPathName_U)(
module_entry.szExePath, &nt_path_name, NULL, NULL);
if (!status)
{
@ -655,6 +653,18 @@ kernelmode::Driver::InitiateApcOperation(INT OperationId)
}
}
VOID
kernelmode::Driver::SendIrpForDriverToStore()
{
BOOLEAN status = FALSE;
status = DeviceIoControl(
this->driver_handle, IOCTL_INSERT_IRP_INTO_QUEUE, NULL, NULL, NULL, NULL, NULL, NULL);
if (status == NULL)
LOG_ERROR("failed to insert irp into irp queue %x", GetLastError());
}
VOID
GetKernelStructureOffsets()
{

View file

@ -42,6 +42,8 @@
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)
#define IOCTL_INSERT_IRP_INTO_QUEUE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x20021, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define MAX_REPORTS_PER_IRP 20
@ -96,6 +98,7 @@ class Driver
VOID StackwalkThreadsViaDpc();
VOID ValidateSystemModules();
BOOLEAN InitiateApcOperation(INT OperationId);
VOID SendIrpForDriverToStore();
};
struct DRIVER_INITIATION_INFORMATION

View file

@ -103,4 +103,16 @@ VOID
kernelmode::KManager::ValidateSystemModules()
{
this->thread_pool->QueueJob([this]() { this->driver_interface->ValidateSystemModules(); });
}
VOID
kernelmode::KManager::InsertIrpIntoIrpQueue()
{
this->thread_pool->QueueJob([this]() { this->driver_interface->SendIrpForDriverToStore(); });
}
VOID
kernelmode::KManager::StartIoCompletionPortThread()
{
}

View file

@ -14,6 +14,8 @@ class KManager
std::unique_ptr<Driver> driver_interface;
std::shared_ptr<global::ThreadPool> thread_pool;
VOID StartIoCompletionPortThread();
public:
KManager(LPCWSTR DriverName,
std::shared_ptr<global::ThreadPool> ThreadPool,
@ -34,6 +36,7 @@ class KManager
VOID CheckForEptHooks();
VOID StackwalkThreadsViaDpc();
VOID ValidateSystemModules();
VOID InsertIrpIntoIrpQueue();
};
}

View file

@ -164,6 +164,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>