implemented global report irp queue

This commit is contained in:
lhodges1 2023-09-02 18:54:04 +10:00
parent 3d1e2c7235
commit 5e8eeb4bf0
13 changed files with 340 additions and 171 deletions

View file

@ -4,107 +4,9 @@
#include "queue.h"
#include "pool.h"
#include "thread.h"
CALLBACK_CONFIGURATION configuration;
QUEUE_HEAD head = { 0 };
/*
* This mutex is to prevent a new item being pushed to the queue
* while the HandlePeriodicCallbackReportQueue is iterating through
* the objects. This can be an issue because the spinlock is released
* after each report is placed in the IRP buffer which means a new report
* can be pushed into the queue before the next iteration can take ownership
* of the spinlock.
*/
KGUARDED_MUTEX mutex;
VOID InitCallbackReportQueue(
_In_ PBOOLEAN Status
)
{
head.start = NULL;
head.end = NULL;
head.entries = 0;
KeInitializeSpinLock( &head.lock );
KeInitializeGuardedMutex( &mutex );
*Status = TRUE;
}
VOID InsertReportToQueue(
_In_ POPEN_HANDLE_FAILURE_REPORT Report
)
{
KeAcquireGuardedMutex( &mutex );
QueuePush( &head, Report );
KeReleaseGuardedMutex( &mutex );
}
VOID FreeQueueObjectsAndCleanup()
{
KeAcquireGuardedMutex( &mutex );
PVOID report = QueuePop( &head );
while ( report != NULL )
{
ExFreePoolWithTag( report, REPORT_POOL_TAG );
report = QueuePop( &head );
}
end:
KeReleaseGuardedMutex( &mutex );
}
NTSTATUS HandlePeriodicCallbackReportQueue(
_In_ PIRP Irp
)
{
PVOID report = NULL;
INT count = 0;
OPEN_HANDLE_FAILURE_REPORT_HEADER header;
KeAcquireGuardedMutex( &mutex );
report = QueuePop( &head );
if ( report == NULL )
{
DEBUG_LOG( "callback report queue is empty, returning" );
Irp->IoStatus.Information = sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER );
goto end;
}
Irp->IoStatus.Information = sizeof( OPEN_HANDLE_FAILURE_REPORT ) * MAX_HANDLE_REPORTS_PER_IRP +
sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER );
while ( report != NULL )
{
if ( count >= MAX_HANDLE_REPORTS_PER_IRP )
goto end;
RtlCopyMemory(
( ( UINT64 )Irp->AssociatedIrp.SystemBuffer + sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER ) ) + count * sizeof( OPEN_HANDLE_FAILURE_REPORT ),
report,
sizeof( OPEN_HANDLE_FAILURE_REPORT )
);
/* QueuePop frees the node, but we still need to free the returned data */
ExFreePoolWithTag( report, REPORT_POOL_TAG );
report = QueuePop( &head );
count += 1;
}
end:
header.count = count;
RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &header, sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER ));
KeReleaseGuardedMutex( &mutex );
DEBUG_LOG( "Moved all reports into the IRP, sending !" );
return STATUS_SUCCESS;
}
VOID ObPostOpCallbackRoutine(
_In_ PVOID RegistrationContext,

View file

@ -10,18 +10,9 @@
#define HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH 64
#define REPORT_POOL_TAG 'repo'
#define MAX_HANDLE_REPORTS_PER_IRP 10
VOID UnregisterCallbacksOnProcessTermination();
typedef struct _OPEN_HANDLE_FAILURE_REPORT_HEADER
{
INT count;
}OPEN_HANDLE_FAILURE_REPORT_HEADER, *POPEN_HANDLE_FAILURE_REPORT_HEADER;
typedef struct _OPEN_HANDLE_FAILURE_REPORT
{
INT report_code;
@ -81,21 +72,11 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
);
VOID InitCallbackReportQueue(
_In_ PBOOLEAN Status
);
NTSTATUS HandlePeriodicCallbackReportQueue(
_In_ PIRP Irp
);
VOID ProcessCreateNotifyRoutine(
_In_ HANDLE ParentId,
_In_ HANDLE ProcessId,
_In_ BOOLEAN Create
);
VOID FreeQueueObjectsAndCleanup();
//VOID ProcessCreateNotifyRoutine(
// _In_ HANDLE ParentId,
// _In_ HANDLE ProcessId,
// _In_ BOOLEAN Create
//);
VOID EnumerateProcessListWithCallbackFunction(
_In_ PVOID Function

View file

@ -10,10 +10,15 @@
#include "modules.h"
#include "integrity.h"
#include "queue.h"
DRIVER_CONFIG driver_config = { 0 };
PROCESS_CONFIG process_config = { 0 };
UNICODE_STRING image_path = RTL_CONSTANT_STRING( L"ImagePath" );
UNICODE_STRING display_name = RTL_CONSTANT_STRING( L"DisplayName" );
VOID ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
)
@ -109,9 +114,6 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
BOOLEAN result;
RtlInitUnicodeString( &value_name, ValueName );
UNICODE_STRING image_path = RTL_CONSTANT_STRING( L"ImagePath" );
UNICODE_STRING display_name = RTL_CONSTANT_STRING( L"DisplayName" );
if ( RtlCompareUnicodeString(&value_name, &image_path, FALSE) == FALSE )
{
DEBUG_LOG( "Value type image path given" );
@ -120,7 +122,10 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
driver_config.driver_path.MaximumLength = ValueLength;
if ( !driver_config.driver_path.Buffer )
{
DEBUG_ERROR( "Failed to allocate buffer for unicode string driver path" );
return STATUS_ABANDONED;
}
RtlCopyMemory(
driver_config.driver_path.Buffer,
@ -131,13 +136,16 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
if ( RtlCompareUnicodeString( &value_name, &display_name, FALSE ) == FALSE )
{
DEBUG_LOG( "Value type image path given" );
DEBUG_LOG( "Value type display name given" );
driver_config.unicode_driver_name.Buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, ValueLength, DRIVER_PATH_POOL_TAG );
driver_config.unicode_driver_name.Length = ValueLength;
driver_config.unicode_driver_name.MaximumLength = ValueLength;
if ( !driver_config.unicode_driver_name.Buffer )
{
DEBUG_ERROR( "Failed to allocate buffer for unicode string driver name" );
return STATUS_ABANDONED;
}
RtlCopyMemory(
driver_config.unicode_driver_name.Buffer,
@ -166,7 +174,9 @@ NTSTATUS InitialiseDriverConfigOnDriverEntry(
)
{
NTSTATUS status;
RTL_QUERY_REGISTRY_TABLE query_table[ 2 ] = { 0 };
/* allocate 3 so the as to act as a null terminator */
RTL_QUERY_REGISTRY_TABLE query_table[ 3 ] = { 0 };
KeInitializeGuardedMutex( &driver_config.lock );
@ -200,6 +210,7 @@ NTSTATUS InitialiseDriverConfigOnDriverEntry(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "RtlxQueryRegistryValues failed with status %x", status );
FreeDriverConfigurationStringBuffers();
return status;
}
@ -221,7 +232,7 @@ NTSTATUS InitialiseDriverConfigOnDriverEntry(
}
NTSTATUS InitialiseDriverConfigOnProcessLaunch(
NTSTATUS InitialiseProcessConfigOnProcessLaunch(
_In_ PIRP Irp
)
{
@ -256,6 +267,7 @@ NTSTATUS InitialiseDriverConfigOnProcessLaunch(
VOID CleanupDriverConfigOnUnload()
{
FreeDriverConfigurationStringBuffers();
FreeGlobalReportQueueObjects();
IoDeleteSymbolicLink( &driver_config.device_symbolic_link );
}
@ -284,7 +296,14 @@ VOID TerminateProtectedProcessOnViolation()
status = ZwTerminateProcess( process_id, STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION );
if ( !NT_SUCCESS( status ) )
{
/*
* We don't want to clear the process config if ZwTerminateProcess fails
* so we can try again.
*/
DEBUG_ERROR( "ZwTerminateProcess failed with status %x", status );
return;
}
ClearProcessConfigOnProcessTermination();
}
@ -301,9 +320,13 @@ NTSTATUS DriverEntry(
status = InitialiseDriverConfigOnDriverEntry( RegistryPath );
KeInitializeGuardedMutex( &process_config.lock );
if ( !NT_SUCCESS( status ) )
return STATUS_ABANDONED;
{
DEBUG_ERROR( "InitialiseDriverConfigOnDriverEntry failed with status %x", status );
return status;
}
status = IoCreateDevice(
DriverObject,
@ -317,6 +340,7 @@ NTSTATUS DriverEntry(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "IoCreateDevice failed with status %x", status );
FreeDriverConfigurationStringBuffers();
return STATUS_FAILED_DRIVER_ENTRY;
}
@ -339,7 +363,7 @@ NTSTATUS DriverEntry(
DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = DeviceControl;
DriverObject->DriverUnload = DriverUnload;
InitCallbackReportQueue(&flag);
InitialiseGlobalReportQueue(&flag);
if ( !flag )
{
@ -352,19 +376,6 @@ NTSTATUS DriverEntry(
DEBUG_LOG( "DonnaAC Driver Entry Complete" );
//HANDLE handle;
//PsCreateSystemThread(
// &handle,
// PROCESS_ALL_ACCESS,
// NULL,
// NULL,
// NULL,
// VerifyInMemoryImageVsDiskImage,
// NULL
//);
//ZwClose( handle );
return STATUS_SUCCESS;
}

View file

@ -40,7 +40,7 @@ typedef struct _PROCESS_CONFIG
}PROCESS_CONFIG, *PPROCESS_CONFIG;
NTSTATUS InitialiseDriverConfigOnProcessLaunch(
NTSTATUS InitialiseProcessConfigOnProcessLaunch(
_In_ PIRP Irp
);

View file

@ -8,6 +8,7 @@
#include "pool.h"
#include "integrity.h"
#include "thread.h"
#include "queue.h"
#include "hv.h"
@ -106,7 +107,7 @@ NTSTATUS DeviceControl(
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH:;
status = InitialiseDriverConfigOnProcessLaunch(Irp);
status = InitialiseProcessConfigOnProcessLaunch(Irp);
if ( !NT_SUCCESS( status ) )
{
@ -123,7 +124,7 @@ NTSTATUS DeviceControl(
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
status = HandlePeriodicCallbackReportQueue(Irp);
status = HandlePeriodicGlobalReportQueueQuery(Irp);
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "Failed to handle period callback report queue" );
@ -252,7 +253,7 @@ NTSTATUS DeviceClose(
{
DEBUG_LOG( "Handle closed to DonnaAC" );
FreeQueueObjectsAndCleanup();
FreeGlobalReportQueueObjects();
ClearProcessConfigOnProcessTermination();
UnregisterCallbacksOnProcessTermination();

View file

@ -1,7 +1,52 @@
#include "queue.h"
#include "callbacks.h"
#include "driver.h"
#include "queue.h"
#include "pool.h"
#include "thread.h"
#include "common.h"
typedef struct _REPORT_HEADER
{
INT report_id;
}REPORT_HEADER, * PREPORT_HEADER;
/*
* This mutex is to prevent a new item being pushed to the queue
* while the HandlePeriodicCallbackReportQueue is iterating through
* the objects. This can be an issue because the spinlock is released
* after each report is placed in the IRP buffer which means a new report
* can be pushed into the queue before the next iteration can take ownership
* of the spinlock.
*/
typedef struct _REPORT_QUEUE_CONFIGURATION
{
QUEUE_HEAD head;
KGUARDED_MUTEX lock;
}REPORT_QUEUE_CONFIGURATION, *PREPORT_QUEUE_CONFIGURATION;
REPORT_QUEUE_CONFIGURATION report_queue_config = { 0 };
VOID InitialiseGlobalReportQueue(
_In_ PBOOLEAN Status
)
{
report_queue_config.head.start = NULL;
report_queue_config.head.end = NULL;
report_queue_config.head.entries = 0;
KeInitializeSpinLock( &report_queue_config.head.lock );
KeInitializeGuardedMutex( &report_queue_config.lock );
*Status = TRUE;
}
//PQUEUE_HEAD QueueCreate()
//{
// PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( QUEUE_HEAD ), QUEUE_POOL_TAG );
@ -74,3 +119,132 @@ end:
KeReleaseSpinLock( &Head->lock, irql );
return data;
}
VOID InsertReportToQueue(
_In_ PVOID Report
)
{
KeAcquireGuardedMutex( &report_queue_config.lock );
QueuePush( &report_queue_config.head, Report );
KeReleaseGuardedMutex( &report_queue_config.lock );
}
VOID FreeGlobalReportQueueObjects()
{
KeAcquireGuardedMutex( &report_queue_config.lock );
PVOID report = QueuePop( &report_queue_config.head );
while ( report != NULL )
{
ExFreePoolWithTag( report, REPORT_POOL_TAG );
report = QueuePop( &report_queue_config.head );
}
end:
KeReleaseGuardedMutex( &report_queue_config.lock );
}
/*
* This function handles sending all the pending reports in the global report
* queue to the usermode application. This function is called periodically by the
* usermode application. The reason I have implemented this is because as this application
* expanded, it became apparent that some of the driver functions will generate multiple
* reports as a result of a single usermode request and hence it makes dealing with
* reports generated from ObRegisterCallbacks for example much easier.
*/
NTSTATUS HandlePeriodicGlobalReportQueueQuery(
_In_ PIRP Irp
)
{
PVOID report = NULL;
INT count = 0;
GLOBAL_REPORT_QUEUE_HEADER header;
PVOID report_buffer = NULL;
PREPORT_HEADER report_header;
SIZE_T total_size = NULL;
KeAcquireGuardedMutex( &report_queue_config.lock );
report = QueuePop( &report_queue_config.head );
report_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, 1024 * 2, REPORT_QUEUE_TEMP_BUFFER_TAG );
if ( !report_buffer )
{
DEBUG_LOG( "Failed to allocate report buffer" );
KeReleaseGuardedMutex( &report_queue_config.lock );
return STATUS_MEMORY_NOT_ALLOCATED;
}
if ( report == NULL )
{
DEBUG_LOG( "callback report queue is empty, returning" );
goto end;
}
while ( report != NULL )
{
if ( count >= MAX_REPORTS_PER_IRP )
goto end;
report_header = ( PREPORT_HEADER )report;
switch ( report_header->report_id )
{
case REPORT_ILLEGAL_HANDLE_OPERATION:
RtlCopyMemory(
( UINT64 )report_buffer + sizeof( GLOBAL_REPORT_QUEUE_HEADER ) + total_size,
report,
sizeof( OPEN_HANDLE_FAILURE_REPORT )
);
total_size += sizeof( OPEN_HANDLE_FAILURE_REPORT );
break;
case REPORT_ILLEGAL_ATTACH_PROCESS:
RtlCopyMemory(
( UINT64 )report_buffer + sizeof( GLOBAL_REPORT_QUEUE_HEADER ) + total_size,
report,
sizeof( ATTACH_PROCESS_REPORT )
);
total_size += sizeof( ATTACH_PROCESS_REPORT );
break;
}
/* QueuePop frees the node, but we still need to free the returned data */
ExFreePoolWithTag( report, REPORT_POOL_TAG );
report = QueuePop( &report_queue_config.head );
count += 1;
}
end:
Irp->IoStatus.Information = sizeof( GLOBAL_REPORT_QUEUE_HEADER ) + total_size;
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
);
KeReleaseGuardedMutex( &report_queue_config.lock );
if ( report_buffer )
ExFreePoolWithTag( report_buffer, REPORT_QUEUE_TEMP_BUFFER_TAG );
DEBUG_LOG( "Moved all reports into the IRP, sending !" );
return STATUS_SUCCESS;
}

View file

@ -4,6 +4,11 @@
#include <ntifs.h>
#define QUEUE_POOL_TAG 'qqqq'
#define REPORT_QUEUE_TEMP_BUFFER_TAG 'temp'
#define REPORT_POOL_TAG 'repo'
#define MAX_REPORTS_PER_IRP 20
typedef struct _QUEUE_NODE
{
@ -21,6 +26,12 @@ typedef struct QUEUE_HEAD
}QUEUE_HEAD, *PQUEUE_HEAD;
typedef struct _GLOBAL_REPORT_QUEUE_HEADER
{
INT count;
}GLOBAL_REPORT_QUEUE_HEADER, * PGLOBAL_REPORT_QUEUE_HEADER;
VOID QueuePush(
_In_ PQUEUE_HEAD Head,
_In_ PVOID Data
@ -30,6 +41,18 @@ PVOID QueuePop(
_In_ PQUEUE_HEAD Head
);
VOID InitialiseGlobalReportQueue(
_In_ PBOOLEAN Status
);
VOID InsertReportToQueue(
_In_ PVOID Report
);
NTSTATUS HandlePeriodicGlobalReportQueueQuery(
_In_ PIRP Irp
);
VOID FreeGlobalReportQueueObjects();
#endif

View file

@ -11,7 +11,7 @@ BOOLEAN finished = FALSE;
UINT64 current_kpcrb_thread = NULL;
VOID ProcessEnumerationCallback(
VOID KPRCBThreadValidationProcessCallback(
_In_ PEPROCESS Process
)
{
@ -88,7 +88,7 @@ VOID ValidateKPCRBThreads(
current_kpcrb_thread = *( UINT64* )( kprcb + KPCRB_CURRENT_THREAD );
EnumerateProcessListWithCallbackFunction(
ProcessEnumerationCallback
KPRCBThreadValidationProcessCallback
);
if ( thread_found_in_kthreadlist == FALSE || thread_found_in_pspcidtable == FALSE )
@ -122,3 +122,49 @@ VOID ValidateKPCRBThreads(
}
}
VOID DetectAttachedThreadsProcessCallback(
_In_ PEPROCESS Process
)
{
NTSTATUS status;
PLIST_ENTRY thread_list_head;
PLIST_ENTRY thread_list_entry;
PETHREAD current_thread;
UINT32 thread_id;
if ( finished == TRUE )
return;
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
thread_list_entry = thread_list_head->Flink;
while ( thread_list_entry != thread_list_head )
{
current_thread = ( PETHREAD )( ( UINT64 )thread_list_entry - KTHREAD_THREADLIST_OFFSET );
thread_list_entry = thread_list_entry->Flink;
}
}
/*
* I did not reverse this myself and previously had no idea how you would go about
* detecting KiAttachProcess so credits to KANKOSHEV for the explanation:
*
* https://github.com/KANKOSHEV/Detect-KeAttachProcess/tree/main
* https://doxygen.reactos.org/d0/dc9/procobj_8c.html#adec6dc539d4a5c0ee7d0f48e24ef0933
*
* Then from here you can see that the _KAPC_STATE structure in the KTHREAD stores the
* APC state for the thread. The Process field in this structure is the offset referred to
* in KANKOSHEV's proof of concept. This the field that is updated by KiAttachProcess when
* calling KeStackAttachProcess.
*/
VOID DetectThreadsAttachedToProtectedProcess(
_In_ PIRP Irp
)
{
EnumerateProcessListWithCallbackFunction(
DetectAttachedThreadsProcessCallback
);
}

View file

@ -13,6 +13,8 @@
#define REPORT_HIDDEN_SYSTEM_THREAD 90
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
VOID ValidateKPCRBThreads(
_In_ PIRP Irp
);
@ -28,4 +30,10 @@ typedef struct _HIDDEN_SYSTEM_THREAD_REPORT
}HIDDEN_SYSTEM_THREAD_REPORT, *PHIDDEN_SYSTEM_THREAD_REPORT;
typedef struct _ATTACH_PROCESS_REPORT
{
INT report_code;
}ATTACH_PROCESS_REPORT, *PATTACH_PROCESS_REPORT;
#endif

View file

@ -23,6 +23,7 @@
#define REPORT_ILLEGAL_HANDLE_OPERATION 70
#define REPORT_INVALID_PROCESS_ALLOCATION 80
#define REPORT_HIDDEN_SYSTEM_THREAD 90
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
enum REPORT_CODES
{
@ -168,6 +169,12 @@ namespace global
LONG thread_id;
CHAR thread[ 4096 ];
};
struct ATTACH_PROCESS_REPORT
{
INT report_code;
};
}
}

View file

@ -155,17 +155,23 @@ VOID kernelmode::Driver::VerifySystemModules()
* modules.
*/
struct REPORT_ID
{
INT report_id;
};
VOID kernelmode::Driver::QueryReportQueue()
{
BOOLEAN status;
DWORD bytes_returned;
PVOID buffer;
LONG buffer_size;
global::report_structures::OPEN_HANDLE_FAILURE_REPORT report;
buffer_size = sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT ) * MAX_HANDLE_REPORTS_PER_IRP +
sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER );
REPORT_ID* report_header;
SIZE_T total_size = NULL;
global::report_structures::OPEN_HANDLE_FAILURE_REPORT* handle_report;
global::report_structures::ATTACH_PROCESS_REPORT* attach_report;
buffer_size = 1024 * 2;
buffer = malloc( buffer_size );
status = DeviceIoControl(
@ -195,14 +201,34 @@ VOID kernelmode::Driver::QueryReportQueue()
if ( header->count == 0 )
goto end;
LOG_INFO( "report count: %i", header->count );
for ( int i = 0; i < header->count; i++ )
{
global::report_structures::OPEN_HANDLE_FAILURE_REPORT* report =
( global::report_structures::OPEN_HANDLE_FAILURE_REPORT* )(
( UINT64 )buffer + sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) +
i * sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT ) );
report_header = (REPORT_ID*)( ( UINT64 )buffer + sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) + total_size );
this->report_interface->ReportViolation( report );
LOG_INFO( "REport id: %i", report_header->report_id );
switch ( report_header->report_id )
{
case REPORT_ILLEGAL_ATTACH_PROCESS:
attach_report = (global::report_structures::ATTACH_PROCESS_REPORT*)(
( UINT64 )buffer + sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) + total_size );
this->report_interface->ReportViolation( attach_report );
total_size += sizeof( global::report_structures::ATTACH_PROCESS_REPORT );
case REPORT_ILLEGAL_HANDLE_OPERATION:
handle_report = ( global::report_structures::OPEN_HANDLE_FAILURE_REPORT* )(
( UINT64 )buffer + sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) + total_size );
this->report_interface->ReportViolation( handle_report );
total_size += sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT );
}
}
end:

View file

@ -19,7 +19,7 @@
#define IOCTL_VALIDATE_KPRCB_CURRENT_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2012, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define MAX_HANDLE_REPORTS_PER_IRP 10
#define MAX_REPORTS_PER_IRP 20
namespace kernelmode
{

View file

@ -31,16 +31,6 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
while ( !GetAsyncKeyState( VK_DELETE ) )
{
kmanager.MonitorCallbackReports();
kmanager.RunNmiCallbacks();
kmanager.VerifySystemModules();
kmanager.RequestModuleExecutableRegionsForIntegrityCheck();
kmanager.DetectSystemVirtualization();
kmanager.ScanPoolsForUnlinkedProcesses();
kmanager.EnumerateHandleTables();
umanager.ValidateProcessModules();
umanager.ValidateProcessMemory();
umanager.ValidateProcessThreads();
std::this_thread::sleep_for( std::chrono::milliseconds( 10000 ) );
}