Merge pull request #283 from HyperDbg/instant-event2

Instant event2
This commit is contained in:
Sina Karvandi 2023-10-11 12:44:03 +09:00 committed by GitHub
commit b57b886cb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 758 additions and 285 deletions

View file

@ -332,11 +332,12 @@ CommandTestQueryPreAllocPoolsState()
/**
* @brief test command for setting target tasks to halted cores
* @param Synchronous
*
* @return VOID
*/
VOID
CommandTestSetTargetTaskToHaltedCores()
CommandTestSetTargetTaskToHaltedCores(BOOLEAN Synchronous)
{
if (!g_IsSerialConnectedToRemoteDebuggee)
{
@ -348,7 +349,29 @@ CommandTestSetTargetTaskToHaltedCores()
//
// Send the target tasks to the halted cores
//
KdSendTestQueryPacketToDebuggee(TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES);
KdSendTestQueryPacketToDebuggee(Synchronous ? TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_SYNCHRONOUS : TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_ASYNCHRONOUS);
}
/**
* @brief test command for setting target task to the specified core
* @param CoreNumber
*
* @return VOID
*/
VOID
CommandTestSetTargetTaskToTargetCore(UINT32 CoreNumber)
{
if (!g_IsSerialConnectedToRemoteDebuggee)
{
ShowMessages("err, query state of the debuggee is only possible when you connected "
"in debugger mode\n");
return;
}
//
// Send the target task to the target halted core
//
KdSendTestQueryPacketWithContextToDebuggee(TEST_SETTING_TARGET_TASKS_ON_TARGET_HALTED_CORES, (UINT64)CoreNumber);
}
/**
@ -389,6 +412,8 @@ CommandTestSetBreakpointState(BOOLEAN State)
VOID
CommandTest(vector<string> SplittedCommand, string Command)
{
UINT64 Context = NULL;
if (SplittedCommand.size() == 1)
{
//
@ -417,12 +442,32 @@ CommandTest(vector<string> SplittedCommand, string Command)
//
CommandTestQueryPreAllocPoolsState();
}
else if (SplittedCommand.size() == 2 && !SplittedCommand.at(1).compare("task"))
else if (SplittedCommand.size() == 2 && !SplittedCommand.at(1).compare("sync-task"))
{
//
// Send target task to the halted cores in debugger mode
// Send target task to the halted cores in debugger mode (synchronous)
//
CommandTestSetTargetTaskToHaltedCores();
CommandTestSetTargetTaskToHaltedCores(TRUE);
}
else if (SplittedCommand.size() == 2 && !SplittedCommand.at(1).compare("async-task"))
{
//
// Send target task to the halted cores in debugger mode (asynchronous)
//
CommandTestSetTargetTaskToHaltedCores(FALSE);
}
else if (SplittedCommand.size() == 3 && !SplittedCommand.at(1).compare("target-core-task"))
{
if (!ConvertStringToUInt64(SplittedCommand.at(2), &Context))
{
ShowMessages("err, you should enter a valid hex number as the core id\n\n");
return;
}
//
// Send target task to the specific halted core in debugger mode
//
CommandTestSetTargetTaskToTargetCore((UINT32)Context);
}
else if (SplittedCommand.size() == 3 && !SplittedCommand.at(1).compare("breakpoint"))
{

View file

@ -391,6 +391,13 @@ ShowErrorMessage(UINT32 Error)
Error);
break;
case DEBUGGER_ERROR_PROCESS_ID_CANNOT_BE_SPECIFIED_WHILE_APPLYING_EVENT_FROM_VMX_ROOT_MODE:
ShowMessages("err, you cannot specify process id while the debugger is paused in the debugger mode. "
"You can use the '.process' or the '.thread' command to switch to the target process's "
"memory layout (%x)\n",
Error);
break;
default:
ShowMessages("err, error not found (%x)\n",
Error);

View file

@ -417,6 +417,7 @@ KdSendCallStackPacketToDebuggee(UINT64 BaseAddress,
* @brief Send a test query request to the debuggee
*
* @param Type
*
* @return BOOLEAN
*/
BOOLEAN
@ -446,6 +447,42 @@ KdSendTestQueryPacketToDebuggee(DEBUGGER_TEST_QUERY_STATE Type)
return TRUE;
}
/**
* @brief Send a test query request to the debuggee with the specified context
*
* @param Type
* @param Context
*
* @return BOOLEAN
*/
BOOLEAN
KdSendTestQueryPacketWithContextToDebuggee(DEBUGGER_TEST_QUERY_STATE Type, UINT64 Context)
{
DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER TestQueryPacket = {0};
TestQueryPacket.RequestType = Type;
TestQueryPacket.Context = Context;
//
// Send 'test query' command as query packet
//
if (!KdCommandPacketAndBufferToDebuggee(
DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_TEST_QUERY,
(CHAR *)&TestQueryPacket,
sizeof(DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER)))
{
return FALSE;
}
//
// Wait until the result of test query is received
//
DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_TEST_QUERY);
return TRUE;
}
/**
* @brief Send symbol reload packet to the debuggee
*

View file

@ -121,6 +121,9 @@ KdSendCallStackPacketToDebuggee(UINT64 BaseAddress,
BOOLEAN
KdSendTestQueryPacketToDebuggee(DEBUGGER_TEST_QUERY_STATE Type);
BOOLEAN
KdSendTestQueryPacketWithContextToDebuggee(DEBUGGER_TEST_QUERY_STATE Type, UINT64 Context);
BOOLEAN
KdSendSymbolReloadPacketToDebuggee(UINT32 ProcessId);

View file

@ -243,3 +243,27 @@ CommonKillProcess(UINT32 ProcessId, PROCESS_KILL_METHODS KillingMethod)
//
return TRUE;
}
/**
* @brief Validate core number
* @param CoreNumber
*
* @return BOOLEAN
*/
_Use_decl_annotations_
BOOLEAN
CommonValidateCoreNumber(UINT32 CoreNumber)
{
ULONG CoreCount;
CoreCount = KeQueryActiveProcessorCount(0);
if (CoreNumber >= CoreCount)
{
return FALSE;
}
else
{
return TRUE;
}
}

