From c60bcda0001b60b9b62de8cb40693698a5751f80 Mon Sep 17 00:00:00 2001 From: lhodges1 Date: Wed, 31 Jan 2024 18:32:13 +1100 Subject: [PATCH] lil big of stuf --- .clang-format | 133 +-------- .clang-format-c | 131 +++++++++ .clang-format-cpp | 4 - ac.sln | 4 +- driver/callbacks.c | 28 +- driver/callbacks.h | 2 +- driver/common.h | 20 +- driver/crypt.c | 19 +- driver/crypt.h | 3 + driver/driver.c | 176 ++---------- driver/driver.h | 28 +- driver/driver.vcxproj | 2 + driver/driver.vcxproj.filters | 6 + driver/imports.c | 270 +++++++------------ driver/imports.h | 4 +- driver/integrity.c | 3 +- driver/io.c | 11 +- driver/io.h | 6 - driver/session.c | 156 +++++++++++ driver/session.h | 35 +++ driver/thread.c | 3 +- module/kernel_interface/kernel_interface.cpp | 6 +- module/kernel_interface/kernel_interface.h | 9 +- 23 files changed, 533 insertions(+), 526 deletions(-) create mode 100644 .clang-format-c delete mode 100644 .clang-format-cpp create mode 100644 driver/session.c create mode 100644 driver/session.h diff --git a/.clang-format b/.clang-format index 5ff9eec..55f2377 100644 --- a/.clang-format +++ b/.clang-format @@ -1,131 +1,4 @@ -Language: Cpp -BasedOnStyle: webkit -AccessModifierOffset: -4 +--- +BasedOnStyle: LLVM -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true - -AlignConsecutiveMacros: true - -AlignEscapedNewlines: Left -AlignOperands: true - -AlignTrailingComments: true - -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true - -AllowShortBlocksOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: true -AllowShortFunctionsOnASingleLine: false -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: TopLevel -AlwaysBreakBeforeMultilineStrings: false - -AlwaysBreakTemplateDeclarations: true #false - -BinPackArguments: false -BinPackParameters: false - -ExperimentalAutoDetectBinPacking: false -AllowAllParametersOfDeclarationOnNextLine: true - -BreakBeforeBraces: Custom -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: 100 -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: 8 - -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 -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: '8' -UseTab: Never \ No newline at end of file +... diff --git a/.clang-format-c b/.clang-format-c new file mode 100644 index 0000000..5ff9eec --- /dev/null +++ b/.clang-format-c @@ -0,0 +1,131 @@ +Language: Cpp +BasedOnStyle: webkit +AccessModifierOffset: -4 + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true + +AlignConsecutiveMacros: true + +AlignEscapedNewlines: Left +AlignOperands: true + +AlignTrailingComments: true + +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true + +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: TopLevel +AlwaysBreakBeforeMultilineStrings: false + +AlwaysBreakTemplateDeclarations: true #false + +BinPackArguments: false +BinPackParameters: false + +ExperimentalAutoDetectBinPacking: false +AllowAllParametersOfDeclarationOnNextLine: true + +BreakBeforeBraces: Custom +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: 100 +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: 8 + +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 +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: '8' +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/ac.sln b/ac.sln index 50e4a3f..9a90e3b 100644 --- a/ac.sln +++ b/ac.sln @@ -201,8 +201,8 @@ Global {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Debug|x64.Build.0 = Debug|x64 {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Debug|x86.ActiveCfg = Debug|Win32 {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Debug|x86.Build.0 = Debug|Win32 - {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|Any CPU.ActiveCfg = test|x64 - {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|Any CPU.Build.0 = test|x64 + {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|Any CPU.ActiveCfg = Release - No Server|x64 + {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|Any CPU.Build.0 = Release - No Server|x64 {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|ARM64.ActiveCfg = Release - No Server|x64 {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|ARM64.Build.0 = Release - No Server|x64 {3B18467A-4358-45EF-81B1-5C6F9B0B6728}.Release - No Server - Win10|x64.ActiveCfg = Release - No Server|x64 diff --git a/driver/callbacks.c b/driver/callbacks.c index 14fc7b6..c149f41 100644 --- a/driver/callbacks.c +++ b/driver/callbacks.c @@ -8,6 +8,7 @@ #include "modules.h" #include "imports.h" #include "list.h" +#include "session.h" STATIC BOOLEAN @@ -547,14 +548,14 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, * whilst we are cleaning up the callbacks on driver unload. We must hold the driver config * lock to ensure the pool containing the callback configuration lock is not freed */ - GetCallbackConfigStructure(&configuration); + SessionGetCallbackConfiguration(&configuration); if (!configuration) return OB_PREOP_SUCCESS; ImpKeAcquireGuardedMutex(&configuration->lock); - GetProtectedProcessId(&protected_process_id); - GetProtectedProcessEProcess(&protected_process); + SessionGetProcessId(&protected_process_id); + SessionGetProcess(&protected_process); if (!protected_process_id || !protected_process) goto end; @@ -690,7 +691,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, process = (PEPROCESS)object; process_name = ImpPsGetProcessImageFileName(process); - GetProtectedProcessEProcess(&protected_process); + SessionGetProcess(&protected_process); protected_process_name = ImpPsGetProcessImageFileName(protected_process); @@ -892,6 +893,9 @@ TimerObjectCallbackRoutine(_In_ PKDPC Dpc, { PTIMER_OBJECT timer = (PTIMER_OBJECT)DeferredContext; + if (!HasDriverLoaded()) + return; + /* we dont want to queue our work item if it hasnt executed */ if (timer->state) return; @@ -944,13 +948,13 @@ VOID UnregisterProcessObCallbacks() { PAGED_CODE(); - PPROCESS_CONFIG config = GetProcessConfig(); + PACTIVE_SESSION config = GetActiveSession(); AcquireDriverConfigLock(); - if (config->callback_info.registration_handle) + if (config->callback_configuration.registration_handle) { - ImpObUnRegisterCallbacks(config->callback_info.registration_handle); - config->callback_info.registration_handle = NULL; + ImpObUnRegisterCallbacks(config->callback_configuration.registration_handle); + config->callback_configuration.registration_handle = NULL; } ReleaseDriverConfigLock(); @@ -962,7 +966,7 @@ RegisterProcessObCallbacks() PAGED_CODE(); NTSTATUS status = STATUS_UNSUCCESSFUL; - PPROCESS_CONFIG config = GetProcessConfig(); + PACTIVE_SESSION config = GetActiveSession(); DEBUG_VERBOSE("Enabling ObRegisterCallbacks."); AcquireDriverConfigLock(); @@ -983,7 +987,7 @@ RegisterProcessObCallbacks() callback_registration.RegistrationContext = NULL; status = ImpObRegisterCallbacks(&callback_registration, - &config->callback_info.registration_handle); + &config->callback_configuration.registration_handle); if (!NT_SUCCESS(status)) DEBUG_ERROR("ObRegisterCallbacks failed with status %x", status); @@ -993,7 +997,7 @@ RegisterProcessObCallbacks() } VOID -InitialiseObCallbacksConfiguration(_Out_ PPROCESS_CONFIG ProcessConfig) +InitialiseObCallbacksConfiguration(_Out_ PACTIVE_SESSION ProcessConfig) { - ImpKeInitializeGuardedMutex(&ProcessConfig->callback_info.lock); + ImpKeInitializeGuardedMutex(&ProcessConfig->callback_configuration.lock); } \ No newline at end of file diff --git a/driver/callbacks.h b/driver/callbacks.h index 7697270..0fc7915 100644 --- a/driver/callbacks.h +++ b/driver/callbacks.h @@ -108,6 +108,6 @@ NTSTATUS RegisterProcessObCallbacks(); VOID -InitialiseObCallbacksConfiguration(_Out_ PPROCESS_CONFIG ProcessConfig); +InitialiseObCallbacksConfiguration(_Out_ PACTIVE_SESSION ProcessConfig); #endif diff --git a/driver/common.h b/driver/common.h index d98e56f..94f30c2 100644 --- a/driver/common.h +++ b/driver/common.h @@ -212,17 +212,23 @@ typedef struct _IRP_QUEUE_ENTRY * This structure can change at anytime based on whether * the target process to protect is open / closed / changes etc. */ -typedef struct _PROCESS_CONFIG + +#define AES_128_KEY_SIZE 16 + +typedef struct _ACTIVE_SESSION { - BOOLEAN initialised; - ULONG um_handle; + BOOLEAN is_session_active; + PVOID um_handle; PVOID km_handle; PEPROCESS process; - OB_CALLBACKS_CONFIG callback_info; - UINT16 cookie; - KGUARDED_MUTEX lock; + OB_CALLBACKS_CONFIG callback_configuration; -} PROCESS_CONFIG, *PPROCESS_CONFIG; + UINT32 session_cookie; + CHAR session_aes_key[AES_128_KEY_SIZE]; + + KGUARDED_MUTEX lock; + +} ACTIVE_SESSION, *PACTIVE_SESSION; #define NMI_CONTEXT_POOL '7331' #define STACK_FRAMES_POOL 'loop' diff --git a/driver/crypt.c b/driver/crypt.c index 458bd26..d1c1ba5 100644 --- a/driver/crypt.c +++ b/driver/crypt.c @@ -3,6 +3,8 @@ #include #include "imports.h" +#include + #define XOR_KEY_1 0x1122334455667788 #define XOR_KEY_2 0x0011223344556677 #define XOR_KEY_3 0x5566778899AABBCC @@ -123,4 +125,19 @@ CryptDecryptImportsArrayEntry(_In_ PUINT64 Array, _In_ UINT32 Entries, _In_ UINT } return pointer; -} \ No newline at end of file +} + +/* +* simple for now.. just to get it working +*/ +VOID +CryptDecryptBufferWithCookie(_In_ PVOID Buffer, _In_ UINT32 BufferSize, _In_ UINT32 Cookie) +{ + PCHAR buffer = (PCHAR)Buffer; + + for (UINT32 index = 0; index < BufferSize; index++) + { + buffer[index] ^= Cookie; + } +} + diff --git a/driver/crypt.h b/driver/crypt.h index fa87ab2..9d2e9bb 100644 --- a/driver/crypt.h +++ b/driver/crypt.h @@ -9,4 +9,7 @@ CryptEncryptImportsArray(_In_ PUINT64 Array, _In_ UINT32 Entries); UINT64 CryptDecryptImportsArrayEntry(_In_ PUINT64 Array, _In_ UINT32 Entries, _In_ UINT32 EntryIndex); +VOID +CryptDecryptBufferWithCookie(_In_ PVOID Buffer, _In_ UINT32 BufferSize, _In_ UINT32 Cookie); + #endif \ No newline at end of file diff --git a/driver/driver.c b/driver/driver.c index d9105a3..cc553ab 100644 --- a/driver/driver.c +++ b/driver/driver.c @@ -12,6 +12,7 @@ #include "imports.h" #include "apc.h" #include "crypt.h" +#include "session.h" STATIC VOID @@ -50,22 +51,12 @@ STATIC NTSTATUS DrvLoadEnableNotifyRoutines(); -STATIC -VOID -DrvLoadInitialiseObCbConfig(); - -STATIC -VOID -DrvLoadInitialiseProcessConfig(); - STATIC NTSTATUS DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath); #ifdef ALLOC_PRAGMA # pragma alloc_text(INIT, DriverEntry) -# pragma alloc_text(PAGE, GetProtectedProcessEProcess) -# pragma alloc_text(PAGE, GetProtectedProcessId) # pragma alloc_text(PAGE, GetDriverName) # pragma alloc_text(PAGE, GetDriverPath) # pragma alloc_text(PAGE, GetDriverRegistryPath) @@ -73,16 +64,12 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST # pragma alloc_text(PAGE, GetDriverSymbolicLink) # pragma alloc_text(PAGE, GetDriverConfigSystemInformation) # pragma alloc_text(PAGE, RegistryPathQueryCallbackRoutine) -# pragma alloc_text(PAGE, TerminateProtectedProcessOnViolation) # pragma alloc_text(PAGE, DrvUnloadUnregisterObCallbacks) # pragma alloc_text(PAGE, DrvUnloadFreeConfigStrings) # pragma alloc_text(PAGE, DrvUnloadFreeThreadList) # pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines) # pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines) -# pragma alloc_text(PAGE, DrvLoadInitialiseObCbConfig) -# pragma alloc_text(PAGE, DrvLoadInitialiseProcessConfig) # pragma alloc_text(PAGE, DrvLoadInitialiseDriverConfig) -# pragma alloc_text(PAGE, ReadProcessInitialisedConfigFlag) #endif typedef struct _DRIVER_CONFIG @@ -103,11 +90,12 @@ typedef struct _DRIVER_CONFIG SYS_MODULE_VAL_CONTEXT sys_val_context; IRP_QUEUE_HEAD irp_queue; TIMER_OBJECT timer; - PROCESS_CONFIG process_config; + ACTIVE_SESSION active_session; THREAD_LIST_HEAD thread_list; DRIVER_LIST_HEAD driver_list; PROCESS_LIST_HEAD process_list; SHARED_MAPPING mapping; + BOOLEAN has_driver_loaded; } DRIVER_CONFIG, *PDRIVER_CONFIG; @@ -126,6 +114,12 @@ PDRIVER_CONFIG g_DriverConfig = NULL; #define POOL_TAG_CONFIG 'conf' +BOOLEAN +HasDriverLoaded() +{ + return g_DriverConfig->has_driver_loaded; +} + VOID UnsetNmiInProgressFlag() { @@ -171,18 +165,10 @@ IsDriverUnloading() g_DriverConfig->unload_in_progress); } -PPROCESS_CONFIG -GetProcessConfig() +PACTIVE_SESSION +GetActiveSession() { - return &g_DriverConfig->process_config; -} - -VOID -GetCallbackConfigStructure(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration) -{ - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - *CallbackConfiguration = &g_DriverConfig->process_config.callback_info; - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); + return &g_DriverConfig->active_session; } LPCSTR @@ -275,88 +261,6 @@ GetProcessList() return &g_DriverConfig->process_list; } -VOID -ReadProcessInitialisedConfigFlag(_Out_ PBOOLEAN Flag) -{ - PAGED_CODE(); - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - *Flag = g_DriverConfig->process_config.initialised; - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); -} - -VOID -GetProtectedProcessEProcess(_Out_ PEPROCESS* Process) -{ - PAGED_CODE(); - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - *Process = g_DriverConfig->process_config.process; - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); -} - -VOID -GetProtectedProcessId(_Out_ PLONG ProcessId) -{ - PAGED_CODE(); - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - *ProcessId = g_DriverConfig->process_config.km_handle; - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); -} - -VOID -ProcCloseClearProcessConfiguration() -{ - PAGED_CODE(); - DEBUG_INFO("Protected process closed. Clearing process configuration."); - - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - g_DriverConfig->process_config.km_handle = NULL; - g_DriverConfig->process_config.um_handle = NULL; - g_DriverConfig->process_config.process = NULL; - g_DriverConfig->process_config.initialised = FALSE; - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); -} - -NTSTATUS -ProcLoadInitialiseProcessConfig(_In_ PIRP Irp) -{ - PAGED_CODE(); - - NTSTATUS status = STATUS_UNSUCCESSFUL; - PEPROCESS process = NULL; - PDRIVER_INITIATION_INFORMATION information = NULL; - - status = ValidateIrpInputBuffer(Irp, sizeof(DRIVER_INITIATION_INFORMATION)); - - if (!NT_SUCCESS(status)) - { - DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x", status); - return status; - } - - information = (PDRIVER_INITIATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer; - - ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock); - - g_DriverConfig->process_config.um_handle = information->protected_process_id; - - /* What if we pass an invalid handle here? not good. */ - status = ImpPsLookupProcessByProcessId(g_DriverConfig->process_config.um_handle, &process); - - if (!NT_SUCCESS(status)) - { - status = STATUS_INVALID_PARAMETER; - goto end; - } - - g_DriverConfig->process_config.km_handle = ImpPsGetProcessId(process); - g_DriverConfig->process_config.process = process; - g_DriverConfig->process_config.initialised = TRUE; - -end: - ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock); - return status; -} - /* * The question is, What happens if we attempt to register our callbacks after we * unregister them but before we free the pool? Hm.. No Good. @@ -561,58 +465,10 @@ DrvLoadSetupDriverLists() return status; } -STATIC -VOID -DrvLoadInitialiseProcessConfig() -{ - PAGED_CODE(); - ImpKeInitializeGuardedMutex(&g_DriverConfig->process_config.lock); -} - -STATIC -VOID -DrvLoadInitialiseObCbConfig() -{ - PAGED_CODE(); - InitialiseObCallbacksConfiguration(&g_DriverConfig->process_config); -} - /* * Regular routines */ -VOID -TerminateProtectedProcessOnViolation() -{ - PAGED_CODE(); - - NTSTATUS status = STATUS_UNSUCCESSFUL; - ULONG process_id = 0; - - GetProtectedProcessId(&process_id); - - if (!process_id) - { - DEBUG_ERROR("Failed to terminate process as process id is null"); - return; - } - - /* Make sure we pass a km handle to ZwTerminateProcess and NOT a usermode handle. */ - 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; - } - /* this wont be needed when procloadstuff is implemented */ - ProcCloseClearProcessConfiguration(); -} - STATIC NTSTATUS RegistryPathQueryCallbackRoutine(IN PWSTR ValueName, @@ -901,7 +757,7 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST ImpKeInitializeGuardedMutex(&g_DriverConfig->lock); IrpQueueInitialise(); - DrvLoadInitialiseObCbConfig(); + SessionInitialiseCallbackConfiguration(); g_DriverConfig->unload_in_progress = FALSE; g_DriverConfig->system_information.virtualised_environment = FALSE; @@ -955,7 +811,7 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl; DriverObject->DriverUnload = DriverUnload; - status = ResolveDynamicImports(DriverObject); + status = ImpResolveDynamicImports(DriverObject); if (!NT_SUCCESS(status)) return STATUS_FAILED_DRIVER_ENTRY; @@ -992,7 +848,7 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) return status; } - DrvLoadInitialiseProcessConfig(); + SessionInitialiseStructure(); status = IoCreateSymbolicLink(g_DriverConfig->device_symbolic_link, g_DriverConfig->device_name); @@ -1030,6 +886,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) return status; } + g_DriverConfig->has_driver_loaded = TRUE; + DEBUG_VERBOSE("Driver Entry Complete."); return STATUS_SUCCESS; } diff --git a/driver/driver.h b/driver/driver.h index c5508e0..edb19d9 100644 --- a/driver/driver.h +++ b/driver/driver.h @@ -10,30 +10,9 @@ #include "integrity.h" #include "callbacks.h" -NTSTATUS -ProcLoadInitialiseProcessConfig(_In_ PIRP Irp); - -VOID -GetProtectedProcessEProcess(_Out_ PEPROCESS* Process); - -VOID -GetProtectedProcessId(_Out_ PLONG ProcessId); - -VOID -ReadProcessInitialisedConfigFlag(_Out_ PBOOLEAN Flag); - NTSTATUS QueryActiveApcContextsForCompletion(); -VOID -TerminateProtectedProcessOnViolation(); - -VOID -ProcCloseClearProcessConfiguration(); - -VOID -GetCallbackConfigStructure(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration); - LPCSTR GetDriverName(); @@ -85,8 +64,8 @@ ReleaseDriverConfigLock(); BOOLEAN IsDriverUnloading(); -PPROCESS_CONFIG -GetProcessConfig(); +PACTIVE_SESSION +GetActiveSession(); PSHARED_MAPPING GetSharedMappingConfig(); @@ -97,4 +76,7 @@ UnsetNmiInProgressFlag(); BOOLEAN IsNmiInProgress(); +BOOLEAN +HasDriverLoaded(); + #endif \ No newline at end of file diff --git a/driver/driver.vcxproj b/driver/driver.vcxproj index 993ca49..4768d08 100644 --- a/driver/driver.vcxproj +++ b/driver/driver.vcxproj @@ -256,6 +256,7 @@ + @@ -273,6 +274,7 @@ + diff --git a/driver/driver.vcxproj.filters b/driver/driver.vcxproj.filters index ecbdf92..5725f7b 100644 --- a/driver/driver.vcxproj.filters +++ b/driver/driver.vcxproj.filters @@ -63,6 +63,9 @@ Source Files + + Source Files + @@ -113,6 +116,9 @@ Header Files + + Header Files + diff --git a/driver/imports.c b/driver/imports.c index 91b1b52..a082d9c 100644 --- a/driver/imports.c +++ b/driver/imports.c @@ -5,8 +5,6 @@ #include "crypt.h" #include -DRIVER_IMPORTS driver_imports = {0}; - PVOID FindDriverBaseNoApi(_In_ PDRIVER_OBJECT DriverObject, _In_ PWCH Name) { @@ -32,7 +30,7 @@ FindDriverBaseNoApi(_In_ PDRIVER_OBJECT DriverObject, _In_ PWCH Name) } PVOID -FindNtExport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) +ImpResolveNtImport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) { PVOID image_base = NULL; PIMAGE_DOS_HEADER dos_header = NULL; @@ -48,9 +46,6 @@ FindNtExport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) PVOID target_function_addr = 0; UINT32 export_offset = 0; - if (!ExportName) - return NULL; - image_base = FindDriverBaseNoApi(DriverObject, L"ntoskrnl.exe"); if (!image_base) @@ -81,8 +76,8 @@ FindNtExport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) if (strcmp(name, ExportName)) continue; - ordinal = ordinals_table[index]; - export_offset = export_addr_table[ordinal]; + ordinal = ordinals_table[index]; + export_offset = export_addr_table[ordinal]; target_function_addr = (PVOID)((UINT64)image_base + export_offset); return target_function_addr; } @@ -90,166 +85,107 @@ FindNtExport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) return NULL; } -NTSTATUS -ResolveDynamicImports(_In_ PDRIVER_OBJECT DriverObject) -{ - // clang-format off - driver_imports.DrvImpObDereferenceObject = FindNtExport(DriverObject, "ObDereferenceObject"); - driver_imports.DrvImpPsGetProcessImageFileName = FindNtExport(DriverObject, "PsGetProcessImageFileName"); - driver_imports.DrvImpPsSetCreateProcessNotifyRoutine = FindNtExport(DriverObject, "PsSetCreateProcessNotifyRoutine"); - driver_imports.DrvImpPsRemoveCreateThreadNotifyRoutine = FindNtExport(DriverObject, "PsRemoveCreateThreadNotifyRoutine"); - driver_imports.DrvImpPsGetCurrentThreadId = FindNtExport(DriverObject, "PsGetCurrentThreadId"); - driver_imports.DrvImpPsGetProcessId = FindNtExport(DriverObject, "PsGetProcessId"); - driver_imports.DrvImpPsLookupProcessByProcessId = FindNtExport(DriverObject, "PsLookupProcessByProcessId"); - driver_imports.DrvImpExEnumHandleTable = FindNtExport(DriverObject, "ExEnumHandleTable"); - driver_imports.DrvImpObGetObjectType = FindNtExport(DriverObject, "ObGetObjectType"); - driver_imports.DrvImpExfUnblockPushLock = FindNtExport(DriverObject, "ExfUnblockPushLock"); - driver_imports.DrvImpstrstr = FindNtExport(DriverObject, "strstr"); - driver_imports.DrvImpRtlInitUnicodeString = FindNtExport(DriverObject, "RtlInitUnicodeString"); - driver_imports.DrvImpMmGetSystemRoutineAddress = FindNtExport(DriverObject, "MmGetSystemRoutineAddress"); - driver_imports.DrvImpRtlUnicodeStringToAnsiString = FindNtExport(DriverObject, "RtlUnicodeStringToAnsiString"); - driver_imports.DrvImpRtlCopyUnicodeString = FindNtExport(DriverObject, "RtlCopyUnicodeString"); - driver_imports.DrvImpRtlFreeAnsiString = FindNtExport(DriverObject, "RtlFreeAnsiString"); - driver_imports.DrvImpKeInitializeGuardedMutex = FindNtExport(DriverObject, "KeInitializeGuardedMutex"); - driver_imports.DrvImpIoCreateDevice = FindNtExport(DriverObject, "IoCreateDevice"); - driver_imports.DrvImpIoCreateSymbolicLink = FindNtExport(DriverObject, "IoCreateSymbolicLink"); - driver_imports.DrvImpIoDeleteDevice = FindNtExport(DriverObject, "IoDeleteDevice"); - driver_imports.DrvImpIoDeleteSymbolicLink = FindNtExport(DriverObject, "IoDeleteSymbolicLink"); - driver_imports.DrvImpObRegisterCallbacks = FindNtExport(DriverObject, "ObRegisterCallbacks"); - driver_imports.DrvImpObUnRegisterCallbacks = FindNtExport(DriverObject, "ObUnRegisterCallbacks"); - driver_imports.DrvImpPsSetCreateThreadNotifyRoutine = FindNtExport(DriverObject, "PsSetCreateThreadNotifyRoutine"); - driver_imports.DrvImpKeRevertToUserAffinityThreadEx = FindNtExport(DriverObject, "KeRevertToUserAffinityThreadEx"); - driver_imports.DrvImpKeSetSystemAffinityThreadEx = FindNtExport(DriverObject, "KeSetSystemAffinityThreadEx"); - driver_imports.DrvImpstrnlen = FindNtExport(DriverObject, "strnlen"); - driver_imports.DrvImpRtlInitAnsiString = FindNtExport(DriverObject, "RtlInitAnsiString"); - driver_imports.DrvImpRtlAnsiStringToUnicodeString = FindNtExport(DriverObject, "RtlAnsiStringToUnicodeString"); - driver_imports.DrvImpIoGetCurrentProcess = FindNtExport(DriverObject, "IoGetCurrentProcess"); - driver_imports.DrvImpRtlGetVersion = FindNtExport(DriverObject, "RtlGetVersion"); - driver_imports.DrvImpRtlCompareMemory = FindNtExport(DriverObject, "RtlCompareMemory"); - driver_imports.DrvImpExGetSystemFirmwareTable = FindNtExport(DriverObject, "ExGetSystemFirmwareTable"); - driver_imports.DrvImpIoAllocateWorkItem = FindNtExport(DriverObject, "IoAllocateWorkItem"); - driver_imports.DrvImpIoFreeWorkItem = FindNtExport(DriverObject, "IoFreeWorkItem"); - driver_imports.DrvImpIoQueueWorkItem = FindNtExport(DriverObject, "IoQueueWorkItem"); - driver_imports.DrvImpZwOpenFile = FindNtExport(DriverObject, "ZwOpenFile"); - driver_imports.DrvImpZwClose = FindNtExport(DriverObject, "ZwClose"); - driver_imports.DrvImpZwCreateSection = FindNtExport(DriverObject, "ZwCreateSection"); - driver_imports.DrvImpZwMapViewOfSection = FindNtExport(DriverObject, "ZwMapViewOfSection"); - driver_imports.DrvImpZwUnmapViewOfSection = FindNtExport(DriverObject, "ZwUnmapViewOfSection"); - driver_imports.DrvImpMmCopyMemory = FindNtExport(DriverObject, "MmCopyMemory"); - driver_imports.DrvImpZwDeviceIoControlFile = FindNtExport(DriverObject, "ZwDeviceIoControlFile"); - driver_imports.DrvImpKeStackAttachProcess = FindNtExport(DriverObject, "KeStackAttachProcess"); - driver_imports.DrvImpKeUnstackDetachProcess = FindNtExport(DriverObject, "KeUnstackDetachProcess"); - driver_imports.DrvImpKeWaitForSingleObject = FindNtExport(DriverObject, "KeWaitForSingleObject"); - driver_imports.DrvImpPsCreateSystemThread = FindNtExport(DriverObject, "PsCreateSystemThread"); - driver_imports.DrvImpIofCompleteRequest = FindNtExport(DriverObject, "IofCompleteRequest"); - driver_imports.DrvImpObReferenceObjectByHandle = FindNtExport(DriverObject, "ObReferenceObjectByHandle"); - driver_imports.DrvImpKeDelayExecutionThread = FindNtExport(DriverObject, "KeDelayExecutionThread"); - driver_imports.DrvImpKeRegisterNmiCallback = FindNtExport(DriverObject, "KeRegisterNmiCallback"); - driver_imports.DrvImpKeDeregisterNmiCallback = FindNtExport(DriverObject, "KeDeregisterNmiCallback"); - driver_imports.DrvImpKeQueryActiveProcessorCount = FindNtExport(DriverObject, "KeQueryActiveProcessorCount"); - driver_imports.DrvImpExAcquirePushLockExclusiveEx = FindNtExport(DriverObject, "ExAcquirePushLockExclusiveEx"); - driver_imports.DrvImpExReleasePushLockExclusiveEx = FindNtExport(DriverObject, "ExReleasePushLockExclusiveEx"); - driver_imports.DrvImpPsGetThreadId = FindNtExport(DriverObject, "PsGetThreadId"); - driver_imports.DrvImpRtlCaptureStackBackTrace = FindNtExport(DriverObject, "RtlCaptureStackBackTrace"); - driver_imports.DrvImpZwOpenDirectoryObject = FindNtExport(DriverObject, "ZwOpenDirectoryObject"); - driver_imports.DrvImpKeInitializeAffinityEx = FindNtExport(DriverObject, "KeInitializeAffinityEx"); - driver_imports.DrvImpKeAddProcessorAffinityEx = FindNtExport(DriverObject, "KeAddProcessorAffinityEx"); - driver_imports.DrvImpRtlQueryModuleInformation = FindNtExport(DriverObject, "RtlQueryModuleInformation"); - driver_imports.DrvImpKeInitializeApc = FindNtExport(DriverObject, "KeInitializeApc"); - driver_imports.DrvImpKeInsertQueueApc = FindNtExport(DriverObject, "KeInsertQueueApc"); - driver_imports.DrvImpKeGenericCallDpc = FindNtExport(DriverObject, "KeGenericCallDpc"); - driver_imports.DrvImpKeSignalCallDpcDone = FindNtExport(DriverObject, "KeSignalCallDpcDone"); - driver_imports.DrvImpMmGetPhysicalMemoryRangesEx2 = FindNtExport(DriverObject, "MmGetPhysicalMemoryRangesEx2"); - driver_imports.DrvImpMmGetVirtualForPhysical = FindNtExport(DriverObject, "MmGetVirtualForPhysical"); - driver_imports.DrvImpObfReferenceObject = FindNtExport(DriverObject, "ObfReferenceObject"); - driver_imports.DrvImpExFreePoolWithTag = FindNtExport(DriverObject, "ExFreePoolWithTag"); - driver_imports.DrvImpExAllocatePool2 = FindNtExport(DriverObject, "ExAllocatePool2"); - driver_imports.DrvImpKeReleaseGuardedMutex = FindNtExport(DriverObject, "KeReleaseGuardedMutex"); - driver_imports.DrvImpKeAcquireGuardedMutex = FindNtExport(DriverObject, "KeAcquireGuardedMutex"); - driver_imports.DrvImpDbgPrintEx = FindNtExport(DriverObject, "DbgPrintEx"); - driver_imports.DrvImpRtlCompareUnicodeString = FindNtExport(DriverObject, "RtlCompareUnicodeString"); - driver_imports.DrvImpRtlFreeUnicodeString = FindNtExport(DriverObject, "RtlFreeUnicodeString"); - driver_imports.DrvImpPsLookupThreadByThreadId = FindNtExport(DriverObject, "PsLookupThreadByThreadId"); - driver_imports.DrvImpMmIsAddressValid = FindNtExport(DriverObject, "MmIsAddressValid"); +/* + * The strings in this array need to be hashed at compile time, then we can use the same hash + * function to compare when we walk the export table. + */ +#define NT_IMPORT_MAX_LENGTH 128 +#define NT_IMPORT_COUNT 79 - if (!driver_imports.DrvImpObDereferenceObject) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsGetProcessImageFileName) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsSetCreateProcessNotifyRoutine) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsRemoveCreateThreadNotifyRoutine) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsGetCurrentThreadId) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsGetProcessId) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsLookupProcessByProcessId) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExEnumHandleTable) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpObGetObjectType) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExfUnblockPushLock) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpstrstr) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlInitUnicodeString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpMmGetSystemRoutineAddress) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlUnicodeStringToAnsiString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlCopyUnicodeString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlFreeAnsiString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeInitializeGuardedMutex) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoCreateDevice) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoCreateSymbolicLink) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoDeleteDevice) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoDeleteSymbolicLink) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpObRegisterCallbacks) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpObUnRegisterCallbacks) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsSetCreateThreadNotifyRoutine) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeRevertToUserAffinityThreadEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeSetSystemAffinityThreadEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpstrnlen) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlInitAnsiString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlAnsiStringToUnicodeString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoGetCurrentProcess) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlGetVersion) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlCompareMemory) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExGetSystemFirmwareTable) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoAllocateWorkItem) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoFreeWorkItem) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIoQueueWorkItem) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwOpenFile) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwClose) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwCreateSection) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwMapViewOfSection) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwUnmapViewOfSection) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpMmCopyMemory) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwDeviceIoControlFile) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeStackAttachProcess) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeUnstackDetachProcess) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeWaitForSingleObject) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsCreateSystemThread) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpIofCompleteRequest) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpObReferenceObjectByHandle) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeDelayExecutionThread) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeRegisterNmiCallback) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeDeregisterNmiCallback) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeQueryActiveProcessorCount) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExAcquirePushLockExclusiveEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExReleasePushLockExclusiveEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsGetThreadId) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlCaptureStackBackTrace) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpZwOpenDirectoryObject) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeInitializeAffinityEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeAddProcessorAffinityEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlQueryModuleInformation) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeInitializeApc) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeInsertQueueApc) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeGenericCallDpc) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeSignalCallDpcDone) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpMmGetPhysicalMemoryRangesEx2) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpMmGetVirtualForPhysical) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpObfReferenceObject) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExFreePoolWithTag) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpExAllocatePool2) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeReleaseGuardedMutex) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpKeAcquireGuardedMutex) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpDbgPrintEx) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlCompareUnicodeString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpRtlFreeUnicodeString) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpPsLookupThreadByThreadId) return STATUS_UNSUCCESSFUL; - if (!driver_imports.DrvImpMmIsAddressValid) return STATUS_UNSUCCESSFUL; - // clang-format on +CHAR NT_IMPORTS[NT_IMPORT_COUNT][NT_IMPORT_MAX_LENGTH] = {"ObDereferenceObject", + "PsLookupThreadByThreadId", + "MmIsAddressValid", + "PsSetCreateProcessNotifyRoutine", + "PsRemoveCreateThreadNotifyRoutine", + "PsGetCurrentThreadId", + "PsGetProcessId", + "PsLookupProcessByProcessId", + "ExEnumHandleTable", + "ObGetObjectType", + "ExfUnblockPushLock", + "PsGetProcessImageFileName", + "strstr", + "RtlInitUnicodeString", + "RtlQueryRegistryValues", + "MmGetSystemRoutineAddress", + "RtlUnicodeStringToAnsiString", + "RtlCopyUnicodeString", + "RtlFreeAnsiString", + "KeInitializeGuardedMutex", + "IoCreateDevice", + "IoCreateSymbolicLink", + "IoDeleteDevice", + "IoDeleteSymbolicLink", + "ObRegisterCallbacks", + "ObUnRegisterCallbacks", + "PsSetCreateThreadNotifyRoutine", + "KeRevertToUserAffinityThreadEx", + "KeSetSystemAffinityThreadEx", + "strnlen", + "RtlInitAnsiString", + "RtlAnsiStringToUnicodeString", + "IoGetCurrentProcess", + "RtlGetVersion", + "RtlCompareMemory", + "ExGetSystemFirmwareTable", + "IoAllocateWorkItem", + "IoFreeWorkItem", + "IoQueueWorkItem", + "ZwOpenFile", + "ZwClose", + "ZwCreateSection", + "ZwMapViewOfSection", + "ZwUnmapViewOfSection", + "MmCopyMemory", + "ZwDeviceIoControlFile", + "KeStackAttachProcess", + "KeUnstackDetachProcess", + "KeWaitForSingleObject", + "PsCreateSystemThread", + "IofCompleteRequest", + "ObReferenceObjectByHandle", + "KeDelayExecutionThread", + "KeRegisterNmiCallback", + "KeDeregisterNmiCallback", + "KeQueryActiveProcessorCount", + "ExAcquirePushLockExclusiveEx", + "ExReleasePushLockExclusiveEx", + "PsGetThreadId", + "RtlCaptureStackBackTrace", + "ZwOpenDirectoryObject", + "KeInitializeAffinityEx", + "KeAddProcessorAffinityEx", + "RtlQueryModuleInformation", + "KeInitializeApc", + "KeInsertQueueApc", + "KeGenericCallDpc", + "KeSignalCallDpcDone", + "MmGetPhysicalMemoryRangesEx2", + "MmGetVirtualForPhysical", + "ObfReferenceObject", + "ExFreePoolWithTag", + "ExAllocatePool2", + "KeReleaseGuardedMutex", + "KeAcquireGuardedMutex", + "DbgPrintEx", + "RtlCompareUnicodeString", + "RtlFreeUnicodeString", + "PsGetProcessImageFileName"}; + +DRIVER_IMPORTS driver_imports = {0}; + +NTSTATUS +ImpResolveDynamicImports(_In_ PDRIVER_OBJECT DriverObject) +{ + PUINT64 imports_array = (PUINT64)&driver_imports; + + for (UINT32 index = 0; index < NT_IMPORT_COUNT; index++) + { + imports_array[index] = ImpResolveNtImport(DriverObject, NT_IMPORTS[index]); + + if (!imports_array[index]) + return STATUS_UNSUCCESSFUL; + } CryptEncryptImportsArray(&driver_imports, IMPORTS_LENGTH); diff --git a/driver/imports.h b/driver/imports.h index 56e317d..c16feea 100644 --- a/driver/imports.h +++ b/driver/imports.h @@ -4,10 +4,10 @@ #include "common.h" PVOID -FindNtExport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName); +ImpResolveNtImport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName); NTSTATUS -ResolveDynamicImports(_In_ PDRIVER_OBJECT DriverObject); +ImpResolveDynamicImports(_In_ PDRIVER_OBJECT DriverObject); #define IMPORT_FUNCTION_MAX_LENGTH 128 #define IMPORT_FUNCTION_COUNT 256 diff --git a/driver/integrity.c b/driver/integrity.c index dcc845d..eed25d8 100644 --- a/driver/integrity.c +++ b/driver/integrity.c @@ -6,6 +6,7 @@ #include "callbacks.h" #include "io.h" #include "imports.h" +#include "session.h" #include #include @@ -888,7 +889,7 @@ ValidateProcessLoadedModule(_Inout_ PIRP Irp) module_info = (PPROCESS_MODULE_INFORMATION)Irp->AssociatedIrp.SystemBuffer; - GetProtectedProcessEProcess(&process); + SessionGetProcess(&process); ImpRtlInitUnicodeString(&module_path, &module_info->module_path); /* diff --git a/driver/io.c b/driver/io.c index 6cc5952..d7a4756 100644 --- a/driver/io.c +++ b/driver/io.c @@ -10,6 +10,7 @@ #include "hv.h" #include "imports.h" #include "list.h" +#include "session.h" STATIC NTSTATUS @@ -669,7 +670,7 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) /* * LMAO */ - ReadProcessInitialisedConfigFlag(&security_flag); + SessionIsActive(&security_flag); if (security_flag == FALSE && stack_location->Parameters.DeviceIoControl.IoControlCode != IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH) @@ -724,11 +725,11 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH Received"); - status = ProcLoadInitialiseProcessConfig(Irp); + status = SessionInitialise(Irp); if (!NT_SUCCESS(status)) { - DEBUG_ERROR("InitialiseProcessConfig failed with status %x", status); + DEBUG_ERROR("InitialiseSession failed with status %x", status); goto end; } @@ -827,7 +828,7 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION Received"); - ProcCloseClearProcessConfiguration(); + SessionTerminate(); UnregisterProcessObCallbacks(); break; @@ -1006,7 +1007,7 @@ DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) DEBUG_INFO("Handle to driver closed."); /* we also lose reports here, so sohuld pass em into the irp before freeing */ - ProcCloseClearProcessConfiguration(); + SessionTerminate(); UnregisterProcessObCallbacks(); SharedMappingTerminate(); diff --git a/driver/io.h b/driver/io.h index d03281d..561e245 100644 --- a/driver/io.h +++ b/driver/io.h @@ -6,12 +6,6 @@ #include #include "common.h" -typedef struct _DRIVER_INITIATION_INFORMATION -{ - ULONG protected_process_id; - -} DRIVER_INITIATION_INFORMATION, *PDRIVER_INITIATION_INFORMATION; - typedef struct _SHARED_MAPPING_INIT { PVOID buffer; diff --git a/driver/session.c b/driver/session.c new file mode 100644 index 0000000..36f42c2 --- /dev/null +++ b/driver/session.c @@ -0,0 +1,156 @@ +#include "session.h" + +#include "imports.h" + +/* for now, lets just xor the aes key with our cookie */ + +typedef struct _SESSION_INITIATION_PACKET +{ + UINT32 session_cookie; + CHAR session_aes_key[AES_128_KEY_SIZE]; + PVOID protected_process_id; + +} SESSION_INITIATION_PACKET, *PSESSION_INITIATION_PACKET; + +VOID +SessionInitialiseStructure() +{ + PAGED_CODE(); + ImpKeInitializeGuardedMutex(&GetActiveSession()->lock); +} + +VOID +SessionInitialiseCallbackConfiguration() +{ + PAGED_CODE(); + InitialiseObCallbacksConfiguration(GetActiveSession()); +} + +VOID +SessionIsActive(_Out_ PBOOLEAN Flag) +{ + PAGED_CODE(); + ImpKeAcquireGuardedMutex(&GetActiveSession()->lock); + *Flag = GetActiveSession()->is_session_active; + ImpKeReleaseGuardedMutex(&GetActiveSession()->lock); +} + +VOID +SessionGetProcess(_Out_ PEPROCESS* Process) +{ + PAGED_CODE(); + ImpKeAcquireGuardedMutex(&GetActiveSession()->lock); + *Process = GetActiveSession()->process; + ImpKeReleaseGuardedMutex(&GetActiveSession()->lock); +} + +VOID +SessionGetProcessId(_Out_ PLONG ProcessId) +{ + PAGED_CODE(); + ImpKeAcquireGuardedMutex(&GetActiveSession()->lock); + *ProcessId = GetActiveSession()->km_handle; + ImpKeReleaseGuardedMutex(&GetActiveSession()->lock); +} + +VOID +SessionGetCallbackConfiguration(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration) +{ + ImpKeAcquireGuardedMutex(&GetActiveSession()->lock); + *CallbackConfiguration = &GetActiveSession()->callback_configuration; + ImpKeReleaseGuardedMutex(&GetActiveSession()->lock); +} + +VOID +SessionTerminate() +{ + PAGED_CODE(); + DEBUG_INFO("Termination active session."); + + PACTIVE_SESSION session = GetActiveSession(); + + ImpKeAcquireGuardedMutex(&session->lock); + session->km_handle = NULL; + session->um_handle = NULL; + session->process = NULL; + session->is_session_active = FALSE; + ImpKeReleaseGuardedMutex(&session->lock); +} + +NTSTATUS +SessionInitialise(_In_ PIRP Irp) +{ + PAGED_CODE(); + + NTSTATUS status = STATUS_UNSUCCESSFUL; + PEPROCESS process = NULL; + PSESSION_INITIATION_PACKET information = NULL; + PACTIVE_SESSION session = GetActiveSession(); + + DEBUG_VERBOSE("Initialising new session."); + + status = ValidateIrpInputBuffer(Irp, sizeof(SESSION_INITIATION_PACKET)); + + if (!NT_SUCCESS(status)) + { + DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x", status); + return status; + } + + information = (PSESSION_INITIATION_PACKET)Irp->AssociatedIrp.SystemBuffer; + + ImpKeAcquireGuardedMutex(&session->lock); + + session->um_handle = information->protected_process_id; + + /* What if we pass an invalid handle here? not good. */ + status = ImpPsLookupProcessByProcessId(session->um_handle, &process); + + if (!NT_SUCCESS(status)) + { + status = STATUS_INVALID_PARAMETER; + goto end; + } + + session->km_handle = ImpPsGetProcessId(process); + session->process = process; + session->is_session_active = TRUE; + session->session_cookie = information->session_cookie; + RtlCopyMemory(session->session_aes_key, information->session_aes_key, AES_128_KEY_SIZE); + +end: + ImpKeReleaseGuardedMutex(&session->lock); + return status; +} + +VOID +SessionTerminateProcess() +{ + PAGED_CODE(); + + NTSTATUS status = STATUS_UNSUCCESSFUL; + ULONG process_id = 0; + + SessionGetProcessId(&process_id); + + if (!process_id) + { + DEBUG_ERROR("Failed to terminate process as process id is null"); + return; + } + + /* Make sure we pass a km handle to ZwTerminateProcess and NOT a usermode handle. */ + 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; + } + /* this wont be needed when procloadstuff is implemented */ + SessionTerminate(); +} \ No newline at end of file diff --git a/driver/session.h b/driver/session.h new file mode 100644 index 0000000..41fae7e --- /dev/null +++ b/driver/session.h @@ -0,0 +1,35 @@ +#ifndef SESSION_H +#define SESSION_H + +#include "common.h" + +#include "driver.h" + +VOID +SessionInitialiseStructure(); + +VOID +SessionInitialiseCallbackConfiguration(); + +VOID +SessionIsActive(_Out_ PBOOLEAN Flag); + +VOID +SessionGetProcess(_Out_ PEPROCESS* Process); + +VOID +SessionGetProcessId(_Out_ PLONG ProcessId); + +VOID +SessionGetCallbackConfiguration(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration); + +VOID +SessionTerminate(); + +NTSTATUS +SessionInitialise(_In_ PIRP Irp); + +VOID +SessionTerminateProcess(); + +#endif \ No newline at end of file diff --git a/driver/thread.c b/driver/thread.c index b79a279..83c2782 100644 --- a/driver/thread.c +++ b/driver/thread.c @@ -6,6 +6,7 @@ #include "callbacks.h" #include "driver.h" #include "queue.h" +#include "session.h" #include "imports.h" #ifdef ALLOC_PRAGMA @@ -80,7 +81,7 @@ DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry, PKAPC_STATE apc_state = NULL; PEPROCESS protected_process = NULL; - GetProtectedProcessEProcess(&protected_process); + SessionGetProcess(&protected_process); if (!protected_process) return; diff --git a/module/kernel_interface/kernel_interface.cpp b/module/kernel_interface/kernel_interface.cpp index 487327d..f93c361 100644 --- a/module/kernel_interface/kernel_interface.cpp +++ b/module/kernel_interface/kernel_interface.cpp @@ -139,10 +139,10 @@ void kernel_interface::kernel_interface::generic_driver_call_apc( void kernel_interface::kernel_interface::notify_driver_on_process_launch() { unsigned long bytes_returned = 0; - process_load_packet packet = {0}; - packet.protected_process_id = GetCurrentProcessId(); + session_initiation_packet packet = {0}; + packet.protected_process_id = reinterpret_cast(GetCurrentProcessId()); generic_driver_call_input(ioctl_code::NotifyDriverOnProcessLaunch, &packet, - sizeof(packet), &bytes_returned); + sizeof(session_initiation_packet), &bytes_returned); } void kernel_interface::kernel_interface::detect_system_virtualization() { diff --git a/module/kernel_interface/kernel_interface.h b/module/kernel_interface/kernel_interface.h index a37f29d..8344d59 100644 --- a/module/kernel_interface/kernel_interface.h +++ b/module/kernel_interface/kernel_interface.h @@ -10,6 +10,7 @@ static constexpr int EVENT_COUNT = 5; static constexpr int MAX_MODULE_PATH = 256; static constexpr int MAXIMUM_REPORT_BUFFER_SIZE = 1000; static constexpr int QUERY_DEFERRED_REPORT_COUNT = 10; +static constexpr int AES_128_KEY_SIZE = 16; enum report_id { report_nmi_callback_failure = 50, @@ -172,10 +173,14 @@ struct event_dispatcher { }; class kernel_interface { - struct process_load_packet { - unsigned long protected_process_id; + struct session_initiation_packet { + unsigned __int32 session_cookie; + char session_aes_key[AES_128_KEY_SIZE]; + void *protected_process_id; }; + int test = sizeof(session_initiation_packet); + struct hv_detection_packet { unsigned long aperf_msr_timing_check; unsigned long invd_emulation_check;