From 3a6cc599c1bb64842e03e647bdb6d46e5ff980d6 Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Sat, 1 Jan 2022 16:29:55 +0330 Subject: [PATCH] remove hooks after calling the user-mode entrypoint --- .../commands/meta-commands/detach.cpp | 2 +- .../code/debugger/core/debugger.cpp | 11 +++ .../user-level/usermode-debugging.cpp | 67 +++++++++++++- .../code/debugger/user-level/Attaching.c | 89 ++++++++++++++++++- .../code/debugger/user-level/UserAccess.c | 1 - hyperdbg/include/Definition.h | 44 +++++++-- 6 files changed, 200 insertions(+), 14 deletions(-) diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/detach.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/detach.cpp index d98c5622..d3bf09ee 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/detach.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/commands/meta-commands/detach.cpp @@ -65,7 +65,7 @@ DetachFromProcess() // // We wanna detach from a process // - DetachRequest.IsAttach = FALSE; + DetachRequest.Action = DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH; DetachRequest.ProcessId = g_DebuggingState.ConnectedProcessId; DetachRequest.ThreadId = g_DebuggingState.ConnectedThreadId; diff --git a/hyperdbg/hprdbgctrl/code/debugger/core/debugger.cpp b/hyperdbg/hprdbgctrl/code/debugger/core/debugger.cpp index e2973dd3..2bb36a65 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/core/debugger.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/core/debugger.cpp @@ -268,6 +268,17 @@ ShowErrorMessage(UINT32 Error) Error); break; + case DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS_ENTRYPOINT_NOT_REACHED: + ShowMessages("err, unable to remove hooks as the entrypoint of user-mode " + "process is not reached yet (%x)\n", + Error); + break; + + case DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS: + ShowMessages("err, unable to remove hooks (%x)\n", + Error); + break; + default: ShowMessages("err, error not found (%x)\n", Error); diff --git a/hyperdbg/hprdbgctrl/code/debugger/user-level/usermode-debugging.cpp b/hyperdbg/hprdbgctrl/code/debugger/user-level/usermode-debugging.cpp index e8685894..289ff2f0 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/user-level/usermode-debugging.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/user-level/usermode-debugging.cpp @@ -258,7 +258,7 @@ UsermodeDebuggingAttachToProcess(UINT32 TargetPid, UINT32 TargetTid, const WCHAR // // We wanna attach to a remote process // - AttachRequest.IsAttach = TRUE; + AttachRequest.Action = DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH; if (AttachRequest.IsStartingNewProcess) { @@ -285,7 +285,6 @@ UsermodeDebuggingAttachToProcess(UINT32 TargetPid, UINT32 TargetTid, const WCHAR // // Send the request to the kernel // - Status = DeviceIoControl( g_DeviceHandle, // Handle to device IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // IO Control @@ -323,6 +322,70 @@ UsermodeDebuggingAttachToProcess(UINT32 TargetPid, UINT32 TargetTid, const WCHAR // ResumeThread(ProcInfo.hThread); + // + // *** Remove the hooks *** + // + + while (TRUE) + { + // + // Send the previous request with removing hook as the action + // + AttachRequest.Action = DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS; + + // + // Send the request to the kernel + // + Status = DeviceIoControl( + g_DeviceHandle, // Handle to device + IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // IO Control + // code + &AttachRequest, // Input Buffer to driver. + SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // Input buffer length + &AttachRequest, // Output Buffer from driver. + SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, // Length of output + // buffer in bytes. + &ReturnedLength, // Bytes placed in buffer. + NULL // synchronous call + ); + + if (!Status) + { + ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); + return FALSE; + } + + // + // Check whether the result of removing hooks was successful or we should + // re-send the request + // + if (AttachRequest.Result == DEBUGGER_OPERATION_WAS_SUCCESSFULL) + { + // + // The hook is remove successfuly + // + break; + } + else if (AttachRequest.Result == DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS_ENTRYPOINT_NOT_REACHED) + { + // + // Wait for a while until the Windows call the entrypoint + // + // ShowMessages("entrypoint is not reached, continue sending the request...\n"); + + Sleep(1000); + continue; + } + else + { + // + // An error happend, we should not continue + // + ShowErrorMessage(AttachRequest.Result); + return FALSE; + } + } + // // The operation of attaching was successful // diff --git a/hyperdbg/hprdbghv/code/debugger/user-level/Attaching.c b/hyperdbg/hprdbghv/code/debugger/user-level/Attaching.c index 7cebd14e..2dd2ae14 100644 --- a/hyperdbg/hprdbghv/code/debugger/user-level/Attaching.c +++ b/hyperdbg/hprdbghv/code/debugger/user-level/Attaching.c @@ -107,10 +107,19 @@ AttachingHandleEntrypointDebugBreak(UINT32 CurrentProcessorIndex, PGUEST_REGS Gu // g_UsermodeAttachingState.IsWaitingForUserModeModuleEntrypointToBeCalled = FALSE; + // + // Clear the current hw debug register + // + DebugRegistersSet(DEBUGGER_DEBUG_REGISTER_FOR_USER_MODE_ENTRY_POINT, + BREAK_ON_INSTRUCTION_FETCH, + FALSE, + NULL); + // // Temporarily handle everything in kernel debugger // - KdHandleDebugEventsWhenKernelDebuggerIsAttached(CurrentProcessorIndex, GuestRegs); + // KdHandleDebugEventsWhenKernelDebuggerIsAttached(CurrentProcessorIndex, GuestRegs); + LogInfo("I'm here at %llx :)", g_GuestState[CurrentProcessorIndex].LastVmexitRip); } } @@ -122,7 +131,7 @@ AttachingHandleEntrypointDebugBreak(UINT32 CurrentProcessorIndex, PGUEST_REGS Gu * @return VOID */ VOID -AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS AttachRequest) +AttachingSuspendedTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS AttachRequest) { PEPROCESS SourceProcess; BOOLEAN ResultOfApplyingEvent; @@ -184,3 +193,79 @@ AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS AttachRequest) AttachRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFULL; } + +/** + * @brief Clearing hooks after resuming the process + * @details this function should be called in vmx-root + * + * @param AttachRequest + * @return VOID + */ +VOID +AttachingRemoveHooks(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS AttachRequest) +{ + // + // Check if the entrypoint is reached or not, + // if it's not reached then we won't remove the hooks + // + if (!g_UsermodeAttachingState.IsWaitingForUserModeModuleEntrypointToBeCalled) + { + // + // The entrypoint is called, we should remove the hook + // + if (!EptHookUnHookSingleAddress(g_UsermodeAttachingState.PebAddressToMonitor, + NULL, + g_UsermodeAttachingState.ProcessId)) + { + AttachRequest->Result = DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS; + return; + } + else + { + // + // The unhooking operation was successful + // + AttachRequest->Result = DEBUGGER_OPERATION_WAS_SUCCESSFULL; + } + } + else + { + // + // The entrypoint is not called, we shouldn't remove the hook + // + AttachRequest->Result = DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS_ENTRYPOINT_NOT_REACHED; + return; + } +} + +/** + * @brief Dispatch and perform attaching tasks + * @details this function should be called in vmx-root + * + * @param AttachRequest + * @return VOID + */ +VOID +AttachingTargetProcess(PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS AttachRequest) +{ + switch (AttachRequest->Action) + { + case DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH: + + AttachingSuspendedTargetProcess(AttachRequest); + + break; + + case DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS: + + AttachingRemoveHooks(AttachRequest); + + break; + + default: + + AttachRequest->Result = DEBUGGER_ERROR_INVALID_ACTION_TYPE; + + break; + } +} diff --git a/hyperdbg/hprdbghv/code/debugger/user-level/UserAccess.c b/hyperdbg/hprdbghv/code/debugger/user-level/UserAccess.c index cd9edd50..a182fb0a 100644 --- a/hyperdbg/hprdbghv/code/debugger/user-level/UserAccess.c +++ b/hyperdbg/hprdbghv/code/debugger/user-level/UserAccess.c @@ -535,7 +535,6 @@ UserAccessPrintLoadedModules(HANDLE ProcessId) // // x64 process, walk x64 module list // - if (UserAccessPrintLoadedModulesX64(SourceProcess)) { return TRUE; diff --git a/hyperdbg/include/Definition.h b/hyperdbg/include/Definition.h index 7b2932cd..343d3623 100644 --- a/hyperdbg/include/Definition.h +++ b/hyperdbg/include/Definition.h @@ -1380,6 +1380,7 @@ typedef enum _DEBUGGER_SEARCH_MEMORY_TYPE { SEARCH_PHYSICAL_MEMORY, SEARCH_VIRTUAL_MEMORY + } DEBUGGER_SEARCH_MEMORY_TYPE; /** @@ -1391,6 +1392,7 @@ typedef enum _DEBUGGER_SEARCH_MEMORY_BYTE_SIZE SEARCH_BYTE, SEARCH_DWORD, SEARCH_QWORD + } DEBUGGER_SEARCH_MEMORY_BYTE_SIZE; /** @@ -1483,20 +1485,32 @@ typedef struct _DEBUGGER_PAUSE_PACKET_RECEIVED #define SIZEOF_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS \ sizeof(DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS) +/** + * @brief different sizes on searching memory + * + */ +typedef enum _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE +{ + DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH, + DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH, + DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS, + +} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE; + /** * @brief request for attaching user-mode process * */ typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS { - BOOLEAN IsAttach; - BOOLEAN IsStartingNewProcess; - UINT32 ProcessId; - UINT64 ThreadId; - BOOLEAN Is32Bit; - UINT64 BaseAddressOfMainModule; - UINT64 EntrypoinOfMainModule; - UINT64 Result; + BOOLEAN IsStartingNewProcess; + UINT32 ProcessId; + UINT64 ThreadId; + BOOLEAN Is32Bit; + UINT64 BaseAddressOfMainModule; + UINT64 EntrypoinOfMainModule; + DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action; + UINT64 Result; } DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, *PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS; @@ -2291,6 +2305,20 @@ typedef struct _DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET */ #define DEBUGGER_ERROR_UNABLE_TO_ATTACH_TO_TARGET_USER_MODE_PROCESS 0xc000002a +/** + * @brief error, failed to remove hooks as entrypoint is not reached yet + * @details The caller of this functionality should keep sending the previous + * IOCTL until the hook is remove successfully + * + */ +#define DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS_ENTRYPOINT_NOT_REACHED 0xc000002b + +/** + * @brief error, could not remove the previous hook + * + */ +#define DEBUGGER_ERROR_UNABLE_TO_REMOVE_HOOKS 0xc000002c + // // WHEN YOU ADD ANYTHING TO THIS LIST OF ERRORS, THEN // MAKE SURE TO ADD AN ERROR MESSAGE TO ShowErrorMessage(UINT32 Error)