View file

@ -835,7 +835,6 @@ BOOLEAN
BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
{
PDEBUGGEE_BP_DESCRIPTOR BreakpointDescriptor = NULL;
UINT32 ProcessorCount;
CR3_TYPE GuestCr3;
BOOLEAN IsAddress32Bit = FALSE;
@ -860,10 +859,8 @@ BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg)
//
// Check if the core number is not invalid
//
ProcessorCount = KeQueryActiveProcessorCount(0);
if (BpDescriptorArg->Core != DEBUGGEE_BP_APPLY_TO_ALL_CORES &&
BpDescriptorArg->Core >= ProcessorCount)
!CommonValidateCoreNumber(BpDescriptorArg->Core))
{
//
// Core is invalid (Set the error)

View file

@ -2105,33 +2105,24 @@ DebuggerRemoveEvent(UINT64 Tag)
}
/**
* @brief Routine for validating and parsing events
* that came from user-mode
* @brief validating events
*
* @param EventDetails The structure that describes event that came
* from the user-mode
* from the user-mode or VMX-root mode
* @param BufferLength Length of the buffer
* @param ResultsToReturnUsermode Result buffer that should be returned to
* @param ResultsToReturn Result buffer that should be returned to
* the user-mode
* @return BOOLEAN TRUE if the event was valid an regisered without error,
* otherwise returns FALSE
* @param InputFromVmxRoot Whether the input comes from VMX root-mode or IOCTL
*
* @return BOOLEAN TRUE if the event was valid otherwise returns FALSE
*/
BOOLEAN
DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturnUsermode)
DebuggerValidateEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
UINT32 BufferLength,
PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn,
BOOLEAN InputFromVmxRoot)
{
PDEBUGGER_EVENT Event;
UINT64 PagesBytes;
UINT32 TempPid;
UINT32 ProcessorCount;
BOOLEAN ResultOfApplyingEvent = FALSE;
ProcessorCount = KeQueryActiveProcessorCount(0);
//
// ----------------------------------------------------------------------------------
// *** Validating the Event's parameters ***
// ----------------------------------------------------------------------------------
//
UINT32 TempPid;
//
// Check whether the event mode (calling stage) to see whether
@ -2143,8 +2134,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
EventDetails->EventStage == VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION) &&
EventDetails->EnableShortCircuiting == TRUE)
{
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_USING_SHORT_CIRCUITING_EVENT_WITH_POST_EVENT_MODE_IS_FORBIDDEDN;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_USING_SHORT_CIRCUITING_EVENT_WITH_POST_EVENT_MODE_IS_FORBIDDEDN;
return FALSE;
}
@ -2157,14 +2148,14 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
//
// Check if the core number is not invalid
//
if (EventDetails->CoreId >= ProcessorCount)
if (!CommonValidateCoreNumber(EventDetails->CoreId))
{
//
// CoreId is invalid (Set the error)
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_CORE_ID;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_CORE_ID;
return FALSE;
}
}
@ -2176,13 +2167,19 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
if (EventDetails->ProcessId != DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES && EventDetails->ProcessId != 0)
{
//
// The used specified a special pid, let's check if it's valid or not
// Here we prefer not to validate the process id, if it's applied from VMX-root mode
//
if (!CommonIsProcessExist(EventDetails->ProcessId))
if (!InputFromVmxRoot)
{
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_PROCESS_ID;
return FALSE;
//
// The used specified a special pid, let's check if it's valid or not
//
if (!CommonIsProcessExist(EventDetails->ProcessId))
{
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_PROCESS_ID;
return FALSE;
}
}
}
@ -2199,8 +2196,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
// more than 32 indexes we should use pin-based external interrupt
// exiting which is completely different
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_EXCEPTION_INDEX_EXCEED_FIRST_32_ENTRIES;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_EXCEPTION_INDEX_EXCEED_FIRST_32_ENTRIES;
return FALSE;
}
}
@ -2215,8 +2212,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
// The IDT Entry is either invalid or is not in the range
// of the pin-based external interrupt exiting controls
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INTERRUPT_INDEX_IS_NOT_VALID;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INTERRUPT_INDEX_IS_NOT_VALID;
return FALSE;
}
}
@ -2232,8 +2229,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
//
// The execution mode is not correctly applied
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_MODE_EXECUTION_IS_INVALID;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_MODE_EXECUTION_IS_INVALID;
return FALSE;
}
}
@ -2243,21 +2240,55 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
// First check if the address are valid
//
TempPid = EventDetails->ProcessId;
if (TempPid == DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES)
{
TempPid = PsGetCurrentProcessId();
}
if (VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam1, TempPid) == NULL)
//
// Check if input is coming from VMX-root or not
// If it's coming from VMX-root, then as switching
// to another process is not possible, we'll return
// an error
//
if (InputFromVmxRoot && TempPid != PsGetCurrentProcessId())
{
//
// Address is invalid (Set the error)
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_PROCESS_ID_CANNOT_BE_SPECIFIED_WHILE_APPLYING_EVENT_FROM_VMX_ROOT_MODE;
return FALSE;
}
//
// Check whether address is valid or not based on whether the event needs
// to be applied directly from VMX-root mode or not
//
if (InputFromVmxRoot)
{
if (VirtualAddressToPhysicalAddressOnTargetProcess(EventDetails->OptionalParam1) == NULL)
{
//
// Address is invalid (Set the error)
//
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
}
else
{
if (VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam1, TempPid) == NULL)
{
//
// Address is invalid (Set the error)
//
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
}
}
else if (EventDetails->EventType == HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE ||
EventDetails->EventType == HIDDEN_HOOK_READ_AND_WRITE ||
@ -2276,92 +2307,90 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
TempPid = PsGetCurrentProcessId();
}
if (VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam1, TempPid) == NULL || VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam2, TempPid) == NULL)
//
// Check if input is coming from VMX-root or not
// If it's coming from VMX-root, then as switching
// to another process is not possible, we'll return
// an error
//
if (InputFromVmxRoot && TempPid != PsGetCurrentProcessId())
{
//
// Address is invalid (Set the error)
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_PROCESS_ID_CANNOT_BE_SPECIFIED_WHILE_APPLYING_EVENT_FROM_VMX_ROOT_MODE;
return FALSE;
}
//
// Check whether address is valid or not based on whether the event needs
// to be applied directly from VMX-root mode or not
//
if (InputFromVmxRoot)
{
if (VirtualAddressToPhysicalAddressOnTargetProcess(EventDetails->OptionalParam1) == NULL ||
VirtualAddressToPhysicalAddressOnTargetProcess(EventDetails->OptionalParam2) == NULL)
{
//
// Address is invalid (Set the error)
//
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
}
else
{
if (VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam1, TempPid) == NULL ||
VirtualAddressToPhysicalAddressByProcessId(EventDetails->OptionalParam2, TempPid) == NULL)
{
//
// Address is invalid (Set the error)
//
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
}
//
// Check if the 'to' is greater that 'from'
//
if (EventDetails->OptionalParam1 >= EventDetails->OptionalParam2)
{
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ADDRESS;
return FALSE;
}
}
//
// ----------------------------------------------------------------------------------
// Create Event
// ----------------------------------------------------------------------------------
// As we reached, all the checks are passed and it means the event is valid
//
return TRUE;
}
//
// We initialize event with disabled mode as it doesn't have action yet
//
if (EventDetails->ConditionBufferSize != 0)
{
//
// Conditional Event
//
Event = DebuggerCreateEvent(FALSE,
EventDetails->CoreId,
EventDetails->ProcessId,
EventDetails->EventType,
EventDetails->Tag,
EventDetails->OptionalParam1,
EventDetails->OptionalParam2,
EventDetails->OptionalParam3,
EventDetails->OptionalParam4,
EventDetails->ConditionBufferSize,
(UINT64)EventDetails + sizeof(DEBUGGER_GENERAL_EVENT_DETAIL));
}
else
{
//
// Unconditional Event
//
Event = DebuggerCreateEvent(FALSE,
EventDetails->CoreId,
EventDetails->ProcessId,
EventDetails->EventType,
EventDetails->Tag,
EventDetails->OptionalParam1,
EventDetails->OptionalParam2,
EventDetails->OptionalParam3,
EventDetails->OptionalParam4,
0,
NULL);
}
if (Event == NULL)
{
//
// Set the error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_UNABLE_TO_CREATE_EVENT;
return FALSE;
}
//
// Register the event
//
DebuggerRegisterEvent(Event);
//
// ----------------------------------------------------------------------------------
// Apply & Enable Event
// ----------------------------------------------------------------------------------
//
/**
* @brief Applying events
*
* @param EventDetails The structure that describes event that came
* from the user-mode or VMX-root mode
* @param BufferLength Length of the buffer
* @param ResultsToReturn Result buffer that should be returned to
* the user-mode
* @param InputFromVmxRoot Whether the input comes from VMX root-mode or IOCTL
*
* @return BOOLEAN TRUE if the event was applied otherwise returns FALSE
*/
BOOLEAN
DebuggerApplyEvent(PDEBUGGER_EVENT Event,
PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
UINT32 BufferLength,
PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn,
BOOLEAN InputFromVmxRoot)
{
UINT64 PagesBytes;
BOOLEAN ResultOfApplyingEvent = FALSE;
//
// Now we should configure the cpu to generate the events
@ -2447,8 +2476,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
default:
LogError("Err, Invalid monitor hook type");
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID;
goto ClearTheEventAfterCreatingEvent;
@ -2500,8 +2529,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
//
if (!ResultOfApplyingEvent)
{
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DebuggerGetLastError();
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DebuggerGetLastError();
goto ClearTheEventAfterCreatingEvent;
}
@ -2528,8 +2557,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
// There was an error applying this event, so we're setting
// the event
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DebuggerGetLastError();
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DebuggerGetLastError();
goto ClearTheEventAfterCreatingEvent;
}
@ -2561,8 +2590,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
// There was an error applying this event, so we're setting
// the event
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DebuggerGetLastError();
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DebuggerGetLastError();
goto ClearTheEventAfterCreatingEvent;
}
@ -3011,8 +3040,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
//
// Set the error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID;
goto ClearTheEventAfterCreatingEvent;
break;
@ -3046,8 +3075,8 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
//
// Set the status
//
ResultsToReturnUsermode->IsSuccessful = TRUE;
ResultsToReturnUsermode->Error = 0;
ResultsToReturn->IsSuccessful = TRUE;
ResultsToReturn->Error = 0;
//
// Event was applied successfully
@ -3056,15 +3085,127 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
ClearTheEventAfterCreatingEvent:
return FALSE;
}
/**
* @brief Routine for parsing events
*
* @param EventDetails The structure that describes event that came
* from the user-mode
* @param BufferLength Length of the buffer
* @param ResultsToReturn Result buffer that should be returned to
* the user-mode
* @param InputFromVmxRoot Whether the input comes from VMX root-mode or IOCTL
*
* @return BOOLEAN TRUE if the event was valid an regisered without error,
* otherwise returns FALSE
*/
BOOLEAN
DebuggerParseEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
UINT32 BufferLength,
PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn,
BOOLEAN InputFromVmxRoot)
{
PDEBUGGER_EVENT Event;
//
// Remove the event as it was not successfull
// ----------------------------------------------------------------------------------
// *** Validating the Event's parameters ***
// ----------------------------------------------------------------------------------
//
if (Event != NULL)
//
// Validate the event parameters
//
if (!DebuggerValidateEvent(EventDetails, BufferLength, ResultsToReturn, InputFromVmxRoot))
{
DebuggerRemoveEvent(Event->Tag);
//
// Input event is not valid
//
return FALSE;
}
return FALSE;
//
// ----------------------------------------------------------------------------------
// *** Create Event ***
// ----------------------------------------------------------------------------------
//
//
// We initialize event with disabled mode as it doesn't have action yet
//
if (EventDetails->ConditionBufferSize != 0)
{
//
// Conditional Event
//
Event = DebuggerCreateEvent(FALSE,
EventDetails->CoreId,
EventDetails->ProcessId,
EventDetails->EventType,
EventDetails->Tag,
EventDetails->OptionalParam1,
EventDetails->OptionalParam2,
EventDetails->OptionalParam3,
EventDetails->OptionalParam4,
EventDetails->ConditionBufferSize,
(UINT64)EventDetails + sizeof(DEBUGGER_GENERAL_EVENT_DETAIL));
}
else
{
//
// Unconditional Event
//
Event = DebuggerCreateEvent(FALSE,
EventDetails->CoreId,
EventDetails->ProcessId,
EventDetails->EventType,
EventDetails->Tag,
EventDetails->OptionalParam1,
EventDetails->OptionalParam2,
EventDetails->OptionalParam3,
EventDetails->OptionalParam4,
0,
NULL);
}
if (Event == NULL)
{
//
// Set the error
//
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_UNABLE_TO_CREATE_EVENT;
return FALSE;
}
//
// Register the event
//
DebuggerRegisterEvent(Event);
//
// ----------------------------------------------------------------------------------
// *** Apply & Enable Event ***
// ----------------------------------------------------------------------------------
//
if (DebuggerApplyEvent(Event, EventDetails, BufferLength, ResultsToReturn, InputFromVmxRoot))
{
return TRUE;
}
else
{
//
// Remove the event as it was not successfull
//
if (Event != NULL)
{
DebuggerRemoveEvent(Event->Tag);
}
return FALSE;
}
}
/**
@ -3075,13 +3216,13 @@ ClearTheEventAfterCreatingEvent:
* @param Action Structure that describes the action that comes from the
* user-mode
* @param BufferLength Length of the buffer that comes from user-mode
* @param ResultsToReturnUsermode The buffer address that should be returned
* @param ResultsToReturn The buffer address that should be returned
* to the user-mode as the result
* @return BOOLEAN if action was parsed and added successfully, return TRUE
* otherwise, returns FALSE
*/
BOOLEAN
DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturnUsermode)
DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn)
{
//
// Check if Tag is valid or not
@ -3093,8 +3234,8 @@ DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLe
//
// Set the appropriate error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_TAG_NOT_EXISTS;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_TAG_NOT_EXISTS;
//
// Show that the
@ -3112,8 +3253,8 @@ DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLe
//
// Set the appropriate error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO;
//
// Show that the
@ -3150,8 +3291,8 @@ DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLe
//
// Set the appropriate error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO;
//
// Show that the
@ -3192,8 +3333,8 @@ DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLe
//
// Set the appropriate error
//
ResultsToReturnUsermode->IsSuccessful = FALSE;
ResultsToReturnUsermode->Error = DEBUGGER_ERROR_INVALID_ACTION_TYPE;
ResultsToReturn->IsSuccessful = FALSE;
ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ACTION_TYPE;
//
// Show that the
@ -3201,8 +3342,8 @@ DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLe
return FALSE;
}
ResultsToReturnUsermode->IsSuccessful = TRUE;
ResultsToReturnUsermode->Error = 0;
ResultsToReturn->IsSuccessful = TRUE;
ResultsToReturn->Error = 0;
return TRUE;
}

