mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
eee
This commit is contained in:
parent
ef4127c167
commit
0d853853bf
13 changed files with 174 additions and 26 deletions
|
@ -7,6 +7,8 @@
|
|||
|
||||
PQUEUE_HEAD report_queue = NULL;
|
||||
|
||||
KGUARDED_MUTEX mutex;
|
||||
|
||||
VOID InitCallbackReportQueue( PBOOLEAN Status )
|
||||
{
|
||||
report_queue = QueueCreate();
|
||||
|
@ -14,6 +16,8 @@ VOID InitCallbackReportQueue( PBOOLEAN Status )
|
|||
if ( report_queue == NULL )
|
||||
*Status = FALSE;
|
||||
|
||||
KeInitializeGuardedMutex( &mutex );
|
||||
|
||||
*Status = TRUE;
|
||||
}
|
||||
|
||||
|
@ -22,16 +26,65 @@ VOID DeleteCallbackReportQueueHead()
|
|||
ExFreePoolWithTag( report_queue, QUEUE_POOL_TAG );
|
||||
}
|
||||
|
||||
VOID InsertReportToQueue( POPEN_HANDLE_FAILURE_REPORT Report )
|
||||
VOID InsertReportToQueue(
|
||||
_In_ POPEN_HANDLE_FAILURE_REPORT Report
|
||||
)
|
||||
{
|
||||
QueuePush( report_queue, Report );
|
||||
}
|
||||
|
||||
PVOID PopFirstReportFromQueue( report_queue )
|
||||
POPEN_HANDLE_FAILURE_REPORT PopFirstReportFromQueue()
|
||||
{
|
||||
return QueuePop( report_queue );
|
||||
}
|
||||
|
||||
NTSTATUS HandlePeriodicCallbackReportQueue(
|
||||
_In_ PIRP Irp
|
||||
)
|
||||
{
|
||||
PVOID report = NULL;
|
||||
INT count = 0;
|
||||
OPEN_HANDLE_FAILURE_REPORT_HEADER header;
|
||||
|
||||
KeAcquireGuardedMutex( &mutex );
|
||||
report = PopFirstReportFromQueue();
|
||||
|
||||
if ( report == NULL )
|
||||
{
|
||||
DEBUG_LOG( "callback report queue is empty, returning" );
|
||||
KeReleaseGuardedMutex( &mutex );
|
||||
Irp->IoStatus.Information = NULL;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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 )
|
||||
);
|
||||
|
||||
report = PopFirstReportFromQueue();
|
||||
count += 1;
|
||||
}
|
||||
|
||||
header.count = count;
|
||||
RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &header, sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER ));
|
||||
|
||||
DEBUG_LOG( "Moved all reports into the IRP, sending !" );
|
||||
|
||||
end:
|
||||
KeReleaseGuardedMutex( &mutex );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID ObPostOpCallbackRoutine(
|
||||
_In_ PVOID RegistrationContext,
|
||||
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
|
||||
|
@ -90,9 +143,25 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
|||
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = deny_access;
|
||||
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = deny_access;
|
||||
DEBUG_LOG( "handle stripped from: %s", process_creator_name );
|
||||
|
||||
POPEN_HANDLE_FAILURE_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( OPEN_HANDLE_FAILURE_REPORT ), REPORT_POOL_TAG );
|
||||
|
||||
if ( !report )
|
||||
goto end;
|
||||
|
||||
report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
|
||||
report->desired_access = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
|
||||
report->is_kernel_handle = OperationInformation->KernelHandle;
|
||||
report->process_id = process_creator_id;
|
||||
report->thread_id = PsGetCurrentThreadId();
|
||||
memcpy( report->process_name, process_creator_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH );
|
||||
|
||||
InsertReportToQueue( report );
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
return OB_PREOP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -133,6 +202,6 @@ VOID ProcessCreateNotifyRoutine(
|
|||
{
|
||||
parent_process_id = PsGetProcessId( target_process );
|
||||
UpdateProtectedProcessId( parent_process_id );
|
||||
LOG_INFO( "Protected process parent proc id: %lx", parent_process_id );
|
||||
DEBUG_LOG( "Protected process parent proc id: %lx", parent_process_id );
|
||||
}
|
||||
}
|
|
@ -5,6 +5,20 @@
|
|||
#include <wdftypes.h>
|
||||
#include <wdf.h>
|
||||
|
||||
#define REPORT_ILLEGAL_HANDLE_OPERATION 70
|
||||
|
||||
#define HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH 64
|
||||
|
||||
#define REPORT_POOL_TAG 'repo'
|
||||
|
||||
#define MAX_HANDLE_REPORTS_PER_IRP 10
|
||||
|
||||
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;
|
||||
|
@ -12,7 +26,7 @@ typedef struct _OPEN_HANDLE_FAILURE_REPORT
|
|||
LONG process_id;
|
||||
LONG thread_id;
|
||||
LONG desired_access;
|
||||
CHAR process_name[ 64 ];
|
||||
CHAR process_name[ HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH ];
|
||||
|
||||
}OPEN_HANDLE_FAILURE_REPORT, *POPEN_HANDLE_FAILURE_REPORT;
|
||||
|
||||
|
@ -44,4 +58,8 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
|||
VOID InitCallbackReportQueue(PBOOLEAN Status);
|
||||
VOID DeleteCallbackReportQueueHead();
|
||||
|
||||
NTSTATUS HandlePeriodicCallbackReportQueue(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,9 @@ LONG protected_process_id;
|
|||
LONG protected_process_parent_id;
|
||||
KGUARDED_MUTEX mutex;
|
||||
|
||||
UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" );
|
||||
UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" );
|
||||
|
||||
VOID UpdateProtectedProcessId(
|
||||
_In_ LONG NewProcessId
|
||||
)
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include <wdftypes.h>
|
||||
#include <wdf.h>
|
||||
|
||||
UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" );
|
||||
UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" );
|
||||
|
||||
VOID UpdateProtectedProcessId(
|
||||
_In_ LONG NewProcessId
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "nmi.h"
|
||||
#include "modules.h"
|
||||
#include "driver.h"
|
||||
#include "callbacks.h"
|
||||
|
||||
NTSTATUS DeviceControl(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
|
@ -95,6 +96,14 @@ NTSTATUS DeviceControl(
|
|||
UpdateProtectedProcessId( information->protected_process_id );
|
||||
break;
|
||||
|
||||
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
|
||||
|
||||
status = HandlePeriodicCallbackReportQueue(Irp);
|
||||
|
||||
if ( !NT_SUCCESS( status ) )
|
||||
DEBUG_ERROR( "Failed to handle period callback report queue" );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
||||
|
@ -102,7 +111,6 @@ NTSTATUS DeviceControl(
|
|||
}
|
||||
|
||||
end:
|
||||
DEBUG_LOG( "completing irp request" );
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
||||
return status;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2004, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _DRIVER_INITIATION_INFORMATION
|
||||
{
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "queue.h"
|
||||
|
||||
/*
|
||||
* Basic thread-safe queue implementation that can be used to create queues for any data.
|
||||
*/
|
||||
|
||||
PQUEUE_HEAD QueueCreate()
|
||||
{
|
||||
PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( PQUEUE_HEAD ), QUEUE_POOL_TAG );
|
||||
|
@ -9,6 +13,7 @@ PQUEUE_HEAD QueueCreate()
|
|||
|
||||
head->end = NULL;
|
||||
head->start = NULL;
|
||||
head->entries = 0;
|
||||
|
||||
KeInitializeSpinLock( head->lock );
|
||||
|
||||
|
@ -28,6 +33,8 @@ VOID QueuePush(
|
|||
if ( !temp )
|
||||
goto end;
|
||||
|
||||
Head->entries += 1;
|
||||
|
||||
temp->data = Data;
|
||||
temp->lock = Head->lock;
|
||||
|
||||
|
@ -56,6 +63,8 @@ PVOID QueuePop(
|
|||
if ( temp == NULL )
|
||||
goto end;
|
||||
|
||||
Head->entries -= 1;
|
||||
|
||||
data = temp->data;
|
||||
Head->start = temp->next;
|
||||
|
||||
|
|
|
@ -18,10 +18,11 @@ typedef struct QUEUE_HEAD
|
|||
struct _QUEUE_NODE* start;
|
||||
struct _QUEUE_NODE* end;
|
||||
PKSPIN_LOCK lock;
|
||||
INT entries;
|
||||
|
||||
}QUEUE_HEAD, *PQUEUE_HEAD;
|
||||
|
||||
PQUEUE_NODE QueueCreate();
|
||||
PQUEUE_HEAD QueueCreate();
|
||||
|
||||
VOID QueuePush(
|
||||
_In_ PQUEUE_HEAD Head,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
@ -59,5 +60,17 @@ namespace service
|
|||
public long DriverSize;
|
||||
public fixed char ModuleName[128];
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct OPEN_HANDLE_FAILURE_REPORT
|
||||
{
|
||||
public int ReportCode;
|
||||
public int IsKernelHandle;
|
||||
public long ProcessId;
|
||||
public long ThreadId;
|
||||
public long DesiredAccess;
|
||||
public fixed char ProcessName[64];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace service
|
|||
private const int REPORT_PATTERN_SCAN_FAILURE = 40;
|
||||
private const int REPORT_NMI_CALLBACK_FAILURE = 50;
|
||||
private const int REPORT_KERNEL_MODULE_FAILURE = 60;
|
||||
private const int REPORT_OPEN_HANDLE_FAILURE_REPORT = 70;
|
||||
|
||||
private const int MESSAGE_TYPE_REPORT = 1;
|
||||
private const int MESSAGE_TYPE_REQUEST = 2;
|
||||
|
@ -170,6 +171,18 @@ namespace service
|
|||
|
||||
goto end;
|
||||
|
||||
case REPORT_OPEN_HANDLE_FAILURE_REPORT:
|
||||
|
||||
var openHandleFailure = BytesToStructure<OPEN_HANDLE_FAILURE_REPORT>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, ProcessID: {1}, ThreadId: {2}, DesiredAccess{3}",
|
||||
openHandleFailure.ReportCode,
|
||||
openHandleFailure.ProcessId,
|
||||
openHandleFailure.ThreadId,
|
||||
openHandleFailure.DesiredAccess);
|
||||
|
||||
goto end;
|
||||
|
||||
default:
|
||||
_logger.LogError("Invalid report code received");
|
||||
goto end;
|
||||
|
|
|
@ -145,42 +145,48 @@ void kernelmode::Driver::VerifySystemModules()
|
|||
* modules.
|
||||
*/
|
||||
|
||||
bool kernelmode::Driver::QueueCallbackReportIrp(PHANDLE Event)
|
||||
void kernelmode::Driver::QueryReportQueue()
|
||||
{
|
||||
if ( !Event )
|
||||
return false;
|
||||
|
||||
OVERLAPPED io;
|
||||
BOOLEAN status;
|
||||
DWORD bytes_returned;
|
||||
PVOID buffer;
|
||||
LONG buffer_size;
|
||||
global::report_structures::OPEN_HANDLE_FAILURE_REPORT report;
|
||||
|
||||
io.hEvent = *Event;
|
||||
buffer_size = sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT ) * MAX_HANDLE_REPORTS_PER_IRP ;
|
||||
buffer = malloc( buffer_size );
|
||||
|
||||
status = DeviceIoControl(
|
||||
this->driver_handle,
|
||||
IOCTL_MONITOR_CALLBACKS_FOR_REPORTS,
|
||||
IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE,
|
||||
NULL,
|
||||
NULL,
|
||||
&report,
|
||||
sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT ),
|
||||
buffer,
|
||||
buffer_size,
|
||||
&bytes_returned,
|
||||
&io
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( status == NULL )
|
||||
{
|
||||
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
WaitForSingleObject( io.hEvent, INFINITE );
|
||||
global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER* header =
|
||||
( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER* )buffer;
|
||||
|
||||
/* we EXPECTED to receive bytes so this is an error */
|
||||
if ( bytes_returned == NULL )
|
||||
return false;
|
||||
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 ) );
|
||||
|
||||
this->report_interface->ReportViolation( report );
|
||||
}
|
||||
|
||||
free( buffer );
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_MONITOR_CALLBACKS_FOR_REPORTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2003, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2004, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define MAX_HANDLE_REPORTS_PER_IRP 10
|
||||
|
||||
namespace kernelmode
|
||||
{
|
||||
|
@ -24,7 +27,7 @@ namespace kernelmode
|
|||
|
||||
void RunNmiCallbacks();
|
||||
void VerifySystemModules();
|
||||
bool QueueCallbackReportIrp( PHANDLE Event );
|
||||
void QueryReportQueue();
|
||||
void NotifyDriverOnProcessLaunch();
|
||||
void CompleteQueuedCallbackReports();
|
||||
void EnableProcessLoadNotifyCallbacks();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define REPORT_PATTERN_SCAN_FAILURE 40
|
||||
#define REPORT_NMI_CALLBACK_FAILURE 50
|
||||
#define REPORT_MODULE_VALIDATION_FAILURE 60
|
||||
#define REPORT_ILLEGAL_HANDLE_OPERATION 70
|
||||
|
||||
|
||||
|
||||
|
@ -106,6 +107,12 @@ namespace global
|
|||
CHAR driver_name[ 128 ];
|
||||
};
|
||||
|
||||
struct OPEN_HANDLE_FAILURE_REPORT_HEADER
|
||||
{
|
||||
INT count;
|
||||
|
||||
};
|
||||
|
||||
struct OPEN_HANDLE_FAILURE_REPORT
|
||||
{
|
||||
INT report_code;
|
||||
|
|
Loading…
Reference in a new issue