mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-09 17:19:26 +00:00
commit
512e7fe290
19 changed files with 1086 additions and 1488 deletions
|
|
@ -45,6 +45,6 @@ object ScriptConstantTypes {
|
|||
|
||||
object ScriptEvalFunc {
|
||||
object ScriptOperators extends ChiselEnum {
|
||||
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncLbr_start, sFuncLbr_stop, sFuncRdtsc, sFuncRdtscp, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
|
||||
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncLbr_save, sFuncLbr_dump, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
|
||||
}
|
||||
}
|
||||
|
|
@ -1500,8 +1500,8 @@ HvGetAndStoreDebugctl(UINT64 * StoreDebugctl)
|
|||
VOID
|
||||
HvSetDebugctl(UINT64 Value)
|
||||
{
|
||||
VmxVmwrite64(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
|
||||
VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
|
||||
VmxVmwrite32(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
|
||||
VmxVmwrite32(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1286,7 +1286,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
//
|
||||
// Perform the HyperTrace operation
|
||||
//
|
||||
HyperTracePerformOperation(HyperTraceOperationRequest, FALSE);
|
||||
HyperTracePerformOperation(HyperTraceOperationRequest, TRUE);
|
||||
|
||||
Irp->IoStatus.Information = SIZEOF_HYPERTRACE_OPERATION_PACKETS;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -23,19 +23,9 @@
|
|||
BOOLEAN
|
||||
DpcRoutineEnableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||
{
|
||||
LBR_IOCTL_REQUEST * CurrentRequest;
|
||||
ULONG CurrentCore;
|
||||
|
||||
UNREFERENCED_PARAMETER(Dpc);
|
||||
UNREFERENCED_PARAMETER(DeferredContext);
|
||||
|
||||
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
|
||||
|
||||
//
|
||||
// Get the current request (for current core)
|
||||
//
|
||||
CurrentRequest = &g_LbrRequestState[CurrentCore];
|
||||
|
||||
//
|
||||
// Check if the initialization is being done for hypervisor environment or not
|
||||
// If it is, then we need to perform some additional steps to enable LBR in VMX
|
||||
|
|
@ -53,8 +43,7 @@ DpcRoutineEnableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PV
|
|||
//
|
||||
// Enable LBR on all cores from VMX-root mode by VMCALL
|
||||
//
|
||||
// LbrStartLbr(CurrentRequest, TRUE, TRUE);
|
||||
HyperTraceExamplePerformLbrTrace(TRUE, TRUE);
|
||||
LbrStartLbr(TRUE, TRUE);
|
||||
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
|
|
@ -81,18 +70,13 @@ DpcRoutineEnableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PV
|
|||
BOOLEAN
|
||||
DpcRoutineDisableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||
{
|
||||
LBR_IOCTL_REQUEST * CurrentRequest;
|
||||
ULONG CurrentCore;
|
||||
|
||||
UNREFERENCED_PARAMETER(Dpc);
|
||||
UNREFERENCED_PARAMETER(DeferredContext);
|
||||
|
||||
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
|
||||
|
||||
//
|
||||
// Get the current request (for current core)
|
||||
// Disable LBR on all cores from VMX-root mode by VMCALL
|
||||
//
|
||||
CurrentRequest = &g_LbrRequestState[CurrentCore];
|
||||
LbrStopLbr(TRUE, TRUE);
|
||||
|
||||
//
|
||||
// Check if the initialization is being done for hypervisor environment or not
|
||||
|
|
@ -108,11 +92,6 @@ DpcRoutineDisableLbr(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, P
|
|||
g_Callbacks.VmFuncSetLoadDebugControlsVmcallOnTargetCore(FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Disable LBR on all cores from VMX-root mode by VMCALL
|
||||
//
|
||||
LbrStopLbr(CurrentRequest, TRUE, TRUE);
|
||||
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@
|
|||
// Global Definitions //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
ULONGLONG LbrCapacity = 0;
|
||||
LIST_ENTRY LbrStateHead;
|
||||
KSPIN_LOCK LbrStateLock;
|
||||
ULONGLONG LbrCapacity = 0;
|
||||
|
||||
//
|
||||
// Typical Intel LBR capacities based on CPU model
|
||||
|
|
@ -82,96 +80,70 @@ CPU_LBR_MAP CPU_LBR_MAPS[] = {
|
|||
{0x36, 8}};
|
||||
|
||||
/**
|
||||
* @brief Initialize LBR state list and spinlock
|
||||
*
|
||||
* @param State
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrInitialize()
|
||||
{
|
||||
InitializeListHead(&LbrStateHead);
|
||||
KeInitializeSpinLock(&LbrStateLock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read LBR MSRs and store the values in the provided LBR_STATE structure
|
||||
*
|
||||
* @param State
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
* @brief Flush LBR MSRs by disabling LBR and clearing all LBR entries
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrGetLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
LbrFlushLbr()
|
||||
{
|
||||
ULONG i;
|
||||
ULONGLONG DbgCtlMsr;
|
||||
KIRQL OldIrql;
|
||||
|
||||
if (ApplyFromVmxRootMode)
|
||||
{
|
||||
if (ApplyByVmcall)
|
||||
{
|
||||
DbgCtlMsr = g_Callbacks.VmFuncGetDebugctlVmcallOnTargetCore();
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgCtlMsr = g_Callbacks.VmFuncGetDebugctl();
|
||||
}
|
||||
xlock_core(&OldIrql);
|
||||
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
//
|
||||
// Disable LBR
|
||||
//
|
||||
LogInfo("Flush LBR on cpu core: %d\n", xcoreid());
|
||||
|
||||
if (ApplyByVmcall)
|
||||
{
|
||||
g_Callbacks.VmFuncSetDebugctlVmcallOnTargetCore(DbgCtlMsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Callbacks.VmFuncSetDebugctl(DbgCtlMsr);
|
||||
}
|
||||
}
|
||||
else
|
||||
xrdmsr(MSR_IA32_DEBUGCTLMSR, &DbgCtlMsr);
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
xwrmsr(MSR_IA32_DEBUGCTLMSR, DbgCtlMsr);
|
||||
|
||||
//
|
||||
// Flush LBR registers
|
||||
//
|
||||
xwrmsr(MSR_LBR_SELECT, 0);
|
||||
xwrmsr(MSR_LBR_TOS, 0);
|
||||
|
||||
for (i = 0; i < LbrCapacity; i++)
|
||||
{
|
||||
xrdmsr(MSR_IA32_DEBUGCTLMSR, &DbgCtlMsr);
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
xwrmsr(MSR_IA32_DEBUGCTLMSR, DbgCtlMsr);
|
||||
xwrmsr(MSR_LBR_NHM_FROM + i, 0);
|
||||
xwrmsr(MSR_LBR_NHM_TO + i, 0);
|
||||
}
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
xrdmsr(MSR_LBR_SELECT, &State->Config.LbrSelect);
|
||||
xrdmsr(MSR_LBR_TOS, &State->Data->LbrTos);
|
||||
|
||||
for (i = 0; i < (ULONG)LbrCapacity; i++)
|
||||
{
|
||||
xrdmsr(MSR_LBR_NHM_FROM + i, &State->Data->Entries[i].From);
|
||||
xrdmsr(MSR_LBR_NHM_TO + i, &State->Data->Entries[i].To);
|
||||
}
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
xrelease_core(&OldIrql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write LBR MSRs from the provided LBR_STATE structure
|
||||
* @brief Start collecting LBR branches
|
||||
*
|
||||
* @param State
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return VOID
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
VOID
|
||||
LbrPutLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
BOOLEAN
|
||||
LbrStartLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
if (LbrCapacity == 0)
|
||||
{
|
||||
LogInfo("LBR: Aborting, CPU model not supported.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ULONGLONG DbgCtlMsr;
|
||||
KIRQL OldIrql;
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
|
||||
//
|
||||
// Force the selection mask
|
||||
xwrmsr(MSR_LBR_SELECT, State->Config.LbrSelect);
|
||||
//
|
||||
xwrmsr(MSR_LBR_SELECT, LBR_SELECT);
|
||||
|
||||
//
|
||||
// Clear hardware state
|
||||
//
|
||||
xwrmsr(MSR_LBR_TOS, 0);
|
||||
for (ULONG i = 0; i < (ULONG)LbrCapacity; i++)
|
||||
{
|
||||
|
|
@ -179,8 +151,6 @@ LbrPutLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall
|
|||
xwrmsr(MSR_LBR_NHM_TO + i, 0);
|
||||
}
|
||||
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
|
||||
if (ApplyFromVmxRootMode)
|
||||
{
|
||||
if (ApplyByVmcall)
|
||||
|
|
@ -215,475 +185,131 @@ LbrPutLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall
|
|||
DbgCtlMsr &= ~(1ULL << 11); // Bit 11 = 0
|
||||
xwrmsr(MSR_IA32_DEBUGCTLMSR, DbgCtlMsr);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flush LBR MSRs by disabling LBR and clearing all LBR entries
|
||||
* @brief Save LBR branches
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrFlushLbr()
|
||||
LbrSaveLbr()
|
||||
{
|
||||
UINT64 LbrTos;
|
||||
LBR_STACK_ENTRY * State;
|
||||
UINT32 CurrentCore = 0;
|
||||
|
||||
//
|
||||
// Get the current core id
|
||||
//
|
||||
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
|
||||
|
||||
//
|
||||
// Get the current processor LBR stack
|
||||
//
|
||||
State = &g_LbrStateList[CurrentCore];
|
||||
|
||||
//
|
||||
// Read and store the current TOS index to know where the most recent branch is stored
|
||||
//
|
||||
xrdmsr(MSR_LBR_TOS, &LbrTos);
|
||||
State->Tos = (UINT32)LbrTos;
|
||||
|
||||
//
|
||||
// Dump LBR entries into the current core's state structure
|
||||
//
|
||||
for (ULONG i = 0; i < (ULONG)LbrCapacity; i++)
|
||||
{
|
||||
xrdmsr(MSR_LBR_NHM_FROM + i, &State->BranchEntry[i].From);
|
||||
xrdmsr(MSR_LBR_NHM_TO + i, &State->BranchEntry[i].To);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop collecting LBR branches
|
||||
*
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrStopLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
ULONG i;
|
||||
ULONGLONG DbgCtlMsr;
|
||||
KIRQL OldIrql;
|
||||
|
||||
xlock_core(&OldIrql);
|
||||
|
||||
//
|
||||
// Disable LBR
|
||||
//
|
||||
LogInfo("LIBIHT-COM: Flush LBR on cpu core: %d\n", xcoreid());
|
||||
xrdmsr(MSR_IA32_DEBUGCTLMSR, &DbgCtlMsr);
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
xwrmsr(MSR_IA32_DEBUGCTLMSR, DbgCtlMsr);
|
||||
|
||||
//
|
||||
// Flush LBR registers
|
||||
//
|
||||
xwrmsr(MSR_LBR_SELECT, 0);
|
||||
xwrmsr(MSR_LBR_TOS, 0);
|
||||
|
||||
for (i = 0; i < LbrCapacity; i++)
|
||||
if (ApplyFromVmxRootMode)
|
||||
{
|
||||
xwrmsr(MSR_LBR_NHM_FROM + i, 0);
|
||||
xwrmsr(MSR_LBR_NHM_TO + i, 0);
|
||||
if (ApplyByVmcall)
|
||||
{
|
||||
DbgCtlMsr = g_Callbacks.VmFuncGetDebugctlVmcallOnTargetCore();
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgCtlMsr = g_Callbacks.VmFuncGetDebugctl();
|
||||
}
|
||||
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
|
||||
if (ApplyByVmcall)
|
||||
{
|
||||
g_Callbacks.VmFuncSetDebugctlVmcallOnTargetCore(DbgCtlMsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Callbacks.VmFuncSetDebugctl(DbgCtlMsr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xrdmsr(MSR_IA32_DEBUGCTLMSR, &DbgCtlMsr);
|
||||
DbgCtlMsr &= ~DEBUGCTLMSR_LBR;
|
||||
xwrmsr(MSR_IA32_DEBUGCTLMSR, DbgCtlMsr);
|
||||
}
|
||||
|
||||
xrelease_core(&OldIrql);
|
||||
//
|
||||
// Save the LBR entries
|
||||
//
|
||||
LbrSaveLbr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start collecting LBR branches for a specific process and store the configuration in the global LBR state list
|
||||
* @brief Dump collected LBR branches
|
||||
*
|
||||
* @param Request
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
* @return VOID
|
||||
*/
|
||||
BOOLEAN
|
||||
LbrStartLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
VOID
|
||||
LbrDumpLbr()
|
||||
{
|
||||
LBR_STATE * State;
|
||||
|
||||
if (LbrCapacity == 0)
|
||||
{
|
||||
LogInfo("LBR: Aborting, CPU model not supported.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
State = LbrFindLbrState(Request->LbrConfig.Pid);
|
||||
if (State)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: LBR already enabled for pid %d\n",
|
||||
Request->LbrConfig.Pid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
State = LbrCreateLbrState();
|
||||
if (State == NULL)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: Create LBR state failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
ULONG CurrentIdx;
|
||||
LBR_STACK_ENTRY * State;
|
||||
UINT32 CurrentCore = 0;
|
||||
|
||||
//
|
||||
// Setup config fields for LBR state
|
||||
// Get the current core id
|
||||
//
|
||||
State->Parent = NULL;
|
||||
State->Config.Pid = Request->LbrConfig.Pid ? Request->LbrConfig.Pid : xgetcurrent_pid();
|
||||
State->Config.LbrSelect = Request->LbrConfig.LbrSelect ? Request->LbrConfig.LbrSelect : LBR_SELECT;
|
||||
LbrInsertLbrState(State);
|
||||
CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
|
||||
|
||||
//
|
||||
// If the requesting process is the current process, trace it right away
|
||||
// Get the current processor LBR stack
|
||||
//
|
||||
if (State->Config.Pid == xgetcurrent_pid())
|
||||
{
|
||||
LbrPutLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop collecting LBR branches for a specific process and remove the corresponding LBR state from the global list
|
||||
*
|
||||
* @param Request
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
LbrStopLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_STATE * State;
|
||||
|
||||
State = LbrFindLbrState(Request->LbrConfig.Pid);
|
||||
if (State == NULL)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: LBR not enabled for pid %d\n",
|
||||
Request->LbrConfig.Pid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (State->Config.Pid == xgetcurrent_pid())
|
||||
{
|
||||
LbrGetLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
LbrRemoveLbrState(State);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dump LBR info for a specific process to debug logs and optionally copy the LBR data to user buffer
|
||||
*
|
||||
* @param Request
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
|
||||
BOOLEAN
|
||||
LbrDumpLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
|
||||
UNREFERENCED_PARAMETER(ApplyByVmcall);
|
||||
|
||||
LBR_STATE * State = LbrFindLbrState(Request->LbrConfig.Pid);
|
||||
if (State == NULL)
|
||||
return FALSE;
|
||||
|
||||
ULONG CurrentIdx;
|
||||
State = &g_LbrStateList[CurrentCore];
|
||||
|
||||
LogInfo("LBR Chronological Trace\n");
|
||||
|
||||
for (ULONG i = 1; i <= LbrCapacity; i++)
|
||||
{
|
||||
CurrentIdx = (ULONG)(State->Data->LbrTos + i) % (ULONG)LbrCapacity;
|
||||
CurrentIdx = (ULONG)(State->Tos + i) % (ULONG)LbrCapacity;
|
||||
|
||||
if (State->Data->Entries[CurrentIdx].From == 0)
|
||||
continue;
|
||||
// if (State->BranchEntry[CurrentIdx].From == 0)
|
||||
// continue;
|
||||
|
||||
LogInfo("[%2u] FROM: 0x%llx TO: 0x%llx\n",
|
||||
CurrentIdx,
|
||||
State->Data->Entries[CurrentIdx].From,
|
||||
State->Data->Entries[CurrentIdx].To);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update LBR configuration for a specific process and optionally refresh the LBR MSRs if the current process is the owner
|
||||
*
|
||||
* @param Request
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
LbrConfigLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_STATE * State;
|
||||
|
||||
State = LbrFindLbrState(Request->LbrConfig.Pid);
|
||||
|
||||
if (State == NULL)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: LBR not enabled for pid %d\n",
|
||||
Request->LbrConfig.Pid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (State->Config.Pid == xgetcurrent_pid())
|
||||
{
|
||||
LbrGetLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
State->Config.LbrSelect = Request->LbrConfig.LbrSelect;
|
||||
LbrPutLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
else
|
||||
{
|
||||
State->Config.LbrSelect = Request->LbrConfig.LbrSelect;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new LBR_STATE structure with allocated memory for LBR data and entries
|
||||
*
|
||||
* @return LBR_STATE*
|
||||
*/
|
||||
LBR_STATE *
|
||||
LbrCreateLbrState()
|
||||
{
|
||||
LBR_STATE * State;
|
||||
LBR_DATA * Data;
|
||||
LBR_STACK_ENTRY * Entries;
|
||||
|
||||
State = xmalloc(sizeof(LBR_STATE));
|
||||
if (State == NULL)
|
||||
return NULL;
|
||||
|
||||
Data = xmalloc(sizeof(LBR_DATA));
|
||||
if (Data == NULL)
|
||||
{
|
||||
xfree(State);
|
||||
return NULL;
|
||||
}
|
||||
SIZE_T TotalEntrySize = (SIZE_T)sizeof(LBR_STACK_ENTRY) * LbrCapacity;
|
||||
Entries = xmalloc(TotalEntrySize);
|
||||
if (Entries == NULL)
|
||||
{
|
||||
xfree(Data);
|
||||
xfree(State);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmemset(State, sizeof(LBR_STATE));
|
||||
xmemset(Data, sizeof(LBR_DATA));
|
||||
xmemset(Entries, TotalEntrySize);
|
||||
|
||||
State->Data = Data;
|
||||
Data->Entries = Entries;
|
||||
|
||||
return State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the LBR_STATE structure for a specific process ID from the global list
|
||||
*
|
||||
* @param Pid
|
||||
* @return LBR_STATE*
|
||||
*/
|
||||
LBR_STATE *
|
||||
LbrFindLbrState(ULONG Pid)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LBR_STATE * RetState = NULL;
|
||||
PLIST_ENTRY Link;
|
||||
|
||||
ULONG TargetPid = (Pid == 0) ? xgetcurrent_pid() : Pid;
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
|
||||
for (Link = LbrStateHead.Flink; Link != &LbrStateHead; Link = Link->Flink)
|
||||
{
|
||||
LBR_STATE * Curr = CONTAINING_RECORD(Link, LBR_STATE, List);
|
||||
if (Curr->Config.Pid == TargetPid)
|
||||
{
|
||||
RetState = Curr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
return RetState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a new LBR_STATE structure into the global list with proper locking
|
||||
*
|
||||
* @param NewState
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrInsertLbrState(LBR_STATE * NewState)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
if (NewState == NULL)
|
||||
return;
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
LogInfo("LIBIHT-COM: Insert LBR state for pid %d\n", NewState->Config.Pid);
|
||||
xlist_add(NewState->List, LbrStateHead);
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove an existing LBR_STATE structure from the global list and free its associated memory with proper locking
|
||||
*
|
||||
* @param OldState
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrRemoveLbrState(LBR_STATE * OldState)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
if (OldState == NULL)
|
||||
return;
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
LogInfo("LIBIHT-COM: Remove LBR state for pid %d\n", OldState->Config.Pid);
|
||||
|
||||
xlist_del(OldState->List);
|
||||
xfree(OldState->Data->Entries);
|
||||
xfree(OldState->Data);
|
||||
xfree(OldState);
|
||||
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free all LBR_STATE structures in the global list and their associated memory with proper locking
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrFreeLbrStatList()
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LBR_STATE * CurrState;
|
||||
PLIST_ENTRY CurrLink;
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
|
||||
CurrLink = LbrStateHead.Flink;
|
||||
while (CurrLink != &LbrStateHead)
|
||||
{
|
||||
CurrState = CONTAINING_RECORD(CurrLink, LBR_STATE, List);
|
||||
CurrLink = CurrLink->Flink;
|
||||
|
||||
xlist_del(CurrState->List);
|
||||
xfree(CurrState->Data->Entries);
|
||||
xfree(CurrState->Data);
|
||||
xfree(CurrState);
|
||||
}
|
||||
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle IOCTL requests for LBR operations by dispatching to the appropriate function based on the command
|
||||
*
|
||||
* @param Request
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
LbrIoctlHandler(XIOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
BOOLEAN Status = TRUE;
|
||||
|
||||
LogInfo("LIBIHT-COM: LBR ioctl command %d.\n", Request->Cmd);
|
||||
switch (Request->Cmd)
|
||||
{
|
||||
case LIBIHT_IOCTL_ENABLE_LBR:
|
||||
Status = LbrStartLbr(&Request->Body.Lbr, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
break;
|
||||
case LIBIHT_IOCTL_DISABLE_LBR:
|
||||
Status = LbrStopLbr(&Request->Body.Lbr, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
break;
|
||||
case LIBIHT_IOCTL_DUMP_LBR:
|
||||
Status = LbrDumpLbr(&Request->Body.Lbr, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
break;
|
||||
case LIBIHT_IOCTL_CONFIG_LBR:
|
||||
Status = LbrConfigLbr(&Request->Body.Lbr, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
break;
|
||||
default:
|
||||
LogInfo("LIBIHT-COM: Invalid LBR ioctl command\n");
|
||||
Status = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle context switch events by saving the LBR state of the previous process and restoring the LBR state of the next process if they are being traced
|
||||
*
|
||||
* @param PrevPid
|
||||
* @param NextPid
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrCswitchHandler(ULONG PrevPid,
|
||||
ULONG NextPid,
|
||||
BOOLEAN ApplyFromVmxRootMode,
|
||||
BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_STATE * PrevState;
|
||||
LBR_STATE * NextState;
|
||||
|
||||
PrevState = LbrFindLbrState(PrevPid);
|
||||
NextState = LbrFindLbrState(NextPid);
|
||||
|
||||
if (PrevState)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: LBR context switch from pid %d on cpu core %d\n",
|
||||
PrevState->Config.Pid,
|
||||
xcoreid());
|
||||
LbrGetLbr(PrevState, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
if (NextState)
|
||||
{
|
||||
LogInfo("LIBIHT-COM: LBR context switch to pid %d on cpu core %d\n",
|
||||
NextState->Config.Pid,
|
||||
xcoreid());
|
||||
LbrPutLbr(NextState, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle new process creation events by inheriting the LBR state from the parent process if it is being traced
|
||||
*
|
||||
* @param ParentPid
|
||||
* @param ChildPid
|
||||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LbrNewProcHandler(
|
||||
ULONG ParentPid,
|
||||
ULONG ChildPid,
|
||||
BOOLEAN ApplyFromVmxRootMode,
|
||||
BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_STATE *ParentState, *ChildState;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ParentState = LbrFindLbrState(ParentPid);
|
||||
if (ParentState == NULL)
|
||||
return;
|
||||
|
||||
LogInfo("LIBIHT-COM: LBR new child process pid %d, parent pid %d\n",
|
||||
ChildPid,
|
||||
ParentPid);
|
||||
|
||||
ChildState = LbrCreateLbrState();
|
||||
if (ChildState == NULL)
|
||||
return;
|
||||
|
||||
xacquire_lock(&LbrStateLock, &OldIrql);
|
||||
ChildState->Parent = ParentState;
|
||||
ChildState->Config.Pid = ChildPid;
|
||||
ChildState->Config.LbrSelect = ParentState->Config.LbrSelect;
|
||||
xmemcpy(ChildState->Data,
|
||||
ParentState->Data,
|
||||
sizeof(LBR_DATA) + LbrCapacity * sizeof(LBR_STACK_ENTRY));
|
||||
xrelease_lock(&LbrStateLock, &OldIrql);
|
||||
|
||||
LbrInsertLbrState(ChildState);
|
||||
|
||||
if (ChildPid == xgetcurrent_pid())
|
||||
{
|
||||
LbrPutLbr(ChildState, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
State->BranchEntry[CurrentIdx].From,
|
||||
State->BranchEntry[CurrentIdx].To);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,22 +22,7 @@
|
|||
VOID
|
||||
HyperTraceExamplePerformLbrTrace(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_IOCTL_REQUEST Request = {0};
|
||||
|
||||
KAFFINITY Affinity = 1;
|
||||
KeSetSystemAffinityThread(Affinity);
|
||||
|
||||
LbrInitialize();
|
||||
|
||||
if (!LbrCheck())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Request.LbrConfig.Pid = 0;
|
||||
Request.LbrConfig.LbrSelect = LBR_SELECT;
|
||||
|
||||
if (LbrStartLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall))
|
||||
if (LbrStartLbr(ApplyFromVmxRootMode, ApplyByVmcall))
|
||||
{
|
||||
for (volatile int i = 0; i < 50; i++)
|
||||
{
|
||||
|
|
@ -53,20 +38,11 @@ HyperTraceExamplePerformLbrTrace(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVm
|
|||
}
|
||||
}
|
||||
|
||||
LBR_STATE * State = LbrFindLbrState(0);
|
||||
|
||||
if (State)
|
||||
{
|
||||
LbrGetLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
LogInfo("Dumping LBR Buffer...\n");
|
||||
|
||||
LbrDumpLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
LbrStopLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
LbrStopLbr(ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
LbrDumpLbr(); // This will print the collected LBR branches to the log
|
||||
}
|
||||
|
||||
KeRevertToUserAffinityThread();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,12 +55,7 @@ HyperTraceExamplePerformLbrTrace(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVm
|
|||
BOOLEAN
|
||||
HyperTraceStartLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_IOCTL_REQUEST Request = {0};
|
||||
|
||||
Request.LbrConfig.Pid = 0;
|
||||
Request.LbrConfig.LbrSelect = LBR_SELECT;
|
||||
|
||||
return LbrStartLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
return LbrStartLbr(ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,27 +63,12 @@ HyperTraceStartLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
|||
* @param ApplyFromVmxRootMode
|
||||
* @param ApplyByVmcall
|
||||
*
|
||||
* @return BOOLEAN
|
||||
* @return VOID
|
||||
*/
|
||||
BOOLEAN
|
||||
VOID
|
||||
HyperTraceStopLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall)
|
||||
{
|
||||
LBR_IOCTL_REQUEST Request = {0};
|
||||
|
||||
Request.LbrConfig.Pid = 0;
|
||||
Request.LbrConfig.LbrSelect = LBR_SELECT;
|
||||
|
||||
LBR_STATE * State = LbrFindLbrState(0);
|
||||
|
||||
if (State)
|
||||
{
|
||||
LbrGetLbr(State, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
LogInfo("Dumping LBR Buffer...\n");
|
||||
LbrDumpLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
|
||||
return LbrStopLbr(&Request, ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
LbrStopLbr(ApplyFromVmxRootMode, ApplyByVmcall);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -129,7 +85,7 @@ BOOLEAN
|
|||
HyperTraceInitCallback(HYPERTRACE_CALLBACKS * HypertraceCallbacks,
|
||||
BOOLEAN InitForHypervisorEnvironment)
|
||||
{
|
||||
ULONG ProcessorsCount;
|
||||
UINT32 ProcessorsCount = 0;
|
||||
|
||||
//
|
||||
// Check if the LBR is supported on this CPU before initializing the hypertrace module,
|
||||
|
|
@ -159,14 +115,14 @@ HyperTraceInitCallback(HYPERTRACE_CALLBACKS * HypertraceCallbacks,
|
|||
RtlCopyMemory(&g_Callbacks, HypertraceCallbacks, sizeof(HYPERTRACE_CALLBACKS));
|
||||
|
||||
//
|
||||
// Read number of cores
|
||||
// Query the number of processors in the system to initialize the global LBR state list accordingly
|
||||
//
|
||||
ProcessorsCount = KeQueryActiveProcessorCount(0);
|
||||
|
||||
//
|
||||
// Initialize the memory for LBR requests on all cores
|
||||
// Initialize the global LBR state list to hold LBR states for each core
|
||||
//
|
||||
g_LbrRequestState = PlatformAllocateMemory(sizeof(LBR_IOCTL_REQUEST) * ProcessorsCount);
|
||||
g_LbrStateList = (LBR_STACK_ENTRY *)xmalloc(sizeof(LBR_STACK_ENTRY) * ProcessorsCount);
|
||||
|
||||
//
|
||||
// Set the flag to indicate whether the initialization is being done for hypervisor environment or not
|
||||
|
|
@ -210,13 +166,11 @@ HyperTraceQueryStateOfLbrSaveAndLoadVmExitAndEntryControls(UINT32 CoreId)
|
|||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HyperTraceEnableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
HyperTraceEnableLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
|
||||
|
||||
ULONG ProcessorsCount;
|
||||
|
||||
//
|
||||
// Check if LBR is already enabled or not
|
||||
//
|
||||
|
|
@ -244,22 +198,6 @@ HyperTraceEnableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReq
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Enabling LBR
|
||||
//
|
||||
LbrInitialize();
|
||||
|
||||
//
|
||||
// Read number of cores
|
||||
//
|
||||
ProcessorsCount = KeQueryActiveProcessorCount(0);
|
||||
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
g_LbrRequestState[i].LbrConfig.Pid = 0;
|
||||
g_LbrRequestState[i].LbrConfig.LbrSelect = LBR_SELECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Broadcast enabling LBR on all cores
|
||||
//
|
||||
|
|
@ -287,8 +225,8 @@ HyperTraceEnableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReq
|
|||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HyperTraceDisableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
HyperTraceDisableLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
|
||||
|
||||
|
|
@ -327,7 +265,7 @@ HyperTraceDisableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRe
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Show LBR tracing for HyperTrace
|
||||
* @brief Save LBR tracing for HyperTrace
|
||||
*
|
||||
* @param HyperTraceOperationRequest
|
||||
* @param ApplyFromVmxRootMode
|
||||
|
|
@ -335,13 +273,11 @@ HyperTraceDisableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRe
|
|||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HyperTraceShowLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
HyperTraceSaveLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
|
||||
|
||||
LBR_IOCTL_REQUEST * CurrentRequest;
|
||||
|
||||
//
|
||||
// Check if LBR is already disabled or not
|
||||
//
|
||||
|
|
@ -355,21 +291,65 @@ HyperTraceShowLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReque
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the current request (for current core)
|
||||
//
|
||||
CurrentRequest = &g_LbrRequestState[KeGetCurrentProcessorNumberEx(NULL)];
|
||||
LogInfo("Saving LBR Buffer...\n");
|
||||
|
||||
LBR_STATE * State = LbrFindLbrState(0);
|
||||
//
|
||||
// Save the LBR state
|
||||
//
|
||||
LbrSaveLbr();
|
||||
|
||||
if (State)
|
||||
//
|
||||
// The operation was successful
|
||||
//
|
||||
if (HyperTraceOperationRequest != NULL)
|
||||
{
|
||||
LbrGetLbr(State, TRUE, TRUE);
|
||||
HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dump LBR tracing for HyperTrace
|
||||
*
|
||||
* @param HyperTraceOperationRequest
|
||||
* @param ApplyFromVmxRootMode
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HyperTraceDumpLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
|
||||
|
||||
//
|
||||
// Check if LBR is already disabled or not
|
||||
//
|
||||
if (!g_LastBranchRecordEnabled)
|
||||
{
|
||||
if (HyperTraceOperationRequest != NULL)
|
||||
{
|
||||
HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_LBR_ALREADY_DISABLED;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LogInfo("Dumping LBR Buffer...\n");
|
||||
|
||||
LbrDumpLbr(CurrentRequest, TRUE, TRUE);
|
||||
//
|
||||
// This will print the collected LBR branches to the log
|
||||
//
|
||||
LbrDumpLbr();
|
||||
|
||||
//
|
||||
// The operation was successful
|
||||
//
|
||||
if (HyperTraceOperationRequest != NULL)
|
||||
{
|
||||
HyperTraceOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -385,7 +365,7 @@ HyperTraceUninit()
|
|||
//
|
||||
// Disable LBR tracing if it is still enabled
|
||||
//
|
||||
HyperTraceDisableLbrTracing(NULL, FALSE);
|
||||
HyperTraceDisableLbr(NULL, FALSE);
|
||||
|
||||
//
|
||||
// Set callbacks to not initialized
|
||||
|
|
@ -393,14 +373,13 @@ HyperTraceUninit()
|
|||
g_HyperTraceCallbacksInitialized = FALSE;
|
||||
|
||||
//
|
||||
// UnAllocate the state buffer
|
||||
// Unallocate the global LBR state list if it is allocated
|
||||
//
|
||||
PlatformFreeMemory(g_LbrRequestState);
|
||||
|
||||
//
|
||||
// Set LBR request buffer to zero
|
||||
//
|
||||
g_LbrRequestState = NULL64_ZERO;
|
||||
if (g_LbrStateList != NULL)
|
||||
{
|
||||
xfree(g_LbrStateList);
|
||||
g_LbrStateList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -435,7 +414,7 @@ HyperTracePerformOperation(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReq
|
|||
|
||||
LogInfo("HyperTrace: Enabling LBR tracing...\n");
|
||||
|
||||
HyperTraceEnableLbrTracing(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
HyperTraceEnableLbr(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -443,15 +422,23 @@ HyperTracePerformOperation(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReq
|
|||
|
||||
LogInfo("HyperTrace: Disabling LBR tracing...\n");
|
||||
|
||||
HyperTraceDisableLbrTracing(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
HyperTraceDisableLbr(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
|
||||
break;
|
||||
|
||||
case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SHOW:
|
||||
case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SAVE:
|
||||
|
||||
LogInfo("HyperTrace: Saving LBR tracing...\n");
|
||||
|
||||
HyperTraceSaveLbr(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
|
||||
break;
|
||||
|
||||
case HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DUMP:
|
||||
|
||||
LogInfo("HyperTrace: Showing LBR tracing...\n");
|
||||
|
||||
HyperTraceShowLbrTracing(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
HyperTraceDumpLbr(HyperTraceOperationRequest, ApplyFromVmxRootMode);
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ BOOLEAN g_InitForHypervisorEnvironment;
|
|||
BOOLEAN g_LastBranchRecordEnabled;
|
||||
|
||||
/**
|
||||
* @brief Core specific state
|
||||
* @brief This will be a dynamically allocated array to hold LBR states for each core
|
||||
*
|
||||
*/
|
||||
LBR_IOCTL_REQUEST * g_LbrRequestState;
|
||||
LBR_STACK_ENTRY * g_LbrStateList;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Globals //
|
||||
// Constants //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
// Intel MSR Constants
|
||||
|
|
@ -23,63 +23,30 @@
|
|||
#define MSR_LBR_NHM_TO 0x000006C0
|
||||
#define LBR_SELECT 0x00000000
|
||||
|
||||
/**
|
||||
* @brief Maximum LBR capacity that is supported by processors
|
||||
*
|
||||
*/
|
||||
#define MAXIMUM_LBR_CAPACITY 0x20 // 32 entries, which is the maximum supported by modern Intel CPUs
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Structures //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
typedef struct _LBR_STACK_ENTRY
|
||||
typedef struct _LBR_BRANCH_ENTRY
|
||||
{
|
||||
ULONGLONG From;
|
||||
ULONGLONG To;
|
||||
|
||||
} LBR_BRANCH_ENTRY, PLBR_BRANCH_ENTRY;
|
||||
|
||||
typedef struct _LBR_STACK_ENTRY
|
||||
{
|
||||
LBR_BRANCH_ENTRY BranchEntry[MAXIMUM_LBR_CAPACITY];
|
||||
UINT32 Tos;
|
||||
|
||||
} LBR_STACK_ENTRY, PLBR_STACK_ENTRY;
|
||||
|
||||
typedef struct _LBR_DATA
|
||||
{
|
||||
ULONGLONG LbrTos;
|
||||
LBR_STACK_ENTRY * Entries;
|
||||
|
||||
} LBR_DATA, *PLBR_DATA;
|
||||
|
||||
typedef struct _LBR_CONFIG
|
||||
{
|
||||
ULONG Pid;
|
||||
ULONGLONG LbrSelect;
|
||||
|
||||
} LBR_CONFIG, *PLBR_CONFIG;
|
||||
|
||||
typedef struct _LBR_STATE
|
||||
{
|
||||
LBR_CONFIG Config;
|
||||
LBR_DATA * Data;
|
||||
PVOID Parent;
|
||||
LIST_ENTRY List;
|
||||
|
||||
} LBR_STATE, *PLBR_STATE;
|
||||
|
||||
typedef struct _LBR_IOCTL_REQUEST
|
||||
{
|
||||
LBR_CONFIG LbrConfig;
|
||||
LBR_DATA * Buffer;
|
||||
|
||||
} LBR_IOCTL_REQUEST, *PLBR_IOCTL_REQUEST;
|
||||
|
||||
typedef struct _XIOCTL_REQUEST
|
||||
{
|
||||
ULONG Cmd;
|
||||
union
|
||||
{
|
||||
LBR_IOCTL_REQUEST Lbr;
|
||||
} Body;
|
||||
|
||||
} XIOCTL_REQUEST, *PXIOCTL_REQUEST;
|
||||
|
||||
// IOCTL Commands
|
||||
#define LIBIHT_IOCTL_ENABLE_LBR 0x1
|
||||
#define LIBIHT_IOCTL_DISABLE_LBR 0x2
|
||||
#define LIBIHT_IOCTL_DUMP_LBR 0x3
|
||||
#define LIBIHT_IOCTL_CONFIG_LBR 0x4
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Platform Wrappers //
|
||||
//////////////////////////////////////////////////
|
||||
|
|
@ -136,41 +103,20 @@ extern CPU_LBR_MAP CPU_LBR_MAPS[];
|
|||
// Prototypes //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
VOID
|
||||
LbrGetLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
|
||||
VOID
|
||||
LbrPutLbr(LBR_STATE * State, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
|
||||
LBR_STATE *
|
||||
LbrCreateLbrState();
|
||||
|
||||
LBR_STATE *
|
||||
LbrFindLbrState(ULONG Pid);
|
||||
|
||||
BOOLEAN
|
||||
LbrCheck();
|
||||
|
||||
VOID
|
||||
LbrInsertLbrState(LBR_STATE * NewState);
|
||||
|
||||
VOID
|
||||
LbrRemoveLbrState(LBR_STATE * OldState);
|
||||
|
||||
VOID
|
||||
LbrFreeLbrStatList();
|
||||
|
||||
VOID
|
||||
LbrInitialize();
|
||||
|
||||
BOOLEAN
|
||||
LbrStartLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
LbrStartLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
|
||||
BOOLEAN
|
||||
LbrStopLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
VOID
|
||||
LbrStopLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
|
||||
BOOLEAN
|
||||
LbrDumpLbr(LBR_IOCTL_REQUEST * Request, BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
VOID
|
||||
LbrSaveLbr();
|
||||
|
||||
VOID
|
||||
LbrDumpLbr();
|
||||
|
||||
extern ULONGLONG LbrCapacity;
|
||||
extern LIST_ENTRY LbrStateHead;
|
||||
|
|
|
|||
|
|
@ -1272,7 +1272,8 @@ typedef enum _HYPERTRACE_OPERATION_REQUEST_TYPE
|
|||
{
|
||||
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE,
|
||||
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE,
|
||||
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SHOW,
|
||||
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SAVE,
|
||||
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DUMP,
|
||||
|
||||
} HYPERTRACE_OPERATION_REQUEST_TYPE;
|
||||
|
||||
|
|
|
|||
|
|
@ -148,10 +148,10 @@ static const char *const SymbolTypeNames[] = {
|
|||
#define FUNC_EVENT_TRACE_STEP_OUT 51
|
||||
#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP 52
|
||||
#define FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN 53
|
||||
#define FUNC_LBR_START 54
|
||||
#define FUNC_LBR_STOP 55
|
||||
#define FUNC_RDTSC 56
|
||||
#define FUNC_RDTSCP 57
|
||||
#define FUNC_RDTSC 54
|
||||
#define FUNC_RDTSCP 55
|
||||
#define FUNC_LBR_SAVE 56
|
||||
#define FUNC_LBR_DUMP 57
|
||||
#define FUNC_SPINLOCK_LOCK_CUSTOM_WAIT 58
|
||||
#define FUNC_EVENT_INJECT 59
|
||||
#define FUNC_POI 60
|
||||
|
|
@ -253,10 +253,10 @@ static const char *const FunctionNames[] = {
|
|||
"FUNC_EVENT_TRACE_STEP_OUT",
|
||||
"FUNC_EVENT_TRACE_INSTRUMENTATION_STEP",
|
||||
"FUNC_EVENT_TRACE_INSTRUMENTATION_STEP_IN",
|
||||
"FUNC_LBR_START",
|
||||
"FUNC_LBR_STOP",
|
||||
"FUNC_RDTSC",
|
||||
"FUNC_RDTSCP",
|
||||
"FUNC_LBR_SAVE",
|
||||
"FUNC_LBR_DUMP",
|
||||
"FUNC_SPINLOCK_LOCK_CUSTOM_WAIT",
|
||||
"FUNC_EVENT_INJECT",
|
||||
"FUNC_POI",
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ HyperTracePerformOperation(HYPERTRACE_OPERATION_PACKETS * LbrOperationRequest,
|
|||
//////////////////////////////////////////////////
|
||||
|
||||
IMPORT_EXPORT_HYPERTRACE BOOLEAN
|
||||
HyperTraceStartLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
HyperTraceSaveLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode);
|
||||
|
||||
IMPORT_EXPORT_HYPERTRACE BOOLEAN
|
||||
HyperTraceStopLbr(BOOLEAN ApplyFromVmxRootMode, BOOLEAN ApplyByVmcall);
|
||||
HyperTraceDumpLbr(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationRequest,
|
||||
BOOLEAN ApplyFromVmxRootMode);
|
||||
|
||||
IMPORT_EXPORT_HYPERTRACE BOOLEAN
|
||||
HyperTraceQueryStateOfLbrSaveAndLoadVmExitAndEntryControls(UINT32 CoreId);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ CommandLbrHelp()
|
|||
ShowMessages("\n");
|
||||
ShowMessages("\t\te.g : !lbr enable\n");
|
||||
ShowMessages("\t\te.g : !lbr disable\n");
|
||||
ShowMessages("\t\te.g : !lbr show\n");
|
||||
ShowMessages("\t\te.g : !lbr save\n");
|
||||
ShowMessages("\t\te.g : !lbr dump\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -140,9 +141,13 @@ CommandLbr(vector<CommandToken> CommandTokens, string Command)
|
|||
{
|
||||
LbrRequest.HyperTraceOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE;
|
||||
}
|
||||
else if (CompareLowerCaseStrings(CommandTokens.at(1), "show"))
|
||||
else if (CompareLowerCaseStrings(CommandTokens.at(1), "save"))
|
||||
{
|
||||
LbrRequest.HyperTraceOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SHOW;
|
||||
LbrRequest.HyperTraceOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SAVE;
|
||||
}
|
||||
else if (CompareLowerCaseStrings(CommandTokens.at(1), "dump"))
|
||||
{
|
||||
LbrRequest.HyperTraceOperationType = HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DUMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -165,7 +170,11 @@ CommandLbr(vector<CommandToken> CommandTokens, string Command)
|
|||
{
|
||||
ShowMessages("LBR disabled successfully\n");
|
||||
}
|
||||
else if (LbrRequest.HyperTraceOperationType == HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SHOW)
|
||||
else if (LbrRequest.HyperTraceOperationType == HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_SAVE)
|
||||
{
|
||||
ShowMessages("LBR branches are saved\n");
|
||||
}
|
||||
else if (LbrRequest.HyperTraceOperationType == HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DUMP)
|
||||
{
|
||||
ShowMessages("LBR branches are shown\n");
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,19 +1,19 @@
|
|||
#pragma once
|
||||
#ifndef PARSE_TABLE_H
|
||||
#define PARSE_TABLE_H
|
||||
#define RULES_COUNT 274
|
||||
#define RULES_COUNT 276
|
||||
#define TERMINAL_COUNT 124
|
||||
#define NONETERMINAL_COUNT 63
|
||||
#define START_VARIABLE "S"
|
||||
#define MAX_RHS_LEN 15
|
||||
#define KEYWORD_LIST_LENGTH 111
|
||||
#define KEYWORD_LIST_LENGTH 113
|
||||
#define OPERATORS_ONE_OPERAND_LIST_LENGTH 3
|
||||
#define OPERATORS_TWO_OPERAND_LIST_LENGTH 16
|
||||
#define REGISTER_MAP_LIST_LENGTH 120
|
||||
#define PSEUDO_REGISTER_MAP_LIST_LENGTH 16
|
||||
#define SCRIPT_VARIABLE_TYPE_LIST_LENGTH 10
|
||||
#define ASSIGNMENT_OPERATOR_LIST_LENGTH 10
|
||||
#define SEMANTIC_RULES_MAP_LIST_LENGTH 156
|
||||
#define SEMANTIC_RULES_MAP_LIST_LENGTH 158
|
||||
#define THREEOPFUNC1_LENGTH 1
|
||||
#define THREEOPFUNC2_LENGTH 3
|
||||
#define TWOOPFUNC1_LENGTH 8
|
||||
|
|
@ -26,8 +26,8 @@
|
|||
#define THREEOPFUNC4_LENGTH 1
|
||||
#define ONEOPFUNC4_LENGTH 1
|
||||
#define TWOOPFUNC4_LENGTH 1
|
||||
#define ZEROOPFUNC1_LENGTH 9
|
||||
#define ZEROOPFUNC2_LENGTH 2
|
||||
#define ZEROOPFUNC1_LENGTH 7
|
||||
#define ZEROOPFUNC2_LENGTH 4
|
||||
#define VARARGFUNC1_LENGTH 1
|
||||
extern const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT];
|
||||
extern const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN];
|
||||
|
|
@ -60,11 +60,11 @@ extern const SYMBOL_MAP PseudoRegisterMapList[];
|
|||
extern const char* ScriptVariableTypeList[];
|
||||
|
||||
|
||||
#define LALR_RULES_COUNT 109
|
||||
#define LALR_TERMINAL_COUNT 78
|
||||
#define LALR_RULES_COUNT 111
|
||||
#define LALR_TERMINAL_COUNT 80
|
||||
#define LALR_NONTERMINAL_COUNT 26
|
||||
#define LALR_MAX_RHS_LEN 9
|
||||
#define LALR_STATE_COUNT 307
|
||||
#define LALR_STATE_COUNT 315
|
||||
extern const struct _SCRIPT_ENGINE_TOKEN LalrLhs[RULES_COUNT];
|
||||
extern const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN];
|
||||
extern const unsigned int LalrRhsSize[RULES_COUNT];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# OneOpFunc1 input is a number and returns a number.
|
||||
.OneOpFunc1->poi db dd dw dq neg hi low not check_address strlen wcslen disassemble_len disassemble_len32 disassemble_len64 interlocked_increment interlocked_decrement reference physical_to_virtual virtual_to_physical poi_pa hi_pa low_pa db_pa dd_pa dw_pa dq_pa
|
||||
.OneOpFunc1->poi db dd dw dq neg hi low not check_address strlen wcslen disassemble_len disassemble_len32 disassemble_len64 lbr_save lbr_dump interlocked_increment interlocked_decrement reference physical_to_virtual virtual_to_physical poi_pa hi_pa low_pa db_pa dd_pa dw_pa dq_pa
|
||||
|
||||
# TwoOpFunc1 inputs are two numbers and returns a number.
|
||||
.TwoOpFunc1->ed eb eq interlocked_exchange interlocked_exchange_add wcscmp eb_pa ed_pa eq_pa
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
# TwoOpFunc4 the two inputs are numbers or wstrings and returns a number.
|
||||
.TwoOpFunc4->wcscmp
|
||||
|
||||
.ZeroOpFunc1->pause flush event_trace_step event_trace_step_in event_trace_step_out event_trace_instrumentation_step event_trace_instrumentation_step_in lbr_start lbr_stop
|
||||
.ZeroOpFunc1->pause flush event_trace_step event_trace_step_in event_trace_step_out event_trace_instrumentation_step event_trace_instrumentation_step_in
|
||||
|
||||
# ZeroOpFunc2 no input and returns a number
|
||||
.ZeroOpFunc2->rdtsc rdtscp
|
||||
.ZeroOpFunc2->rdtsc rdtscp lbr_save lbr_dump
|
||||
|
||||
.VarArgFunc1->printf
|
||||
|
||||
|
|
|
|||
|
|
@ -2014,15 +2014,16 @@ ScriptEngineFunctionEventTraceStepIn()
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of lbr_start function
|
||||
* @brief Implementation of lbr_save function
|
||||
*
|
||||
* @return VOID
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
VOID
|
||||
ScriptEngineFunctionLbrStart()
|
||||
BOOLEAN
|
||||
ScriptEngineFunctionLbrSave()
|
||||
{
|
||||
#ifdef SCRIPT_ENGINE_USER_MODE
|
||||
ShowMessages("err, it's not possible to call lbr_start function in the user-mode\n");
|
||||
return FALSE;
|
||||
#endif // SCRIPT_ENGINE_USER_MODE
|
||||
|
||||
#ifdef SCRIPT_ENGINE_KERNEL_MODE
|
||||
|
|
@ -2030,7 +2031,7 @@ ScriptEngineFunctionLbrStart()
|
|||
//
|
||||
// Depending if we are in VMX-root then a VMCALL is issued by default instead, otherwise the VMCALL is ignored
|
||||
//
|
||||
HyperTraceStartLbr(VmFuncVmxGetCurrentExecutionMode(), TRUE);
|
||||
return HyperTraceSaveLbr(NULL, VmFuncVmxGetCurrentExecutionMode());
|
||||
|
||||
#endif // SCRIPT_ENGINE_KERNEL_MODE
|
||||
}
|
||||
|
|
@ -2038,13 +2039,14 @@ ScriptEngineFunctionLbrStart()
|
|||
/**
|
||||
* @brief Implementation of lbr_stop function
|
||||
*
|
||||
* @return VOID
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
VOID
|
||||
ScriptEngineFunctionLbrStop()
|
||||
BOOLEAN
|
||||
ScriptEngineFunctionLbrDump()
|
||||
{
|
||||
#ifdef SCRIPT_ENGINE_USER_MODE
|
||||
ShowMessages("err, it's not possible to call lbr_stop function in the user-mode\n");
|
||||
return FALSE;
|
||||
#endif // SCRIPT_ENGINE_USER_MODE
|
||||
|
||||
#ifdef SCRIPT_ENGINE_KERNEL_MODE
|
||||
|
|
@ -2052,7 +2054,7 @@ ScriptEngineFunctionLbrStop()
|
|||
//
|
||||
// Depending if we are in VMX-root then a VMCALL is issued by default instead, otherwise the VMCALL is ignored
|
||||
//
|
||||
HyperTraceStopLbr(VmFuncVmxGetCurrentExecutionMode(), TRUE);
|
||||
return HyperTraceDumpLbr(NULL, VmFuncVmxGetCurrentExecutionMode());
|
||||
|
||||
#endif // SCRIPT_ENGINE_KERNEL_MODE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -736,16 +736,26 @@ ScriptEngineExecute(PGUEST_REGS GuestRegs,
|
|||
GuestRegs);
|
||||
break;
|
||||
|
||||
case FUNC_LBR_START:
|
||||
case FUNC_LBR_SAVE:
|
||||
|
||||
ScriptEngineFunctionLbrStart();
|
||||
Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head +
|
||||
(unsigned long long)(*Indx * sizeof(SYMBOL)));
|
||||
*Indx = *Indx + 1;
|
||||
|
||||
DesVal = ScriptEngineFunctionLbrSave();
|
||||
|
||||
SetValue(GuestRegs, ScriptGeneralRegisters, Des, DesVal);
|
||||
break;
|
||||
|
||||
case FUNC_LBR_STOP:
|
||||
case FUNC_LBR_DUMP:
|
||||
|
||||
ScriptEngineFunctionLbrStop();
|
||||
Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head +
|
||||
(unsigned long long)(*Indx * sizeof(SYMBOL)));
|
||||
*Indx = *Indx + 1;
|
||||
|
||||
DesVal = ScriptEngineFunctionLbrDump();
|
||||
|
||||
SetValue(GuestRegs, ScriptGeneralRegisters, Des, DesVal);
|
||||
break;
|
||||
|
||||
case FUNC_FLUSH:
|
||||
|
|
|
|||
|
|
@ -263,11 +263,11 @@ ScriptEngineFunctionEventTraceInstrumentationStep();
|
|||
VOID
|
||||
ScriptEngineFunctionEventTraceStepIn();
|
||||
|
||||
VOID
|
||||
ScriptEngineFunctionLbrStart();
|
||||
BOOLEAN
|
||||
ScriptEngineFunctionLbrSave();
|
||||
|
||||
VOID
|
||||
ScriptEngineFunctionLbrStop();
|
||||
BOOLEAN
|
||||
ScriptEngineFunctionLbrDump();
|
||||
|
||||
UINT64
|
||||
ScriptEngineFunctionStrcmp(const char * Address1, const char * Address2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue