From c6b1f03db0bef333813db06d40a502ab9918c508 Mon Sep 17 00:00:00 2001 From: donnaskiez Date: Sun, 5 May 2024 20:42:22 +1000 Subject: [PATCH] fix apc bug --- .clang-format | 129 +------------ .clang-format-c | 127 +++++++++++++ .clang-format-cpp | 4 - driver/apc.c | 14 +- driver/callbacks.c | 57 +++--- driver/common.h | 6 +- driver/integrity.c | 38 +++- driver/io.c | 6 +- driver/modules.c | 55 ++++-- driver/pool.c | 22 +-- driver/thread.c | 5 +- driver/types/types.h | 207 ++++++++++++--------- module/helper.cpp | 34 ++-- module/kernel_interface/kernel_interface.h | 57 +++--- module/module.cpp | 39 ++-- 15 files changed, 442 insertions(+), 358 deletions(-) create mode 100644 .clang-format-c delete mode 100644 .clang-format-cpp diff --git a/.clang-format b/.clang-format index f33dc92..55f2377 100644 --- a/.clang-format +++ b/.clang-format @@ -1,127 +1,4 @@ -BasedOnStyle: webkit -AccessModifierOffset: -4 +--- +BasedOnStyle: LLVM -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true - -AlignConsecutiveMacros: true - -AlignEscapedNewlines: Left -AlignOperands: true - -AlignTrailingComments: true - -AllowAllArgumentsOnNextLine: true - -AllowShortBlocksOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: true -AllowShortFunctionsOnASingleLine: false -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: TopLevel -AlwaysBreakBeforeMultilineStrings: false - -AlwaysBreakTemplateDeclarations: true #false - -BinPackArguments: false -BinPackParameters: false - -AllowAllParametersOfDeclarationOnNextLine: true - -BreakBeforeBraces: Stroustrup -BraceWrapping: - AfterCaseLabel: true - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: false - AfterStruct: true - AfterUnion: true - AfterExternBlock: false - BeforeCatch: true - BeforeElse: true - -BreakBeforeBinaryOperators: None -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: AfterColon -BreakStringLiterals: false - -ColumnLimit: 80 -CommentPragmas: '^begin_wpp|^end_wpp|^FUNC |^USESUFFIX |^USESUFFIX ' - -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true - -DerivePointerAlignment: false -ExperimentalAutoDetectBinPacking: false - -IndentCaseLabels: false -IndentPPDirectives: AfterHash -IndentWidth: 4 - -KeepEmptyLinesAtTheStartOfBlocks: false -Language: Cpp - -MacroBlockBegin: '^BEGIN_MODULE$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$' -MacroBlockEnd: '^END_MODULE$|^END_TEST_CLASS$|^END_TEST_METHOD$' - -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None #All -PointerAlignment: Left -ReflowComments: true -SortIncludes: false - -SpaceAfterCStyleCast: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeCtorInitializerColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyParentheses: false -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false - -Standard: Cpp11 -StatementMacros: [ - 'EXTERN_C', - 'PAGED', - 'PAGEDX', - 'NONPAGED', - 'PNPCODE', - 'INITCODE', - '_At_', - '_When_', - '_Success_', - '_Check_return_', - '_Must_inspect_result_', - '_IRQL_requires_same_', - '_IRQL_requires_', - '_IRQL_requires_max_', - '_IRQL_requires_min_', - '_IRQL_saves_', - '_IRQL_restores_', - '_IRQL_saves_global_', - '_IRQL_restores_global_', - '_IRQL_raises_', - '_IRQL_lowers_', - '_Acquires_lock_', - '_Releases_lock_', - '_Acquires_exclusive_lock_', - '_Releases_exclusive_lock_', - '_Acquires_shared_lock_', - '_Releases_shared_lock_', - '_Requires_lock_held_', - '_Use_decl_annotations_', - '_Guarded_by_', - '__drv_preferredFunction', - '__drv_allocatesMem', - '__drv_freesMem', - ] - -TabWidth: '4' -UseTab: Never \ No newline at end of file +... diff --git a/.clang-format-c b/.clang-format-c new file mode 100644 index 0000000..f33dc92 --- /dev/null +++ b/.clang-format-c @@ -0,0 +1,127 @@ +BasedOnStyle: webkit +AccessModifierOffset: -4 + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true + +AlignConsecutiveMacros: true + +AlignEscapedNewlines: Left +AlignOperands: true + +AlignTrailingComments: true + +AllowAllArgumentsOnNextLine: true + +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: TopLevel +AlwaysBreakBeforeMultilineStrings: false + +AlwaysBreakTemplateDeclarations: true #false + +BinPackArguments: false +BinPackParameters: false + +AllowAllParametersOfDeclarationOnNextLine: true + +BreakBeforeBraces: Stroustrup +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +BreakStringLiterals: false + +ColumnLimit: 80 +CommentPragmas: '^begin_wpp|^end_wpp|^FUNC |^USESUFFIX |^USESUFFIX ' + +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true + +DerivePointerAlignment: false +ExperimentalAutoDetectBinPacking: false + +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 + +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp + +MacroBlockBegin: '^BEGIN_MODULE$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$' +MacroBlockEnd: '^END_MODULE$|^END_TEST_CLASS$|^END_TEST_METHOD$' + +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None #All +PointerAlignment: Left +ReflowComments: true +SortIncludes: false + +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false + +Standard: Cpp11 +StatementMacros: [ + 'EXTERN_C', + 'PAGED', + 'PAGEDX', + 'NONPAGED', + 'PNPCODE', + 'INITCODE', + '_At_', + '_When_', + '_Success_', + '_Check_return_', + '_Must_inspect_result_', + '_IRQL_requires_same_', + '_IRQL_requires_', + '_IRQL_requires_max_', + '_IRQL_requires_min_', + '_IRQL_saves_', + '_IRQL_restores_', + '_IRQL_saves_global_', + '_IRQL_restores_global_', + '_IRQL_raises_', + '_IRQL_lowers_', + '_Acquires_lock_', + '_Releases_lock_', + '_Acquires_exclusive_lock_', + '_Releases_exclusive_lock_', + '_Acquires_shared_lock_', + '_Releases_shared_lock_', + '_Requires_lock_held_', + '_Use_decl_annotations_', + '_Guarded_by_', + '__drv_preferredFunction', + '__drv_allocatesMem', + '__drv_freesMem', + ] + +TabWidth: '4' +UseTab: Never \ No newline at end of file diff --git a/.clang-format-cpp b/.clang-format-cpp deleted file mode 100644 index 55f2377..0000000 --- a/.clang-format-cpp +++ /dev/null @@ -1,4 +0,0 @@ ---- -BasedOnStyle: LLVM - -... diff --git a/driver/apc.c b/driver/apc.c index fef617b..b27dbe6 100644 --- a/driver/apc.c +++ b/driver/apc.c @@ -121,16 +121,17 @@ FreeApcAndDecrementApcCount(_Inout_ PRKAPC Apc, _In_ LONG ContextId) NTSTATUS QueryActiveApcContextsForCompletion() { + AcquireDriverConfigLock(); + for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) { PAPC_CONTEXT_HEADER entry = NULL; GetApcContextByIndex(&entry, index); - AcquireDriverConfigLock(); if (!entry) - goto increment; + continue; if (entry->count > 0 || entry->allocation_in_progress == TRUE) - goto increment; + continue; switch (entry->context_id) { case APC_CONTEXT_ID_STACKWALK: @@ -138,10 +139,9 @@ QueryActiveApcContextsForCompletion() FreeApcContextStructure(entry); break; } - - increment: - ReleaseDriverConfigLock(); } + + ReleaseDriverConfigLock(); return STATUS_SUCCESS; } @@ -211,7 +211,7 @@ DrvUnloadFreeAllApcContextStructures() return FALSE; } - ImpExFreePoolWithTag(entry, POOL_TAG_APC); + ImpExFreePoolWithTag(context, POOL_TAG_APC); } unlock: ReleaseDriverConfigLock(); diff --git a/driver/callbacks.c b/driver/callbacks.c index 96c05f1..8f0c9da 100644 --- a/driver/callbacks.c +++ b/driver/callbacks.c @@ -669,34 +669,34 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, !strcmp(process_creator_name, "explorer.exe")) goto end; - // POPEN_HANDLE_FAILURE_REPORT report = - // ImpExAllocatePool2(POOL_FLAG_NON_PAGED, - // sizeof(OPEN_HANDLE_FAILURE_REPORT), - // REPORT_POOL_TAG); + POPEN_HANDLE_FAILURE_REPORT report = + ImpExAllocatePool2(POOL_FLAG_NON_PAGED, + sizeof(OPEN_HANDLE_FAILURE_REPORT), + REPORT_POOL_TAG); - // if (!report) - // goto end; + if (!report) + goto end; - // report->report_code = - // REPORT_ILLEGAL_HANDLE_OPERATION; - // report->is_kernel_handle = - // OperationInformation->KernelHandle; - // report->process_id = process_creator_id; - // report->thread_id = ImpPsGetCurrentThreadId(); - // report->access = - // OperationInformation->Parameters->CreateHandleInformation.DesiredAccess; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, + REPORT_ILLEGAL_HANDLE_OPERATION, 0); - // RtlCopyMemory(report->process_name, - // process_creator_name, - // HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); + DEBUG_INFO("packet type: %hx", report->header.packet_type); + DEBUG_INFO("report code: %lx", report->report_header.report_code); + DEBUG_INFO("report subcode: %lx", report->report_header.report_sub_type); - // if (!NT_SUCCESS( - // IrpQueueCompleteIrp(report, - // sizeof(OPEN_HANDLE_FAILURE_REPORT)))) - //{ - // DEBUG_ERROR("IrpQueueCompleteIrp failed with - // no status."); goto end; - // } + report->is_kernel_handle = OperationInformation->KernelHandle; + report->process_id = process_creator_id; + report->thread_id = ImpPsGetCurrentThreadId(); + report->access = + OperationInformation->Parameters->CreateHandleInformation.DesiredAccess; + + RtlCopyMemory(report->process_name, + process_creator_name, + HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); + + IrpQueueCompleteIrp(report, + sizeof(OPEN_HANDLE_FAILURE_REPORT)); } end: @@ -857,8 +857,11 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, * also don't think its worth creating another queue * specifically for open handle reports since they will be rare. */ - report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION; - report->is_kernel_handle = 0; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER( + &report->report_header, REPORT_ILLEGAL_HANDLE_OPERATION, 0); + + report->is_kernel_handle = Entry->Attributes & OBJ_KERNEL_HANDLE; report->process_id = ImpPsGetProcessId(process); report->thread_id = 0; report->access = handle_access_mask; @@ -977,7 +980,7 @@ InitialiseTimerObject(_Out_ PTIMER_OBJECT Timer) LARGE_INTEGER due_time = {0}; LONG period = 0; - due_time.QuadPart = ABSOLUTE(SECONDS(5)); + due_time.QuadPart = -ABSOLUTE(SECONDS(5)); Timer->work_item = IoAllocateWorkItem(GetDriverDeviceObject()); diff --git a/driver/common.h b/driver/common.h index 0758818..02e539d 100644 --- a/driver/common.h +++ b/driver/common.h @@ -8,7 +8,7 @@ #include "types/types.h" /* - * For numbers < 32, these are equivalent to 0ul < x. + * For numbers < 32, these are equivalent to 0ul << x. * * For an item to be printed, its bitwise AND'd with the set filter. If the * result is non zero the log will be printed. @@ -191,7 +191,9 @@ typedef struct _DEFERRED_REPORTS_LIST { typedef struct _IRP_QUEUE_HEAD { LIST_ENTRY queue; - volatile UINT32 count; + volatile UINT32 irp_count; + volatile UINT32 total_reports_completed; + volatile UINT32 total_irps_completed; IO_CSQ csq; KSPIN_LOCK lock; DEFERRED_REPORTS_LIST deferred_reports; diff --git a/driver/integrity.c b/driver/integrity.c index c19b860..1aa11af 100644 --- a/driver/integrity.c +++ b/driver/integrity.c @@ -867,9 +867,12 @@ ReportInvalidProcessModule(_In_ PPROCESS_MODULE_INFORMATION Module) if (!report) return; - report->report_code = REPORT_INVALID_PROCESS_MODULE; - report->image_base = Module->module_base; - report->image_size = Module->module_size; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER( + &report->report_header, REPORT_INVALID_PROCESS_MODULE, 0); + + report->image_base = Module->module_base; + report->image_size = Module->module_size; RtlCopyMemory( report->module_path, Module->module_path, sizeof(report->module_path)); @@ -2099,7 +2102,7 @@ VOID WaitForHeartbeatCompletion(_In_ PHEARTBEAT_CONFIGURATION Configuration) { while (Configuration->active) - ; + YieldProcessor(); } STATIC @@ -2131,6 +2134,26 @@ HeartbeatWorkItem(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context) SetheartbeatInactive(config); } +FORCEINLINE +STATIC +VOID +IncrementHeartbeatCounter(_In_ PHEARTBEAT_CONFIGURATION Configuration) +{ + InterlockedIncrement(&Configuration->counter); +} + +FORCEINLINE +STATIC +PHEARTBEAT_PACKET +BuildHeartbeatPacket(_In_ PHEARTBEAT_CONFIGURATION Configuration) +{ + PHEARTBEAT_PACKET packet = ImpExAllocatePool2( + POOL_FLAG_NON_PAGED, sizeof(HEARTBEAT_PACKET), POOL_TAG_HEARTBEAT); + + if (!packet) + return NULL; +} + STATIC VOID HeartbeatDpcRoutine(_In_ PKDPC Dpc, @@ -2149,8 +2172,13 @@ HeartbeatDpcRoutine(_In_ PKDPC Dpc, SetHeartbeatActive(config); +#if DEBUG DEBUG_INFO("heartbeat called!"); - config->counter++; +#endif + + IncrementHeartbeatCounter(config); + +end: IoQueueWorkItem( config->work_item, HeartbeatWorkItem, NormalWorkQueue, config); diff --git a/driver/io.c b/driver/io.c index 9a8683a..eab2f9f 100644 --- a/driver/io.c +++ b/driver/io.c @@ -105,7 +105,7 @@ IrpQueuePeekNextEntry(_In_ PIO_CSQ Csq, _In_ PIRP Irp, _In_ PVOID Context) UNREFERENCED_PARAMETER(Context); PIRP_QUEUE_HEAD queue = GetIrpQueueHead(); - if (queue->count == 0) + if (queue->irp_count == 0) return NULL; return CONTAINING_RECORD(queue->queue.Flink, IRP, Tail.Overlay.ListEntry); @@ -116,7 +116,7 @@ VOID IrpQueueRemove(_In_ PIO_CSQ Csq, _In_ PIRP Irp) { UNREFERENCED_PARAMETER(Csq); - GetIrpQueueHead()->count--; + GetIrpQueueHead()->irp_count--; RemoveEntryList(&Irp->Tail.Overlay.ListEntry); } @@ -204,7 +204,7 @@ IrpQueueInsert(_In_ PIO_CSQ Csq, _In_ PIRP Irp) { PIRP_QUEUE_HEAD queue = GetIrpQueueHead(); InsertTailList(&queue->queue, &Irp->Tail.Overlay.ListEntry); - queue->count++; + queue->irp_count++; } STATIC diff --git a/driver/modules.c b/driver/modules.c index 51ea4f3..65f8a94 100644 --- a/driver/modules.c +++ b/driver/modules.c @@ -662,8 +662,15 @@ ReportInvalidDriverObject(_In_ PINVALID_DRIVERS_HEAD Head) if (!report) return; - report->report_code = REPORT_MODULE_VALIDATION_FAILURE; - report->report_type = Head->first_entry->reason; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, + REPORT_MODULE_VALIDATION_FAILURE, + Head->first_entry->reason); + + DEBUG_INFO("packet type: %hx", report->header.packet_type); + DEBUG_INFO("report code: %lx", report->report_header.report_code); + DEBUG_INFO("report subcode: %lx", report->report_header.report_sub_type); + report->driver_base_address = Head->first_entry->driver->DriverStart; report->driver_size = Head->first_entry->driver->DriverSize; @@ -803,7 +810,9 @@ ReportNmiBlocking() if (!report) return STATUS_INSUFFICIENT_RESOURCES; - report->report_code = REPORT_NMI_CALLBACK_FAILURE; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_NMI_CALLBACK_FAILURE, 0); + report->kthread_address = NULL; report->invalid_rip = NULL; report->were_nmis_disabled = TRUE; @@ -826,7 +835,9 @@ ReportMissingCidTableEntry(_In_ PNMI_CONTEXT Context) if (!report) return; - report->report_code = REPORT_HIDDEN_SYSTEM_THREAD; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_HIDDEN_SYSTEM_THREAD, 0); + report->found_in_kthreadlist = FALSE; // wip report->found_in_pspcidtable = FALSE; report->thread_id = ImpPsGetThreadId(Context->kthread); @@ -845,7 +856,12 @@ ReportInvalidRipFoundDuringNmi(_In_ PNMI_CONTEXT Context) sizeof(HIDDEN_SYSTEM_THREAD_REPORT), REPORT_POOL_TAG); - report->report_code = REPORT_NMI_CALLBACK_FAILURE; + if (!report) + return; + + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_NMI_CALLBACK_FAILURE, 0); + report->kthread_address = Context->kthread; report->invalid_rip = Context->interrupted_rip; report->were_nmis_disabled = FALSE; @@ -1130,9 +1146,12 @@ ReportApcStackwalkViolation(_In_ UINT64 Rip) if (!report) return; - report->report_code = REPORT_APC_STACKWALK; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_APC_STACKWALK, 0); + report->kthread_address = (UINT64)KeGetCurrentThread(); report->invalid_rip = Rip; + // report->driver ?? todo! IrpQueueCompleteIrp(report, sizeof(APC_STACKWALK_REPORT)); } @@ -1441,7 +1460,9 @@ ReportDpcStackwalkViolation(_In_ PDPC_CONTEXT Context, _In_ UINT64 Frame) if (!report) return; - report->report_code = REPORT_DPC_STACKWALK; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_DPC_STACKWALK, 0); + report->kthread_address = PsGetCurrentThread(); report->invalid_rip = Frame; @@ -1805,9 +1826,12 @@ ReportDataTableInvalidRoutine(_In_ TABLE_ID TableId, _In_ UINT64 Address) TableId, Address); - report->address = Address; - report->id = TableId; - report->id = REPORT_DATA_TABLE_ROUTINE; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_DATA_TABLE_ROUTINE, 0); + + report->address = Address; + report->table_id = TableId; + report->index = 0; RtlCopyMemory(report->routine, Address, DATA_TABLE_ROUTINE_BUF_SIZE); if (!NT_SUCCESS( @@ -2133,11 +2157,14 @@ ReportWin32kBase_DxgInterfaceViolation(_In_ UINT32 TableIndex, if (!report) return; - report->id = REPORT_DATA_TABLE_ROUTINE; - report->address = Address; - report->id = Win32kBase_gDxgInterface; - report->index = TableIndex; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER(&report->report_header, REPORT_DATA_TABLE_ROUTINE, 0); + + report->address = Address; + report->table_id = Win32kBase_gDxgInterface; + report->index = TableIndex; // todo! report->routine = ?? + // todo: maybe get routine by name from index ? IrpQueueCompleteIrp(report, sizeof(DPC_STACKWALK_REPORT)); } diff --git a/driver/pool.c b/driver/pool.c index f04e2b3..0c3a138 100644 --- a/driver/pool.c +++ b/driver/pool.c @@ -680,7 +680,7 @@ FindUnlinkedProcesses() PUINT64 allocation_address = NULL; PROCESS_SCAN_CONTEXT context = {0}; - PINVALID_PROCESS_ALLOCATION_REPORT report_buffer = NULL; + PINVALID_PROCESS_ALLOCATION_REPORT report = NULL; EnumerateProcessListWithCallbackRoutine(IncrementProcessCounter, &context); @@ -722,22 +722,22 @@ FindUnlinkedProcesses() "Potentially found an unlinked process allocation at address: %llx", allocation); - report_buffer = - ImpExAllocatePool2(POOL_FLAG_NON_PAGED, - sizeof(INVALID_PROCESS_ALLOCATION_REPORT), - REPORT_POOL_TAG); + report = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, + sizeof(INVALID_PROCESS_ALLOCATION_REPORT), + REPORT_POOL_TAG); - if (!report_buffer) + if (!report) continue; - report_buffer->report_code = REPORT_INVALID_PROCESS_ALLOCATION; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER( + &report->report_header, REPORT_INVALID_PROCESS_ALLOCATION, 0); - RtlCopyMemory(report_buffer->process, - allocation, - REPORT_INVALID_PROCESS_BUFFER_SIZE); + RtlCopyMemory( + report->process, allocation, REPORT_INVALID_PROCESS_BUFFER_SIZE); if (!NT_SUCCESS(IrpQueueCompleteIrp( - report_buffer, sizeof(INVALID_PROCESS_ALLOCATION_REPORT)))) { + report, sizeof(INVALID_PROCESS_ALLOCATION_REPORT)))) { DEBUG_ERROR("IrpQueueCompleteIrp failed with no status."); continue; } diff --git a/driver/thread.c b/driver/thread.c index a2863b9..cb7fd79 100644 --- a/driver/thread.c +++ b/driver/thread.c @@ -112,7 +112,10 @@ DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry, if (!report) return; - report->report_code = REPORT_ILLEGAL_ATTACH_PROCESS; + INIT_PACKET_HEADER(&report->header, PACKET_TYPE_REPORT); + INIT_REPORT_HEADER( + &report->report_header, REPORT_ILLEGAL_ATTACH_PROCESS, 0); + report->thread_id = ImpPsGetThreadId(ThreadListEntry->thread); report->thread_address = ThreadListEntry->thread; diff --git a/driver/types/types.h b/driver/types/types.h index 7a4f735..ab6580f 100644 --- a/driver/types/types.h +++ b/driver/types/types.h @@ -3,141 +3,174 @@ #include "../common.h" -#define REPORT_NMI_CALLBACK_FAILURE 50 -#define REPORT_MODULE_VALIDATION_FAILURE 60 -#define REPORT_ILLEGAL_HANDLE_OPERATION 70 +#define REPORT_NMI_CALLBACK_FAILURE 50 +#define REPORT_MODULE_VALIDATION_FAILURE 60 +#define REPORT_ILLEGAL_HANDLE_OPERATION 70 #define REPORT_INVALID_PROCESS_ALLOCATION 80 -#define REPORT_HIDDEN_SYSTEM_THREAD 90 -#define REPORT_ILLEGAL_ATTACH_PROCESS 100 -#define REPORT_APC_STACKWALK 110 -#define REPORT_DPC_STACKWALK 120 -#define REPORT_DATA_TABLE_ROUTINE 130 -#define REPORT_INVALID_PROCESS_MODULE 140 +#define REPORT_HIDDEN_SYSTEM_THREAD 90 +#define REPORT_ILLEGAL_ATTACH_PROCESS 100 +#define REPORT_APC_STACKWALK 110 +#define REPORT_DPC_STACKWALK 120 +#define REPORT_DATA_TABLE_ROUTINE 130 +#define REPORT_INVALID_PROCESS_MODULE 140 -typedef enum _TABLE_ID -{ - HalDispatch = 0, - HalPrivateDispatch, - Win32kBase_gDxgInterface +#define PACKET_TYPE_REPORT 0x0 +#define PACKET_TYPE_HEARTBEAT 0x1 + +#define INIT_PACKET_HEADER(header, type) \ + { \ + (header)->packet_type = type; \ + } + +#define INIT_REPORT_HEADER(report, code, subcode) \ + { \ + (report)->report_code = code; \ + (report)->report_sub_type = subcode; \ + } + +/* use a UINT16 rather then enum to explicitly state the size */ +typedef struct _PACKET_HEADER { + UINT16 packet_type; + +} PACKET_HEADER, *PPACKET_HEADER; + +typedef struct _REPORT_PACKET_HEADER { + UINT32 report_code; + UINT32 report_sub_type; + +} REPORT_PACKET_HEADER, *PREPORT_PACKET_HEADER; + +typedef enum _TABLE_ID { + HalDispatch = 0, + HalPrivateDispatch, + Win32kBase_gDxgInterface } TABLE_ID; -typedef struct _HYPERVISOR_DETECTION_REPORT -{ - INT aperf_msr_timing_check; - INT invd_emulation_check; +typedef struct _HYPERVISOR_DETECTION_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT8 aperf_msr_timing_check; + UINT8 invd_emulation_check; } HYPERVISOR_DETECTION_REPORT, *PHYPERVISOR_DETECTION_REPORT; #define APC_STACKWALK_BUFFER_SIZE 500 -typedef struct _APC_STACKWALK_REPORT -{ - INT report_code; - UINT64 kthread_address; - UINT64 invalid_rip; - CHAR driver[APC_STACKWALK_BUFFER_SIZE]; +typedef struct _APC_STACKWALK_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT64 kthread_address; + UINT64 invalid_rip; + CHAR driver[APC_STACKWALK_BUFFER_SIZE]; } APC_STACKWALK_REPORT, *PAPC_STACKWALK_REPORT; -typedef struct _DPC_STACKWALK_REPORT -{ - UINT32 report_code; - UINT64 kthread_address; - UINT64 invalid_rip; - CHAR driver[APC_STACKWALK_BUFFER_SIZE]; +typedef struct _DPC_STACKWALK_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT64 kthread_address; + UINT64 invalid_rip; + CHAR driver[APC_STACKWALK_BUFFER_SIZE]; } DPC_STACKWALK_REPORT, *PDPC_STACKWALK_REPORT; -typedef struct _MODULE_VALIDATION_FAILURE -{ - INT report_code; - INT report_type; - UINT64 driver_base_address; - UINT64 driver_size; - CHAR driver_name[128]; +typedef struct _MODULE_VALIDATION_FAILURE { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT64 driver_base_address; + UINT64 driver_size; + CHAR driver_name[128]; } MODULE_VALIDATION_FAILURE, *PMODULE_VALIDATION_FAILURE; #define DATA_TABLE_ROUTINE_BUF_SIZE 256 -typedef struct _DATA_TABLE_ROUTINE_REPORT -{ - UINT32 report_code; - TABLE_ID id; - UINT64 address; - UINT32 index; - CHAR routine[DATA_TABLE_ROUTINE_BUF_SIZE]; +typedef struct _DATA_TABLE_ROUTINE_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + TABLE_ID table_id; + UINT64 address; + UINT32 index; + CHAR routine[DATA_TABLE_ROUTINE_BUF_SIZE]; } DATA_TABLE_ROUTINE_REPORT, *PDATA_TABLE_ROUTINE_REPORT; -typedef struct _NMI_CALLBACK_FAILURE -{ - INT report_code; - INT were_nmis_disabled; - UINT64 kthread_address; - UINT64 invalid_rip; +typedef struct _NMI_CALLBACK_FAILURE { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT8 were_nmis_disabled; + UINT64 kthread_address; + UINT64 invalid_rip; } NMI_CALLBACK_FAILURE, *PNMI_CALLBACK_FAILURE; #define REPORT_INVALID_PROCESS_BUFFER_SIZE 500 -typedef struct _INVALID_PROCESS_ALLOCATION_REPORT -{ - INT report_code; - CHAR process[REPORT_INVALID_PROCESS_BUFFER_SIZE]; +typedef struct _INVALID_PROCESS_ALLOCATION_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + CHAR process[REPORT_INVALID_PROCESS_BUFFER_SIZE]; } INVALID_PROCESS_ALLOCATION_REPORT, *PINVALID_PROCESS_ALLOCATION_REPORT; -typedef struct _HIDDEN_SYSTEM_THREAD_REPORT -{ - INT report_code; - INT found_in_kthreadlist; - INT found_in_pspcidtable; - UINT64 thread_address; - LONG thread_id; - CHAR thread[500]; +typedef struct _HIDDEN_SYSTEM_THREAD_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT8 found_in_kthreadlist; + UINT8 found_in_pspcidtable; + UINT64 thread_address; + UINT32 thread_id; + CHAR thread[500]; } HIDDEN_SYSTEM_THREAD_REPORT, *PHIDDEN_SYSTEM_THREAD_REPORT; -typedef struct _ATTACH_PROCESS_REPORT -{ - INT report_code; - UINT32 thread_id; - UINT64 thread_address; +typedef struct _ATTACH_PROCESS_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT32 thread_id; + UINT64 thread_address; } ATTACH_PROCESS_REPORT, *PATTACH_PROCESS_REPORT; -typedef struct _KPRCB_THREAD_VALIDATION_CTX -{ - UINT64 thread; - BOOLEAN thread_found_in_pspcidtable; - // BOOLEAN thread_found_in_kthreadlist; - BOOLEAN finished; +typedef struct _KPRCB_THREAD_VALIDATION_CTX { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT64 thread; + BOOLEAN thread_found_in_pspcidtable; + // BOOLEAN thread_found_in_kthreadlist; + BOOLEAN finished; } KPRCB_THREAD_VALIDATION_CTX, *PKPRCB_THREAD_VALIDATION_CTX; #define HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH 64 -typedef struct _OPEN_HANDLE_FAILURE_REPORT -{ - INT report_code; - INT is_kernel_handle; - LONG process_id; - LONG thread_id; - LONG access; - CHAR process_name[HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH]; +typedef struct _OPEN_HANDLE_FAILURE_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT8 is_kernel_handle; + UINT32 process_id; + UINT32 thread_id; + UINT32 access; + CHAR process_name[HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH]; } OPEN_HANDLE_FAILURE_REPORT, *POPEN_HANDLE_FAILURE_REPORT; #define MODULE_PATH_LEN 256 -typedef struct _PROCESS_MODULE_VALIDATION_REPORT -{ - INT report_code; - UINT64 image_base; - UINT32 image_size; - WCHAR module_path[MODULE_PATH_LEN]; +typedef struct _PROCESS_MODULE_VALIDATION_REPORT { + PACKET_HEADER header; + REPORT_PACKET_HEADER report_header; + UINT64 image_base; + UINT32 image_size; + WCHAR module_path[MODULE_PATH_LEN]; } PROCESS_MODULE_VALIDATION_REPORT, *PPROCESS_MODULE_VALIDATION_REPORT; +typedef struct _HEARTBEAT_PACKET { + PACKET_HEADER header; + UINT32 heartbeat_count; + UINT32 last_report_id; + +} HEARTBEAT_PACKET, *PHEARTBEAT_PACKET; + #endif \ No newline at end of file diff --git a/module/helper.cpp b/module/helper.cpp index 2de351d..69389ed 100644 --- a/module/helper.cpp +++ b/module/helper.cpp @@ -13,8 +13,9 @@ void helper::sleep_thread(int seconds) { int helper::get_report_id_from_buffer(void *buffer) { kernel_interface::report_header *header = - reinterpret_cast(buffer); - return header->report_id; + reinterpret_cast( + (uint64_t)buffer + sizeof(kernel_interface::report_header)); + return header->report_code; } kernel_interface::report_id helper::get_kernel_report_type(void *buffer) { @@ -49,12 +50,18 @@ kernel_interface::report_id helper::get_kernel_report_type(void *buffer) { } void helper::print_kernel_report(void *buffer) { - switch (get_kernel_report_type(buffer)) { + kernel_interface::packet_header *header = + reinterpret_cast(buffer); + LOG_INFO("packet type: %lx", header->packet_type); + kernel_interface::report_header *report_header = + reinterpret_cast( + (uint64_t)buffer + sizeof(kernel_interface::packet_header)); + LOG_INFO("report code: %lx", report_header->report_code); + LOG_INFO("report sub code: %lx", report_header->report_sub_type); + switch (report_header->report_code) { case kernel_interface::report_id::report_nmi_callback_failure: { kernel_interface::nmi_callback_failure *r1 = reinterpret_cast(buffer); - LOG_INFO("report type: nmi_callback_failure"); - LOG_INFO("report code: %lx", r1->report_code); LOG_INFO("were_nmis_disabled: %lx", r1->were_nmis_disabled); LOG_INFO("kthread_address: %llx", r1->kthread_address); LOG_INFO("invalid_rip: %llx", r1->invalid_rip); @@ -65,8 +72,6 @@ void helper::print_kernel_report(void *buffer) { kernel_interface::invalid_process_allocation_report *r2 = reinterpret_cast( buffer); - LOG_INFO("report type: invalid_process_allocation_report"); - LOG_INFO("report code: %d", r2->report_code); LOG_INFO("********************************"); break; } @@ -74,8 +79,6 @@ void helper::print_kernel_report(void *buffer) { kernel_interface::hidden_system_thread_report *r3 = reinterpret_cast( buffer); - LOG_INFO("report type: hidden_system_thread_report"); - LOG_INFO("report code: %lx", r3->report_code); LOG_INFO("found_in_kthreadlist: %lx", r3->found_in_kthreadlist); LOG_INFO("found_in_pspcidtable: %lx", r3->found_in_pspcidtable); LOG_INFO("thread_address: %llx", r3->thread_address); @@ -97,8 +100,6 @@ void helper::print_kernel_report(void *buffer) { kernel_interface::open_handle_failure_report *r5 = reinterpret_cast( buffer); - LOG_INFO("report type: open_handle_failure_report"); - LOG_INFO("report code: %lx", r5->report_code); LOG_INFO("is_kernel_handle: %lx", r5->is_kernel_handle); LOG_INFO("process_id: %lx", r5->process_id); LOG_INFO("thread_id: %lx", r5->thread_id); @@ -111,8 +112,6 @@ void helper::print_kernel_report(void *buffer) { kernel_interface::process_module_validation_report *r6 = reinterpret_cast( buffer); - LOG_INFO("report type: process_module_validation_report"); - LOG_INFO("report code: %d", r6->report_code); LOG_INFO("image_base: %llx", r6->image_base); LOG_INFO("image_size: %u", r6->image_size); LOG_INFO("module_path: %ls", r6->module_path); @@ -122,8 +121,6 @@ void helper::print_kernel_report(void *buffer) { case kernel_interface::report_id::report_apc_stackwalk: { kernel_interface::apc_stackwalk_report *r7 = reinterpret_cast(buffer); - LOG_INFO("report type: apc_stackwalk_report"); - LOG_INFO("report code: %d", r7->report_code); LOG_INFO("kthread_address: %llx", r7->kthread_address); LOG_INFO("invalid_rip: %llx", r7->invalid_rip); LOG_INFO("********************************"); @@ -132,8 +129,6 @@ void helper::print_kernel_report(void *buffer) { case kernel_interface::report_id::report_dpc_stackwalk: { kernel_interface::dpc_stackwalk_report *r8 = reinterpret_cast(buffer); - LOG_INFO("report type: dpc_stackwalk_report"); - LOG_INFO("report code: %d", r8->report_code); LOG_INFO("kthread_address: %llx", r8->kthread_address); LOG_INFO("invalid_rip: %llx", r8->invalid_rip); LOG_INFO("********************************"); @@ -142,8 +137,6 @@ void helper::print_kernel_report(void *buffer) { case kernel_interface::report_id::report_data_table_routine: { kernel_interface::data_table_routine_report *r9 = reinterpret_cast(buffer); - LOG_INFO("report type: data_table_routine_report"); - LOG_INFO("report code: %d", r9->report_code); LOG_INFO("id: %d", r9->id); LOG_INFO("address: %llx", r9->address); LOG_INFO("routine: %s", r9->routine); @@ -153,9 +146,6 @@ void helper::print_kernel_report(void *buffer) { case kernel_interface::report_id::report_module_validation_failure: { kernel_interface::module_validation_failure *r10 = reinterpret_cast(buffer); - LOG_INFO("report type: module_validation_failure"); - LOG_INFO("report code: %lx", r10->report_code); - LOG_INFO("report type: %lx", r10->report_type); LOG_INFO("driver_base_address: %llx", r10->driver_base_address); LOG_INFO("driver_size: %llx", r10->driver_size); LOG_INFO("driver_name: %s", r10->driver_name); diff --git a/module/kernel_interface/kernel_interface.h b/module/kernel_interface/kernel_interface.h index 2a9857e..b07b61a 100644 --- a/module/kernel_interface/kernel_interface.h +++ b/module/kernel_interface/kernel_interface.h @@ -25,8 +25,13 @@ enum report_id { report_invalid_process_module = 140 }; +struct packet_header { + uint16_t packet_type; +}; + struct report_header { - int report_id; + uint32_t report_code; + uint32_t report_sub_type; }; constexpr int APC_STACKWALK_BUFFER_SIZE = 500; @@ -36,22 +41,24 @@ constexpr int HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH = 64; constexpr int MODULE_PATH_LEN = 256; struct apc_stackwalk_report { - int report_code; + packet_header header; + report_header report_header; uint64_t kthread_address; uint64_t invalid_rip; char driver[APC_STACKWALK_BUFFER_SIZE]; }; struct dpc_stackwalk_report { - uint32_t report_code; + packet_header header; + report_header report_header; uint64_t kthread_address; uint64_t invalid_rip; char driver[APC_STACKWALK_BUFFER_SIZE]; }; struct module_validation_failure { - int report_code; - int report_type; + packet_header header; + report_header report_header; uint64_t driver_base_address; uint64_t driver_size; char driver_name[128]; @@ -60,7 +67,8 @@ struct module_validation_failure { enum table_id { hal_dispatch = 0, hal_private_dispatch }; struct data_table_routine_report { - uint32_t report_code; + packet_header header; + report_header report_header; table_id id; uint64_t address; uint32_t index; @@ -68,23 +76,26 @@ struct data_table_routine_report { }; struct nmi_callback_failure { - int report_code; - int were_nmis_disabled; + packet_header header; + report_header report_header; + uint8_t were_nmis_disabled; uint64_t kthread_address; uint64_t invalid_rip; }; struct invalid_process_allocation_report { - int report_code; + packet_header header; + report_header report_header; char process[REPORT_INVALID_PROCESS_BUFFER_SIZE]; }; struct hidden_system_thread_report { - int report_code; - int found_in_kthreadlist; - int found_in_pspcidtable; + packet_header header; + report_header report_header; + uint8_t found_in_kthreadlist; + uint8_t found_in_pspcidtable; uint64_t thread_address; - long thread_id; + uint32_t thread_id; char thread[500]; }; @@ -94,23 +105,19 @@ struct attach_process_report { uint64_t thread_address; }; -struct kprcb_thread_validation_ctx { - uint64_t thread; - bool thread_found_in_pspcidtable; - bool finished; -}; - struct open_handle_failure_report { - int report_code; - int is_kernel_handle; - long process_id; - long thread_id; - long access; + packet_header header; + report_header report_header; + uint8_t is_kernel_handle; + uint32_t process_id; + uint32_t thread_id; + uint32_t access; char process_name[HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH]; }; struct process_module_validation_report { - int report_code; + packet_header header; + report_header report_header; uint64_t image_base; uint32_t image_size; wchar_t module_path[MODULE_PATH_LEN]; diff --git a/module/module.cpp b/module/module.cpp index 2d27e79..4282964 100644 --- a/module/module.cpp +++ b/module/module.cpp @@ -5,33 +5,24 @@ #include "client/message_queue.h" #include "dispatcher/dispatcher.h" -void -module::run(HINSTANCE hinstDLL) -{ -#if DEBUG - AllocConsole(); - FILE* file; - freopen_s(&file, "CONOUT$", "w", stdout); - freopen_s(&file, "CONIN$", "r", stdin); -#endif +void module::run(HINSTANCE hinstDLL) { + AllocConsole(); + FILE *file; + freopen_s(&file, "CONOUT$", "w", stdout); + freopen_s(&file, "CONIN$", "r", stdin); - LPTSTR pipe_name = (LPTSTR)L"\\\\.\\pipe\\DonnaACPipe"; - LPCWSTR driver_name = L"\\\\.\\DonnaAC"; + LPTSTR pipe_name = (LPTSTR)L"\\\\.\\pipe\\DonnaACPipe"; + LPCWSTR driver_name = L"\\\\.\\DonnaAC"; - client::message_queue queue(pipe_name); - dispatcher::dispatcher dispatch(driver_name, queue); - dispatch.run(); + client::message_queue queue(pipe_name); + dispatcher::dispatcher dispatch(driver_name, queue); + dispatch.run(); -#if DEBUG - fclose(stdout); - fclose(stdin); - FreeConsole(); -#endif + fclose(stdout); + fclose(stdin); + FreeConsole(); - FreeLibraryAndExitThread(hinstDLL, 0); + FreeLibraryAndExitThread(hinstDLL, 0); } -void -module::terminate() -{ -} \ No newline at end of file +void module::terminate() {} \ No newline at end of file