View file

@ -32,24 +32,108 @@ HaltedCorePerformTargetTask(PROCESSOR_DEBUGGING_STATE * DbgState,
}
/**
* @brief Broadcast tasks to halted cores
* @brief Run the task on a single halted core
* @details This function should be called from VMX root-mode
*
* @param DbgState The state of the debugger on the current core
* @param TargetCoreId The target core's ID (to just run on this 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)
HaltedCoreApplyTaskOnTargetCore(UINT32 TargetCoreId,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask)
{
PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[TargetCoreId];
//
// Activate running the halted task
//
DbgState->HaltedCoreTask.PerformHaltedTask = TRUE;
DbgState->HaltedCoreTask.KernelStatus = NULL;
DbgState->HaltedCoreTask.LockAgainAfterTask = LockAgainAfterTask;
DbgState->HaltedCoreTask.TargetTask = TargetTask;
//
// Unlock halted core
//
KdUnlockTheHaltedCore(DbgState);
}
/**
* @brief Run the task on a single halted core
* @details This function should be called from VMX root-mode
*
* @param TargetCoreId The target core's ID (to just run on this core)
* @param TargetTask The target task
* @param LockAgainAfterTask Lock the core after the task
*
* @return VOID
*/
VOID
HaltedCoreRunTaskOnSingleCore(UINT32 TargetCoreId,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask)
{
//
// Check if the task needs to be executed for the current
// core or any other cores
//
if (TargetCoreId == KeGetCurrentProcessorNumberEx(NULL))
{
//
// *** Perform the task for the current core ***
//
HaltedCorePerformTargetTask(&g_DbgState[TargetCoreId], TargetTask);
}
else
{
//
// *** Perform the task for another core ***
//
//
// apply task to the target core
//
HaltedCoreApplyTaskOnTargetCore(TargetCoreId, TargetTask, LockAgainAfterTask);
}
}
/**
* @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
* @param Synchronize Whether the function should wait for all cores to synchronize
* and lock again or not
*
* @return BOOLEAN
*/
BOOLEAN
HaltedCoreBroadcastTaskAllCores(PROCESSOR_DEBUGGING_STATE * DbgState,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask,
BOOLEAN Synchronize)
{
ULONG CoreCount;
CoreCount = KeQueryActiveProcessorCount(0);
//
// Synchronization is not possible when the locking after the task is
// not expected
//
if (Synchronize && !LockAgainAfterTask)
{
LogWarning("Synchronization is not possible when the locking after the task is not expected");
return FALSE;
}
//
// Apply the task to all cores except current core
//
@ -58,23 +142,53 @@ HaltedCoreBroadcasTaskToAllCores(PROCESSOR_DEBUGGING_STATE * DbgState,
if (DbgState->CoreId != i)
{
//
// Activate running the halted task
// apply task to the target core
//
g_DbgState[i].HaltedCoreTask.PerformHaltedTask = TRUE;
g_DbgState[i].HaltedCoreTask.KernelStatus = NULL;
g_DbgState[i].HaltedCoreTask.LockAgainAfterTask = LockAgainAfterTask;
g_DbgState[i].HaltedCoreTask.TargetTask = TargetTask;
HaltedCoreApplyTaskOnTargetCore(i, TargetTask, LockAgainAfterTask);
}
else
{
//
// Unlock halted core
// Perform the task for the current core
//
KdUnlockTheHaltedCore(&g_DbgState[i]);
HaltedCorePerformTargetTask(DbgState, TargetTask);
}
}
//
// Perform the task for the current core
// If synchronization is expected, we need to check to make sure
// all cores are synchronized (locked) at this point or not
//
HaltedCorePerformTargetTask(DbgState, TargetTask);
if (Synchronize)
{
for (size_t i = 0; i < CoreCount; i++)
{
if (DbgState->CoreId != i)
{
//
// Wait until the core is locked again
//
while (TRUE)
{
//
// Keep checking to make sure the target core finished the
// execution its task and locked again
//
if (KdCheckTheHaltedCore(&g_DbgState[i]) == FALSE)
{
continue;
}
else
{
break;
}
}
}
}
}
//
// All cores locked again
//
return TRUE;
}

