mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
234 lines
No EOL
6 KiB
C
234 lines
No EOL
6 KiB
C
#include "callbacks.h"
|
|
|
|
#include "common.h"
|
|
#include "driver.h"
|
|
|
|
#include "queue.h"
|
|
|
|
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 );
|
|
|
|
if ( report == NULL )
|
|
goto end;
|
|
|
|
while ( report != NULL )
|
|
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 )
|
|
);
|
|
|
|
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,
|
|
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
|
|
)
|
|
{
|
|
|
|
}
|
|
|
|
OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
|
_In_ PVOID RegistrationContext,
|
|
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER( RegistrationContext );
|
|
|
|
/* 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
|
|
*/
|
|
PEPROCESS process_creator = PsGetCurrentProcess();
|
|
PEPROCESS target_process = ( PEPROCESS )OperationInformation->Object;
|
|
|
|
LONG target_process_id = PsGetProcessId( target_process );
|
|
LONG process_creator_id = PsGetProcessId( process_creator );
|
|
|
|
LONG protected_process_id;
|
|
LONG parent_process_id;
|
|
|
|
GetProtectedProcessId( &protected_process_id );
|
|
GetProtectedProcessParentId( &parent_process_id );
|
|
|
|
LPCSTR process_creator_name = PsGetProcessImageFileName( process_creator );
|
|
LPCSTR target_process_name = PsGetProcessImageFileName( target_process );
|
|
|
|
/*
|
|
* NOTE for whatever fukin reason this shit prevent notepad rfom launching need
|
|
* 2 fix lol
|
|
*/
|
|
|
|
if ( !strcmp( "notepad.exe", target_process_name) )
|
|
{
|
|
if ( !strcmp( process_creator_name, "lsass.exe" ) || !strcmp( process_creator_name, "csrss.exe" ) )
|
|
{
|
|
/* We will downgrade these handles later */
|
|
DEBUG_LOG( "Handles created by CSRSS and LSASS are allowed for now..." );
|
|
}
|
|
else if ( target_process == process_creator )
|
|
{
|
|
DEBUG_LOG( "handles made by NOTEPAD r okay :)" );
|
|
/* handles created by the game (notepad) are okay */
|
|
}
|
|
/* NOTE: try allowing only 1 handle from the proc creator */
|
|
else if ( parent_process_id == process_creator_id )
|
|
{
|
|
/* Allow handles created by the protected process' creator i.e explorer, cmd etc. */
|
|
DEBUG_LOG( "Process creator: %s handles are fine for now...", process_creator_name );
|
|
}
|
|
else
|
|
{
|
|
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;
|
|
}
|
|
|
|
VOID ProcessCreateNotifyRoutine(
|
|
_In_ HANDLE ParentId,
|
|
_In_ HANDLE ProcessId,
|
|
_In_ BOOLEAN Create
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PEPROCESS parent_process;
|
|
PEPROCESS target_process;
|
|
LONG parent_process_id;
|
|
LPCSTR target_process_name = NULL;
|
|
LPCSTR parent_process_name = NULL;
|
|
|
|
status = PsLookupProcessByProcessId( ParentId, &parent_process );
|
|
|
|
if ( !NT_SUCCESS( status ) )
|
|
return;
|
|
|
|
status = PsLookupProcessByProcessId( ProcessId, &target_process );
|
|
|
|
if ( !NT_SUCCESS( status ) )
|
|
return;
|
|
|
|
parent_process_name = PsGetProcessImageFileName( parent_process );
|
|
|
|
if ( !parent_process_name )
|
|
return;
|
|
|
|
target_process_name = PsGetProcessImageFileName( target_process );
|
|
|
|
if ( !target_process_name )
|
|
return;
|
|
|
|
if ( !strcmp( target_process_name, "notepad.exe") )
|
|
{
|
|
parent_process_id = PsGetProcessId( target_process );
|
|
UpdateProtectedProcessId( parent_process_id );
|
|
DEBUG_LOG( "Protected process parent proc id: %lx", parent_process_id );
|
|
}
|
|
} |