mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-10 01:29:59 +00:00
165 lines
4.3 KiB
C
165 lines
4.3 KiB
C
/**
|
|
* @file TraceApi.c
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @brief Tracing routines for HyperTrace module
|
|
* @details
|
|
* @version 0.19
|
|
* @date 2026-04-25
|
|
*
|
|
* @copyright This project is released under the GNU Public License v3.
|
|
*/
|
|
#include "pch.h"
|
|
|
|
/**
|
|
* @brief Initialize the hyper trace module callbacks
|
|
* @details This only for callback initialization, not for LBR, PT, etc. initialization
|
|
*
|
|
* @param HyperTraceCallbacks Pointer to the HyperTrace callbacks structure to be registered
|
|
* @param RunningOnHypervisorEnvironment Whether the initialization is being done for hypervisor environment or not,
|
|
* it can be used to skip some of the initialization steps if it is not for hypervisor environment and behave differently based on that
|
|
*
|
|
* @return BOOLEAN
|
|
*/
|
|
BOOLEAN
|
|
HyperTraceInitCallback(HYPERTRACE_CALLBACKS * HyperTraceCallbacks,
|
|
BOOLEAN RunningOnHypervisorEnvironment)
|
|
{
|
|
UINT32 ProcessorsCount = 0;
|
|
|
|
//
|
|
// Check if any of the required callbacks are NULL
|
|
//
|
|
for (UINT32 i = 0; i < sizeof(HYPERTRACE_CALLBACKS) / sizeof(UINT64); i++)
|
|
{
|
|
if (((PVOID *)HyperTraceCallbacks)[i] == NULL)
|
|
{
|
|
//
|
|
// The callback has null entry, so we cannot proceed
|
|
//
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save the callbacks
|
|
//
|
|
PlatformWriteMemory(&g_Callbacks, HyperTraceCallbacks, sizeof(HYPERTRACE_CALLBACKS));
|
|
|
|
//
|
|
// Query the number of processors in the system to initialize the global LBR state list accordingly
|
|
//
|
|
ProcessorsCount = PlatformCpuGetActiveProcessorCount();
|
|
|
|
//
|
|
// Initialize the global LBR state list to hold LBR states for each core
|
|
//
|
|
g_LbrStateList = (LBR_STACK_ENTRY *)PlatformMemAllocateZeroedNonPagedPool(sizeof(LBR_STACK_ENTRY) * ProcessorsCount);
|
|
|
|
//
|
|
// Initialize the global PT per-CPU state list. Each entry starts in
|
|
// PT_STATE_DISABLED with no buffers allocated; PtStart() will lazily
|
|
// allocate ToPA / output / overflow buffers on first use per core.
|
|
//
|
|
g_PtStateList = (PT_PER_CPU *)PlatformMemAllocateZeroedNonPagedPool(sizeof(PT_PER_CPU) * ProcessorsCount);
|
|
|
|
if (g_PtStateList != NULL)
|
|
{
|
|
UINT32 i;
|
|
for (i = 0; i < ProcessorsCount; i++)
|
|
{
|
|
PtEngineInitDefaultConfig(&g_PtStateList[i].Config);
|
|
g_PtStateList[i].State = PT_STATE_DISABLED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the flag to indicate whether the initialization is being done for hypervisor environment or not
|
|
//
|
|
g_RunningOnHypervisorEnvironment = RunningOnHypervisorEnvironment;
|
|
|
|
//
|
|
// It is initialized, but LBR is disabled at this stage
|
|
//
|
|
g_LastBranchRecordEnabled = FALSE;
|
|
|
|
//
|
|
// It is initialized, but Processor Trace is disabled at this stage
|
|
//
|
|
g_ProcessorTraceEnabled = FALSE;
|
|
|
|
//
|
|
// Enable callbacks and set the initialized flag
|
|
//
|
|
g_HyperTraceCallbacksInitialized = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief Uninitialize the hypertrace module
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
HyperTraceUninit()
|
|
{
|
|
//
|
|
// Check if the callbacks are initialized, if not, we don't need to handle anymore
|
|
//
|
|
if (!g_HyperTraceCallbacksInitialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Disable LBR tracing if it is still enabled
|
|
//
|
|
if (g_LastBranchRecordEnabled)
|
|
{
|
|
HyperTraceLbrDisable(NULL);
|
|
}
|
|
|
|
//
|
|
// Unallocate the global LBR state list if it is allocated
|
|
//
|
|
if (g_LbrStateList != NULL)
|
|
{
|
|
PlatformMemFreePool(g_LbrStateList);
|
|
g_LbrStateList = NULL;
|
|
}
|
|
|
|
//
|
|
// Disable Processor Trace if it is still enabled
|
|
//
|
|
if (g_ProcessorTraceEnabled)
|
|
{
|
|
HyperTracePtDisable(NULL);
|
|
}
|
|
|
|
//
|
|
// Free PT buffers (if any) and the per-CPU state list
|
|
//
|
|
if (g_PtStateList != NULL)
|
|
{
|
|
UINT32 ProcessorsCountLocal = KeQueryActiveProcessorCount(0);
|
|
UINT32 i;
|
|
|
|
for (i = 0; i < ProcessorsCountLocal; i++)
|
|
{
|
|
PtEngineFreeBuffers(&g_PtStateList[i]);
|
|
}
|
|
|
|
PlatformMemFreePool(g_PtStateList);
|
|
g_PtStateList = NULL;
|
|
}
|
|
|
|
//
|
|
// Reset the environment flag to default value
|
|
//
|
|
g_RunningOnHypervisorEnvironment = FALSE;
|
|
|
|
//
|
|
// Set callbacks to not initialized
|
|
//
|
|
g_HyperTraceCallbacksInitialized = FALSE;
|
|
}
|