mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
c:
This commit is contained in:
parent
1a61c9f6f1
commit
142ced5845
5 changed files with 95 additions and 65 deletions
|
@ -354,9 +354,13 @@ NTSTATUS EnumerateProcessHandles(
|
|||
* cheat which is mass deployed and needs to ensure that it won't crash the system.
|
||||
* Since we have no access to the process structure locks it is definitely not
|
||||
* mass deployment safe lol.
|
||||
*
|
||||
* The Context argument is simply a pointer to a user designed context structure
|
||||
* which is passed to the callback function.
|
||||
*/
|
||||
VOID EnumerateProcessListWithCallbackFunction(
|
||||
_In_ PVOID Function
|
||||
_In_ PVOID Function,
|
||||
_In_ PVOID Context
|
||||
)
|
||||
{
|
||||
UINT64 current_process;
|
||||
|
@ -377,8 +381,8 @@ VOID EnumerateProcessListWithCallbackFunction(
|
|||
if ( !current_process )
|
||||
return;
|
||||
|
||||
VOID( *callback_function_ptr )( PEPROCESS ) = Function;
|
||||
( *callback_function_ptr )( current_process );
|
||||
VOID( *callback_function_ptr )( PEPROCESS, PVOID ) = Function;
|
||||
( *callback_function_ptr )( current_process, Context );
|
||||
|
||||
process_list_entry = process_list_entry->Flink;
|
||||
|
||||
|
|
|
@ -74,7 +74,8 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
|||
//);
|
||||
|
||||
VOID EnumerateProcessListWithCallbackFunction(
|
||||
_In_ PVOID Function
|
||||
_In_ PVOID Function,
|
||||
_In_ PVOID Context
|
||||
);
|
||||
|
||||
NTSTATUS EnumerateProcessHandles(
|
||||
|
|
|
@ -144,7 +144,8 @@ NTSTATUS DeviceControl(
|
|||
|
||||
/* can maybe implement this better so we can extract a status value */
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
EnumerateProcessHandles
|
||||
EnumerateProcessHandles,
|
||||
NULL
|
||||
);
|
||||
|
||||
break;
|
||||
|
|
|
@ -30,8 +30,12 @@ CHAR EXECUTIVE_OBJECT_POOL_TAGS[ EXECUTIVE_OBJECT_COUNT ][ POOL_TAG_LENGTH ] =
|
|||
"\x4C\x69\x6E\x6B" /* Symbolic links */
|
||||
};
|
||||
|
||||
PVOID process_buffer = NULL;
|
||||
ULONG process_count = NULL;
|
||||
typedef struct _PROCESS_SCAN_CONTEXT
|
||||
{
|
||||
PVOID process_buffer;
|
||||
ULONG process_count;
|
||||
|
||||
}PROCESS_SCAN_CONTEXT, *PPROCESS_SCAN_CONTEXT;
|
||||
|
||||
PKDDEBUGGER_DATA64 GetGlobalDebuggerData()
|
||||
{
|
||||
|
@ -60,7 +64,8 @@ PKDDEBUGGER_DATA64 GetGlobalDebuggerData()
|
|||
dump_header
|
||||
);
|
||||
|
||||
debugger_data = ( PKDDEBUGGER_DATA64 )ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( KDDEBUGGER_DATA64 ), POOL_DEBUGGER_DATA_TAG );
|
||||
debugger_data =
|
||||
( PKDDEBUGGER_DATA64 )ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( KDDEBUGGER_DATA64 ), POOL_DEBUGGER_DATA_TAG );
|
||||
|
||||
if ( !debugger_data )
|
||||
goto end;
|
||||
|
@ -130,7 +135,7 @@ VOID ScanPageForKernelObjectAllocation(
|
|||
_In_ UINT64 PageBase,
|
||||
_In_ ULONG PageSize,
|
||||
_In_ ULONG ObjectIndex,
|
||||
_In_ PVOID AddressBuffer
|
||||
_In_ PPROCESS_SCAN_CONTEXT Context
|
||||
)
|
||||
{
|
||||
INT length = 0;
|
||||
|
@ -189,12 +194,12 @@ VOID ScanPageForKernelObjectAllocation(
|
|||
break;
|
||||
}
|
||||
|
||||
address_list = ( PUINT64 )AddressBuffer;
|
||||
address_list = ( PUINT64 )Context->process_buffer;
|
||||
|
||||
/*
|
||||
* Find the first free entry in the process address list and store the address.
|
||||
*/
|
||||
for ( INT i = 0; i < process_count; i++ )
|
||||
for ( INT i = 0; i < Context->process_count; i++ )
|
||||
{
|
||||
if ( address_list[ i ] == NULL )
|
||||
{
|
||||
|
@ -216,8 +221,8 @@ VOID ScanPageForKernelObjectAllocation(
|
|||
VOID EnumerateKernelLargePages(
|
||||
_In_ UINT64 PageBase,
|
||||
_In_ ULONG PageSize,
|
||||
_In_ PVOID AddressBuffer,
|
||||
_In_ ULONG ObjectIndex
|
||||
_In_ ULONG ObjectIndex,
|
||||
_In_ PPROCESS_SCAN_CONTEXT Context
|
||||
)
|
||||
{
|
||||
for ( INT page_index = 0; page_index < PageSize; page_index++ )
|
||||
|
@ -226,7 +231,7 @@ VOID EnumerateKernelLargePages(
|
|||
PageBase + ( page_index * PageSize ),
|
||||
PAGE_SIZE,
|
||||
ObjectIndex,
|
||||
AddressBuffer
|
||||
Context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +289,9 @@ BOOLEAN IsPhysicalAddressInPhysicalMemoryRange(
|
|||
* and extract the physical address from the value at each virtual address page entry.
|
||||
*/
|
||||
|
||||
VOID WalkKernelPageTables(PVOID AddressBuffer)
|
||||
VOID WalkKernelPageTables(
|
||||
_In_ PPROCESS_SCAN_CONTEXT Context
|
||||
)
|
||||
{
|
||||
CR3 cr3;
|
||||
PML4E pml4_base;
|
||||
|
@ -366,8 +373,8 @@ VOID WalkKernelPageTables(PVOID AddressBuffer)
|
|||
EnumerateKernelLargePages(
|
||||
base_1gb_virtual_page,
|
||||
LARGE_PAGE_1GB_ENTRIES,
|
||||
AddressBuffer,
|
||||
INDEX_PROCESS_POOL_TAG
|
||||
INDEX_PROCESS_POOL_TAG,
|
||||
Context
|
||||
);
|
||||
|
||||
continue;
|
||||
|
@ -408,8 +415,8 @@ VOID WalkKernelPageTables(PVOID AddressBuffer)
|
|||
EnumerateKernelLargePages(
|
||||
base_2mb_virtual_page,
|
||||
LARGE_PAGE_2MB_ENTRIES,
|
||||
AddressBuffer,
|
||||
INDEX_PROCESS_POOL_TAG
|
||||
INDEX_PROCESS_POOL_TAG,
|
||||
Context
|
||||
);
|
||||
|
||||
continue;
|
||||
|
@ -451,7 +458,7 @@ VOID WalkKernelPageTables(PVOID AddressBuffer)
|
|||
base_virtual_page,
|
||||
PAGE_BASE_SIZE,
|
||||
INDEX_PROCESS_POOL_TAG,
|
||||
AddressBuffer
|
||||
Context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -461,25 +468,31 @@ VOID WalkKernelPageTables(PVOID AddressBuffer)
|
|||
DEBUG_LOG( "Finished scanning memory" );
|
||||
}
|
||||
|
||||
VOID IncrementProcessCounter()
|
||||
VOID IncrementProcessCounter(
|
||||
_In_ PEPROCESS Process,
|
||||
_In_ PVOID Context
|
||||
)
|
||||
{
|
||||
process_count++;
|
||||
PPROCESS_SCAN_CONTEXT context = ( PPROCESS_SCAN_CONTEXT )Context;
|
||||
context->process_count += 1;
|
||||
}
|
||||
|
||||
VOID CheckIfProcessAllocationIsInProcessList(
|
||||
_In_ PEPROCESS Process
|
||||
_In_ PEPROCESS Process,
|
||||
_In_ PVOID Context
|
||||
)
|
||||
{
|
||||
PUINT64 allocation_address;
|
||||
PPROCESS_SCAN_CONTEXT context = ( PPROCESS_SCAN_CONTEXT )Context;
|
||||
|
||||
for ( INT i = 0; i < process_count; i++ )
|
||||
for ( INT i = 0; i < context->process_count; i++ )
|
||||
{
|
||||
allocation_address = ( PUINT64 )process_buffer;
|
||||
allocation_address = ( PUINT64 )context->process_buffer;
|
||||
|
||||
if ( ( UINT64 )Process >= allocation_address[ i ] - PROCESS_OBJECT_ALLOCATION_MARGIN &&
|
||||
( UINT64 )Process <= allocation_address[ i ] + PROCESS_OBJECT_ALLOCATION_MARGIN )
|
||||
{
|
||||
RtlZeroMemory( ( UINT64 )process_buffer + i * sizeof( UINT64 ), sizeof( UINT64 ) );
|
||||
RtlZeroMemory( ( UINT64 )context->process_buffer + i * sizeof( UINT64 ), sizeof( UINT64 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,31 +514,35 @@ NTSTATUS FindUnlinkedProcesses(
|
|||
{
|
||||
PUINT64 allocation_address;
|
||||
PINVALID_PROCESS_ALLOCATION_REPORT report_buffer = NULL;
|
||||
PROCESS_SCAN_CONTEXT context = { 0 };
|
||||
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
IncrementProcessCounter
|
||||
IncrementProcessCounter,
|
||||
&context
|
||||
);
|
||||
|
||||
if ( process_count == NULL )
|
||||
if ( context.process_count == NULL )
|
||||
{
|
||||
DEBUG_ERROR( "Faield to get process count " );
|
||||
return STATUS_ABANDONED;
|
||||
}
|
||||
|
||||
process_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, process_count * 2 * sizeof( UINT64 ), PROCESS_ADDRESS_LIST_TAG );
|
||||
context.process_buffer =
|
||||
ExAllocatePool2( POOL_FLAG_NON_PAGED, context.process_count * 2 * sizeof( UINT64 ), PROCESS_ADDRESS_LIST_TAG );
|
||||
|
||||
if ( !process_buffer )
|
||||
if ( !context.process_buffer )
|
||||
return STATUS_ABANDONED;
|
||||
|
||||
WalkKernelPageTables( process_buffer );
|
||||
WalkKernelPageTables( &context );
|
||||
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
CheckIfProcessAllocationIsInProcessList
|
||||
CheckIfProcessAllocationIsInProcessList,
|
||||
&context
|
||||
);
|
||||
|
||||
allocation_address = ( PUINT64 )process_buffer;
|
||||
allocation_address = ( PUINT64 )context.process_buffer;
|
||||
|
||||
for ( INT i = 0; i < process_count; i++ )
|
||||
for ( INT i = 0; i < context.process_count; i++ )
|
||||
{
|
||||
if ( allocation_address[ i ] == NULL )
|
||||
continue;
|
||||
|
@ -537,7 +554,8 @@ NTSTATUS FindUnlinkedProcesses(
|
|||
/* report / do some further analysis */
|
||||
DEBUG_ERROR( "INVALID POOL proc OMGGG" );
|
||||
|
||||
report_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( INVALID_PROCESS_ALLOCATION_REPORT ), INVALID_PROCESS_REPORT_TAG );
|
||||
report_buffer =
|
||||
ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( INVALID_PROCESS_ALLOCATION_REPORT ), INVALID_PROCESS_REPORT_TAG );
|
||||
|
||||
if ( !report_buffer )
|
||||
goto end;
|
||||
|
@ -562,11 +580,8 @@ end:
|
|||
if (report_buffer )
|
||||
ExFreePoolWithTag( report_buffer, INVALID_PROCESS_REPORT_TAG );
|
||||
|
||||
if (process_buffer )
|
||||
ExFreePoolWithTag( process_buffer, PROCESS_ADDRESS_LIST_TAG );
|
||||
|
||||
process_count = NULL;
|
||||
process_buffer = NULL;
|
||||
if (context.process_buffer )
|
||||
ExFreePoolWithTag( context.process_buffer, PROCESS_ADDRESS_LIST_TAG );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -7,14 +7,18 @@
|
|||
|
||||
#include <intrin.h>
|
||||
|
||||
UINT8 thread_found_in_pspcidtable = FALSE;
|
||||
UINT8 thread_found_in_kthreadlist = FALSE;
|
||||
BOOLEAN finished = FALSE;
|
||||
typedef struct _KPRCB_THREAD_VALIDATION_CTX
|
||||
{
|
||||
UINT64 current_kpcrb_thread;
|
||||
UINT8 thread_found_in_pspcidtable;
|
||||
UINT8 thread_found_in_kthreadlist;
|
||||
BOOLEAN finished;
|
||||
|
||||
UINT64 current_kpcrb_thread = NULL;
|
||||
}KPRCB_THREAD_VALIDATION_CTX, *PKPRCB_THREAD_VALIDATION_CTX;
|
||||
|
||||
VOID KPRCBThreadValidationProcessCallback(
|
||||
_In_ PEPROCESS Process
|
||||
_In_ PEPROCESS Process,
|
||||
_In_ PVOID Context
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
@ -22,8 +26,9 @@ VOID KPRCBThreadValidationProcessCallback(
|
|||
PLIST_ENTRY thread_list_entry;
|
||||
PETHREAD current_thread;
|
||||
UINT32 thread_id;
|
||||
PKPRCB_THREAD_VALIDATION_CTX context = ( PKPRCB_THREAD_VALIDATION_CTX )Context;
|
||||
|
||||
if ( finished == TRUE )
|
||||
if ( context->finished == TRUE )
|
||||
return;
|
||||
|
||||
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
|
||||
|
@ -33,16 +38,16 @@ VOID KPRCBThreadValidationProcessCallback(
|
|||
{
|
||||
current_thread = ( PETHREAD )( ( UINT64 )thread_list_entry - KTHREAD_THREADLIST_OFFSET );
|
||||
|
||||
if ( current_thread == current_kpcrb_thread )
|
||||
if ( current_thread == context->current_kpcrb_thread )
|
||||
{
|
||||
thread_found_in_kthreadlist = TRUE;
|
||||
context->thread_found_in_kthreadlist = TRUE;
|
||||
|
||||
thread_id = PsGetThreadId( current_thread );
|
||||
|
||||
if ( thread_id != NULL )
|
||||
{
|
||||
thread_found_in_pspcidtable = TRUE;
|
||||
finished = TRUE;
|
||||
context->thread_found_in_pspcidtable = TRUE;
|
||||
context->finished = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,6 +85,7 @@ VOID ValidateKPCRBThreads(
|
|||
UINT64 kpcr;
|
||||
UINT64 kprcb;
|
||||
KAFFINITY old_affinity = { 0 };
|
||||
KPRCB_THREAD_VALIDATION_CTX context = { 0 };
|
||||
|
||||
for ( LONG processor_index = 0; processor_index < KeQueryActiveProcessorCount( 0 ); processor_index++ )
|
||||
{
|
||||
|
@ -87,26 +93,30 @@ VOID ValidateKPCRBThreads(
|
|||
|
||||
kpcr = __readmsr( IA32_GS_BASE );
|
||||
kprcb = kpcr + KPRCB_OFFSET_FROM_GS_BASE;
|
||||
current_kpcrb_thread = *( UINT64* )( kprcb + KPCRB_CURRENT_THREAD );
|
||||
context.current_kpcrb_thread = *( UINT64* )( kprcb + KPCRB_CURRENT_THREAD );
|
||||
|
||||
if (!context.current_kpcrb_thread )
|
||||
continue;
|
||||
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
KPRCBThreadValidationProcessCallback
|
||||
KPRCBThreadValidationProcessCallback,
|
||||
&context
|
||||
);
|
||||
|
||||
if ( thread_found_in_kthreadlist == FALSE || thread_found_in_pspcidtable == FALSE )
|
||||
if ( context.current_kpcrb_thread == FALSE || context.thread_found_in_pspcidtable == FALSE )
|
||||
{
|
||||
Irp->IoStatus.Information = sizeof( HIDDEN_SYSTEM_THREAD_REPORT );
|
||||
|
||||
HIDDEN_SYSTEM_THREAD_REPORT report;
|
||||
report.report_code = REPORT_HIDDEN_SYSTEM_THREAD;
|
||||
report.found_in_kthreadlist = thread_found_in_kthreadlist;
|
||||
report.found_in_pspcidtable = thread_found_in_pspcidtable;
|
||||
report.thread_id = PsGetThreadId( current_kpcrb_thread );
|
||||
report.thread_address = current_kpcrb_thread;
|
||||
report.found_in_kthreadlist = context.thread_found_in_kthreadlist;
|
||||
report.found_in_pspcidtable = context.thread_found_in_pspcidtable;
|
||||
report.thread_id = PsGetThreadId( context.current_kpcrb_thread );
|
||||
report.thread_address = context.current_kpcrb_thread;
|
||||
|
||||
RtlCopyMemory(
|
||||
report.thread,
|
||||
current_kpcrb_thread,
|
||||
context.current_kpcrb_thread,
|
||||
sizeof( report.thread ));
|
||||
|
||||
RtlCopyMemory(
|
||||
|
@ -115,19 +125,17 @@ VOID ValidateKPCRBThreads(
|
|||
sizeof( HIDDEN_SYSTEM_THREAD_REPORT ) );
|
||||
}
|
||||
|
||||
current_kpcrb_thread = NULL;
|
||||
thread_found_in_pspcidtable = FALSE;
|
||||
thread_found_in_kthreadlist = FALSE;
|
||||
finished = FALSE;
|
||||
|
||||
KeRevertToUserAffinityThreadEx( old_affinity );
|
||||
}
|
||||
}
|
||||
|
||||
VOID DetectAttachedThreadsProcessCallback(
|
||||
_In_ PEPROCESS Process
|
||||
_In_ PEPROCESS Process,
|
||||
_In_ PVOID Context
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMTER( Context );
|
||||
|
||||
NTSTATUS status;
|
||||
PLIST_ENTRY thread_list_head;
|
||||
PLIST_ENTRY thread_list_entry;
|
||||
|
@ -186,7 +194,8 @@ VOID DetectAttachedThreadsProcessCallback(
|
|||
VOID DetectThreadsAttachedToProtectedProcess()
|
||||
{
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
DetectAttachedThreadsProcessCallback
|
||||
DetectAttachedThreadsProcessCallback,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in a new issue