View file

@ -1591,7 +1591,7 @@ KdQuerySystemState()
for (size_t i = 0; i < CoreCount; i++)
{
if (g_DbgState[i].Lock)
if (SpinlockCheckLock(&g_DbgState[i].Lock))
{
LogInfo("Core : %d is locked", i);
}
@ -1623,7 +1623,7 @@ KdQuerySystemState()
/**
* @brief unlock the target core
*
* @param DbgState The state of the debugger on the current core
* @param DbgState The state of the debugger on the target core
*
* @return VOID
*/
@ -1633,6 +1633,19 @@ KdUnlockTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState)
SpinlockUnlock(&DbgState->Lock);
}
/**
* @brief check the lock state of the target core
*
* @param DbgState The state of the debugger on the target core
*
* @return BOOLEAN
*/
BOOLEAN
KdCheckTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState)
{
return SpinlockCheckLock(&DbgState->Lock);
}
/**
* @brief routines to break page-in
*
@ -1680,6 +1693,150 @@ KdBringPagein(PROCESSOR_DEBUGGING_STATE * DbgState,
}
}
/**
* @brief Perform the test packet's operation
*
* @param DbgState The state of the debugger on the current core
* @param TestQueryPacket test packet request
*
* @return VOID
*/
VOID
KdPerformTheTestPacketOperation(PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER * TestQueryPacket)
{
//
// Dispatch the request
//
switch (TestQueryPacket->RequestType)
{
case TEST_QUERY_HALTING_CORE_STATUS:
//
// Query state of the system
//
KdQuerySystemState();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_QUERY_TRAP_STATE:
//
// Query state of the trap
//
KdQueryRflagTrapState();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_QUERY_PREALLOCATED_POOL_STATE:
//
// Query state of pre-allocated pools
//
PoolManagerShowPreAllocatedPools();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_SYNCHRONOUS:
case TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_ASYNCHRONOUS:
//
// Send request for the target task to the halted cores (synchronized and unsynchronized)
//
HaltedCoreBroadcastTaskAllCores(DbgState,
0x55,
TRUE,
TestQueryPacket->RequestType == TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_SYNCHRONOUS ? TRUE : FALSE);
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_SETTING_TARGET_TASKS_ON_TARGET_HALTED_CORES:
//
// Validate core number
//
if (!CommonValidateCoreNumber(TestQueryPacket->Context))
{
//
// Core number is invalid
//
TestQueryPacket->KernelStatus = DEBUGGER_ERROR_INVALID_CORE_ID;
}
else
{
//
// Send request for the target task to the target halted core
//
HaltedCoreRunTaskOnSingleCore((UINT32)TestQueryPacket->Context, 0x8585, TRUE);
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
}
break;
case TEST_BREAKPOINT_TURN_OFF_BPS:
//
// Turn off the breakpoint interception
//
g_InterceptBreakpoints = TRUE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_ON_BPS:
//
// Turn on the breakpoint interception
//
g_InterceptBreakpoints = FALSE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER:
//
// Turn off the breakpoints and events interception before executing the commands in the remote computer
//
g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer = TRUE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER:
//
// Turn on the breakpoints and events interception after finishing the commands in the remote computer
//
g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer = FALSE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
default:
//
// Query index not found
//
TestQueryPacket->KernelStatus = DEBUGGER_ERROR_UNKNOWN_TEST_QUERY_RECEIVED;
break;
}
}
/**
* @brief Perform modify the state of short-circuiting
*
@ -2168,107 +2325,9 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
TestQueryPacket = (DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
//
// Dispatch the request
// Perform the test packet operation
//
switch (TestQueryPacket->RequestType)
{
case TEST_QUERY_HALTING_CORE_STATUS:
//
// Query state of the system
//
KdQuerySystemState();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_QUERY_TRAP_STATE:
//
// Query state of the trap
//
KdQueryRflagTrapState();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_QUERY_PREALLOCATED_POOL_STATE:
//
// Query state of pre-allocated pools
//
PoolManagerShowPreAllocatedPools();
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
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:
//
// Turn off the breakpoint interception
//
g_InterceptBreakpoints = TRUE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_ON_BPS:
//
// Turn on the breakpoint interception
//
g_InterceptBreakpoints = FALSE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER:
//
// Turn off the breakpoints and events interception before executing the commands in the remote computer
//
g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer = TRUE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
case TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER:
//
// Turn on the breakpoints and events interception after finishing the commands in the remote computer
//
g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer = FALSE;
TestQueryPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
break;
default:
//
// Query index not found
//
TestQueryPacket->KernelStatus = DEBUGGER_ERROR_UNKNOWN_TEST_QUERY_RECEIVED;
break;
}
KdPerformTheTestPacketOperation(DbgState, TestQueryPacket);
//
// Send the result of query system state to the debuggee

View file

@ -310,11 +310,12 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
//
// Both usermode and to send to usermode and the comming buffer are
// at the same place
// at the same place (not comming from the VMX-root mode)
//
DebuggerParseEventFromUsermode(DebuggerNewEventRequest,
InBuffLength,
(PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER)Irp->AssociatedIrp.SystemBuffer);
DebuggerParseEvent(DebuggerNewEventRequest,
InBuffLength,
(PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER)Irp->AssociatedIrp.SystemBuffer,
FALSE);
Irp->IoStatus.Information = sizeof(DEBUGGER_EVENT_AND_ACTION_REG_BUFFER);
Status = STATUS_SUCCESS;

View file

@ -98,3 +98,6 @@ CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess);
BOOLEAN
CommonKillProcess(UINT32 ProcessId, PROCESS_KILL_METHODS KillingMethod);
BOOLEAN
CommonValidateCoreNumber(UINT32 CoreNumber);

View file

@ -220,10 +220,13 @@ BOOLEAN
DebuggerQueryDebuggerStatus();
BOOLEAN
DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturnUsermode);
DebuggerParseEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
UINT32 BufferLength,
PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn,
BOOLEAN InputFromVmxRoot);
BOOLEAN
DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturnUsermode);
DebuggerParseActionFromUsermode(PDEBUGGER_GENERAL_ACTION Action, UINT32 BufferLength, PDEBUGGER_EVENT_AND_ACTION_REG_BUFFER ResultsToReturn);
BOOLEAN
DebuggerParseEventsModificationFromUsermode(PDEBUGGER_MODIFY_EVENTS DebuggerEventModificationRequest);

View file

@ -20,6 +20,12 @@ HaltedCorePerformTargetTask(PROCESSOR_DEBUGGING_STATE * DbgState,
UINT32 TargetTask);
VOID
HaltedCoreBroadcasTaskToAllCores(PROCESSOR_DEBUGGING_STATE * DbgState,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask);
HaltedCoreRunTaskOnSingleCore(UINT32 TargetCoreId,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask);
BOOLEAN
HaltedCoreBroadcastTaskAllCores(PROCESSOR_DEBUGGING_STATE * DbgState,
UINT32 TargetTask,
BOOLEAN LockAgainAfterTask,
BOOLEAN Synchronize);

View file

@ -230,6 +230,9 @@ KdHandleNmiBroadcastDebugBreaks(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler);
VOID
KdUnlockTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState);
BOOLEAN
KdCheckTheHaltedCore(PROCESSOR_DEBUGGING_STATE * DbgState);
BOOLEAN
KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(UINT32 CoreId,
DEBUGGER_THREAD_PROCESS_TRACING TracingType);

View file

@ -422,6 +422,12 @@
*/
#define DEBUGGER_ERROR_MODE_EXECUTION_IS_INVALID 0xc000003f
/**
* @brief error, the process id cannot be specified while the debugger is in VMX-root mode
*
*/
#define DEBUGGER_ERROR_PROCESS_ID_CANNOT_BE_SPECIFIED_WHILE_APPLYING_EVENT_FROM_VMX_ROOT_MODE 0xc0000040
//
// WHEN YOU ADD ANYTHING TO THIS LIST OF ERRORS, THEN
// MAKE SURE TO ADD AN ERROR MESSAGE TO ShowErrorMessage(UINT32 Error)

