diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/test.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/test.cpp index c937d24d..758862f4 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/test.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/test.cpp @@ -330,6 +330,27 @@ CommandTestQueryPreAllocPoolsState() KdSendTestQueryPacketToDebuggee(TEST_QUERY_PREALLOCATED_POOL_STATE); } +/** + * @brief test command for setting target tasks to halted cores + * + * @return VOID + */ +VOID +CommandTestSetTargetTaskToHaltedCores() +{ + if (!g_IsSerialConnectedToRemoteDebuggee) + { + ShowMessages("err, query state of the debuggee is only possible when you connected " + "in debugger mode\n"); + return; + } + + // + // Send the target tasks to the halted cores + // + KdSendTestQueryPacketToDebuggee(TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES); +} + /** * @brief test command for turning on/off the breakpoints * @param State @@ -396,6 +417,13 @@ CommandTest(vector SplittedCommand, string Command) // CommandTestQueryPreAllocPoolsState(); } + else if (SplittedCommand.size() == 2 && !SplittedCommand.at(1).compare("task")) + { + // + // Send target task to the halted cores in debugger mode + // + CommandTestSetTargetTaskToHaltedCores(); + } else if (SplittedCommand.size() == 3 && !SplittedCommand.at(1).compare("breakpoint")) { // diff --git a/hyperdbg/hprdbgkd/code/debugger/core/HaltedCore.c b/hyperdbg/hprdbgkd/code/debugger/core/HaltedCore.c new file mode 100644 index 00000000..3e72eb6f --- /dev/null +++ b/hyperdbg/hprdbgkd/code/debugger/core/HaltedCore.c @@ -0,0 +1,80 @@ +/** + * @file HaltedCore.c + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Implementation of applying events in halted cores + * @details + * + * @version 0.7 + * @date 2023-09-30 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#include "pch.h" + +/** + * @brief Perform the task on halted core + * @details This function should be called from VMX root-mode + * + * @param DbgState The state of the debugger on the current core + * @param TargetTask The target task + * + * @return VOID + */ +VOID +HaltedCorePerformTargetTask(PROCESSOR_DEBUGGING_STATE * DbgState, + UINT32 TargetTask) +{ + // + // Test target task + // + LogInfo("Target task executed: %x", TargetTask); +} + +/** + * @brief Broadcast tasks to halted cores + * @details This function should be called from VMX root-mode + * + * @param DbgState The state of the debugger on the current core + * @param TargetTask The target task + * @param LockAgainAfterTask Lock the core after the task + * + * @return VOID + */ +VOID +HaltedCoreBroadcasTaskToAllCores(PROCESSOR_DEBUGGING_STATE * DbgState, + UINT32 TargetTask, + BOOLEAN LockAgainAfterTask) +{ + ULONG CoreCount; + + CoreCount = KeQueryActiveProcessorCount(0); + + // + // Apply the task to all cores except current core + // + for (size_t i = 0; i < CoreCount; i++) + { + if (DbgState->CoreId != i) + { + // + // Activate running the halted task + // + g_DbgState[i].HaltedCoreTask.PerformHaltedTask = TRUE; + + g_DbgState[i].HaltedCoreTask.KernelStatus = NULL; + g_DbgState[i].HaltedCoreTask.LockAgainAfterTask = LockAgainAfterTask; + g_DbgState[i].HaltedCoreTask.TargetTask = TargetTask; + + // + // Unlock halted core + // + KdUnlockTheHaltedCore(&g_DbgState[i]); + } + } + + // + // Perform the task for the current core + // + HaltedCorePerformTargetTask(DbgState, TargetTask); +} diff --git a/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c b/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c index 3b59a074..446e9c87 100644 --- a/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c +++ b/hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c @@ -1277,7 +1277,6 @@ KdHandleNmi(PROCESSOR_DEBUGGING_STATE * DbgState) // // Test // - // LogInfo("NMI Arrived on : %d \n",CurrentProcessorIndex); // @@ -1621,6 +1620,19 @@ KdQuerySystemState() } } +/** + * @brief unlock the target core + * + * @param DbgState The state of the debugger on the current core + * + * @return VOID + */ +VOID +KdUnlockTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState) +{ + SpinlockUnlock(&DbgState->Lock); +} + /** * @brief routines to break page-in * @@ -2193,6 +2205,17 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState) break; + case TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES: + + // + // Send request for the target task to the halted cores + // + HaltedCoreBroadcasTaskToAllCores(DbgState, 0x55, TRUE); + + TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL; + + break; + case TEST_BREAKPOINT_TURN_OFF_BPS: // @@ -2881,6 +2904,7 @@ StartAgain: ScopedSpinlock( DbgState->Lock, + // // Check if it's a change core event or not // @@ -2894,6 +2918,36 @@ StartAgain: } ); + + // + // Check if any task needs to be executed on this core or not + // + if (DbgState->HaltedCoreTask.PerformHaltedTask) + { + // + // Indicate that the halted core is no longer needed to execute a task + // as the current task is executed once + // + DbgState->HaltedCoreTask.PerformHaltedTask = FALSE; + + // + // Perform the target task + // + HaltedCorePerformTargetTask(DbgState, DbgState->HaltedCoreTask.TargetTask); + + // + // Check if the core needs to be locked again + // + if (DbgState->HaltedCoreTask.LockAgainAfterTask) + { + // + // Lock again + // + SpinlockLock(&DbgState->Lock); + + goto StartAgain; + } + } } // diff --git a/hyperdbg/hprdbgkd/header/debugger/core/HaltedCore.h b/hyperdbg/hprdbgkd/header/debugger/core/HaltedCore.h new file mode 100644 index 00000000..95543245 --- /dev/null +++ b/hyperdbg/hprdbgkd/header/debugger/core/HaltedCore.h @@ -0,0 +1,25 @@ +/** + * @file HaltedCore.h + * @author Sina Karvandi (sina@hyperdbg.org) + * @brief Header for the implementation of applying events in halted cores + * @details + * @version 0.7 + * @date 2023-09-30 + * + * @copyright This project is released under the GNU Public License v3. + * + */ +#pragma once + +////////////////////////////////////////////////// +// Functions // +////////////////////////////////////////////////// + +VOID +HaltedCorePerformTargetTask(PROCESSOR_DEBUGGING_STATE * DbgState, + UINT32 TargetTask); + +VOID +HaltedCoreBroadcasTaskToAllCores(PROCESSOR_DEBUGGING_STATE * DbgState, + UINT32 TargetTask, + BOOLEAN LockAgainAfterTask); diff --git a/hyperdbg/hprdbgkd/header/debugger/core/State.h b/hyperdbg/hprdbgkd/header/debugger/core/State.h index 74c4f8d9..8566e50a 100644 --- a/hyperdbg/hprdbgkd/header/debugger/core/State.h +++ b/hyperdbg/hprdbgkd/header/debugger/core/State.h @@ -129,6 +129,19 @@ typedef struct _DEBUGGER_TRAP_FLAG_STATE } DEBUGGER_TRAP_FLAG_STATE, *PDEBUGGER_TRAP_FLAG_STATE; +/** + * @brief Details of setting tasks for the locked (halted) cores + * + */ +typedef struct _DEBUGGEE_HALTED_CORE_TASK +{ + BOOLEAN PerformHaltedTask; + BOOLEAN LockAgainAfterTask; + UINT32 TargetTask; + UINT64 KernelStatus; + +} DEBUGGEE_HALTED_CORE_TASK, *PDEBUGGEE_HALTED_CORE_TASK; + /** * @brief Saves the debugger state * @details Each logical processor contains one of this structure which describes about the @@ -149,6 +162,7 @@ typedef struct _PROCESSOR_DEBUGGING_STATE BOOLEAN DoNotNmiNotifyOtherCoresByThisCore; DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails; KD_NMI_STATE NmiState; + DEBUGGEE_HALTED_CORE_TASK HaltedCoreTask; BOOLEAN BreakStarterCore; UINT16 InstructionLengthHint; UINT64 HardwareDebugRegisterForStepping; diff --git a/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h b/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h index eb6b9741..f8ec6def 100644 --- a/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h +++ b/hyperdbg/hprdbgkd/header/debugger/kernel-level/Kd.h @@ -227,6 +227,9 @@ KdIsGuestOnUsermode32Bit(); VOID KdHandleNmiBroadcastDebugBreaks(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler); +VOID +KdUnlockTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState); + BOOLEAN KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(UINT32 CoreId, DEBUGGER_THREAD_PROCESS_TRACING TracingType); diff --git a/hyperdbg/hprdbgkd/header/pch.h b/hyperdbg/hprdbgkd/header/pch.h index d9c40394..0c313365 100644 --- a/hyperdbg/hprdbgkd/header/pch.h +++ b/hyperdbg/hprdbgkd/header/pch.h @@ -111,6 +111,7 @@ #include "header/debugger/user-level/ThreadHolder.h" #include "header/debugger/broadcast/DpcRoutines.h" #include "header/debugger/core/DebuggerVmcalls.h" +#include "header/debugger/core/HaltedCore.h" // // DPC Headers diff --git a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj b/hyperdbg/hprdbgkd/hprdbgkd.vcxproj index d3045f2a..af1ed233 100644 --- a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj +++ b/hyperdbg/hprdbgkd/hprdbgkd.vcxproj @@ -120,6 +120,7 @@ + @@ -154,6 +155,7 @@ + diff --git a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters b/hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters index 80bb22d0..d7e96fba 100644 --- a/hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters +++ b/hyperdbg/hprdbgkd/hprdbgkd.vcxproj.filters @@ -222,6 +222,9 @@ code\components\optimizations + + code\debugger\core + @@ -329,6 +332,9 @@ header\components\optimizations + + header\debugger\core + diff --git a/hyperdbg/include/SDK/Headers/Constants.h b/hyperdbg/include/SDK/Headers/Constants.h index 50410b62..2172c6b6 100644 --- a/hyperdbg/include/SDK/Headers/Constants.h +++ b/hyperdbg/include/SDK/Headers/Constants.h @@ -17,7 +17,7 @@ ////////////////////////////////////////////////// #define VERSION_MAJOR 0 -#define VERSION_MINOR 6 +#define VERSION_MINOR 7 #define VERSION_PATCH 0 // diff --git a/hyperdbg/include/SDK/Headers/RequestStructures.h b/hyperdbg/include/SDK/Headers/RequestStructures.h index 9c424c7d..40f7b0c9 100644 --- a/hyperdbg/include/SDK/Headers/RequestStructures.h +++ b/hyperdbg/include/SDK/Headers/RequestStructures.h @@ -266,11 +266,12 @@ typedef struct _DEBUGGER_FLUSH_LOGGING_BUFFERS */ typedef enum _DEBUGGER_TEST_QUERY_STATE { - TEST_QUERY_HALTING_CORE_STATUS = 1, // Query constant to show detail of halting of core - TEST_QUERY_PREALLOCATED_POOL_STATE = 2, // Query pre-allocated pool state - TEST_QUERY_TRAP_STATE = 3, // Query trap state - TEST_BREAKPOINT_TURN_OFF_BPS = 4, // Turn off the breakpoints - TEST_BREAKPOINT_TURN_ON_BPS = 5, // Turn on the breakpoints + TEST_QUERY_HALTING_CORE_STATUS = 1, // Query constant to show detail of halting of core + TEST_QUERY_PREALLOCATED_POOL_STATE = 2, // Query pre-allocated pool state + TEST_QUERY_TRAP_STATE = 3, // Query trap state + TEST_BREAKPOINT_TURN_OFF_BPS = 4, // Turn off the breakpoints + TEST_BREAKPOINT_TURN_ON_BPS = 5, // Turn on the breakpoints + TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES = 6, // For test purposes } DEBUGGER_TEST_QUERY_STATE;