View file

@ -266,14 +266,16 @@ 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_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER = 6, // Turn off the breakpoints and events for executing the commands in the remote computer
TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER = 7, // Turn on the breakpoints and events for executing the commands in the remote computer
TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES = 8, // For test purposes
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_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER = 6, // Turn off the breakpoints and events for executing the commands in the remote computer
TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER = 7, // Turn on the breakpoints and events for executing the commands in the remote computer
TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_SYNCHRONOUS = 8, // For testing synchronized event
TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_ASYNCHRONOUS = 9, // For testing unsynchronized event
TEST_SETTING_TARGET_TASKS_ON_TARGET_HALTED_CORES = 10, // Send the task to the halted core
} DEBUGGER_TEST_QUERY_STATE;
@ -284,6 +286,7 @@ typedef enum _DEBUGGER_TEST_QUERY_STATE
typedef struct _DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER
{
DEBUGGER_TEST_QUERY_STATE RequestType;
UINT64 Context;
UINT32 KernelStatus;
} DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER, *PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER;

View file

@ -159,3 +159,21 @@ SpinlockUnlock(volatile LONG * Lock)
{
*Lock = 0;
}
/**
* @brief Check the lock without changing the state
*
* @param LONG Lock variable
*/
BOOLEAN
SpinlockCheckLock(volatile LONG * Lock)
{
if (*Lock)
{
return TRUE;
}
else
{
return FALSE;
}
}

View file

@ -18,6 +18,9 @@
BOOLEAN
SpinlockTryLock(volatile LONG * Lock);
BOOLEAN
SpinlockCheckLock(volatile LONG * Lock);
void
SpinlockLock(volatile LONG * Lock);