HyperDbg Debugger
Loading...
Searching...
No Matches
LbrApi.c File Reference

Tracing routines for HyperTrace module (Intel Last Branch Record). More...

#include "pch.h"

Functions

VOID HyperTraceLbrExamplePerformTrace ()
 Example of performing LBR trace.
BOOLEAN HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls (UINT32 CoreId)
 Query the state of LBR save and load VM exit and entry controls.
VOID HyperTraceLbrSetKernelStatus (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceLbrOperationRequest, UINT32 Status)
 Set the kernel status in the HyperTrace LBR operation request structure.
VOID HyperTraceLbrDumpSetKernelStatus (HYPERTRACE_LBR_DUMP_PACKETS *HyperTraceLbrDumpOperationRequest, UINT32 Status)
 Set the kernel status in the HyperTrace LBR dump operation request structure.
BOOLEAN HyperTraceLbrCheck ()
 Check if LBR is supported and enabled on the current core.
BOOLEAN HyperTraceLbrRestoreByFilter (UINT64 FilterOptions)
 Restore (re-enable) LBR collection on the current core with the specified filter options.
BOOLEAN HyperTraceLbrRestore ()
 Restore (re-enable) LBR collection on the current core with previous filter options.
BOOLEAN HyperTraceLbrIsSupported (UINT32 *Capacity, BOOLEAN *IsArchLbr)
 Check if LBR is supported on the current CPU and get its capacity.
BOOLEAN HyperTraceLbrEnable (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Enable LBR tracing for HyperTrace.
BOOLEAN HyperTraceLbrDisable (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Disable LBR tracing for HyperTrace.
BOOLEAN HyperTraceLbrFlush (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Flush LBR tracing for HyperTrace.
BOOLEAN HyperTraceLbrSave (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Save LBR tracing for HyperTrace.
BOOLEAN HyperTraceLbrPrint (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Print LBR tracing for HyperTrace.
BOOLEAN HyperTraceLbrUpdateFilterOptions (HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
 Update LBR filter options for HyperTrace.
BOOLEAN HyperTraceLbrPerformDump (HYPERTRACE_LBR_DUMP_PACKETS *LbrDumpRequest)
 Perform actions related to HyperTrace LBR dumping.
BOOLEAN HyperTraceLbrPerformOperation (HYPERTRACE_LBR_OPERATION_PACKETS *LbrOperationRequest)
 Perform actions related to HyperTrace LBR operations.

Detailed Description

Tracing routines for HyperTrace module (Intel Last Branch Record).

Author
Hari Mishal (harim.nosp@m.isha.nosp@m.l6@gm.nosp@m.ail..nosp@m.com)
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.18
Date
2025-12-02

Function Documentation

◆ HyperTraceLbrCheck()

BOOLEAN HyperTraceLbrCheck ( )

Check if LBR is supported and enabled on the current core.

Returns
BOOLEAN
105{
106 //
107 // Only check LBR once it is already initialized
108 //
110 {
111 return FALSE;
112 }
113
114 return LbrCheck();
115}
BOOLEAN LbrCheck()
Check if LBR is enabled or not.
Definition Lbr.c:876
#define FALSE
Definition BasicTypes.h:113
BOOLEAN g_LastBranchRecordEnabled
The flag indicating whether the hypertrace LBR tracing is initialized or not.
Definition GlobalVariables.h:48

◆ HyperTraceLbrDisable()

BOOLEAN HyperTraceLbrDisable ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Disable LBR tracing for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
279{
280 //
281 // Check if LBR is already disabled or not
282 //
284 {
286 return FALSE;
287 }
288
289 //
290 // Disabling LBR
291 //
293
294 //
295 // Broadcast disabling LBR on all cores
296 //
298
299 //
300 // Set successful status
301 //
303
304 return TRUE;
305}
VOID HyperTraceLbrSetKernelStatus(HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceLbrOperationRequest, UINT32 Status)
Set the kernel status in the HyperTrace LBR operation request structure.
Definition LbrApi.c:69
#define TRUE
Definition BasicTypes.h:114
#define DEBUGGER_ERROR_LBR_ALREADY_DISABLED
error, LBR is already disabled
Definition ErrorCodes.h:606
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
VOID BroadcastDisableLbrOnAllCores()
Routines to disable LBR on all cores.
Definition Broadcast.c:34

◆ HyperTraceLbrDumpSetKernelStatus()

VOID HyperTraceLbrDumpSetKernelStatus ( HYPERTRACE_LBR_DUMP_PACKETS * HyperTraceLbrDumpOperationRequest,
UINT32 Status )

Set the kernel status in the HyperTrace LBR dump operation request structure.

Parameters
HyperTraceLbrDumpOperationRequestPointer to the HyperTrace LBR dump operation request packet
StatusThe kernel status code to write into the request
Returns
VOID
91{
92 if (HyperTraceLbrDumpOperationRequest != NULL)
93 {
94 HyperTraceLbrDumpOperationRequest->KernelStatus = Status;
95 }
96}
UINT32 KernelStatus
Definition RequestStructures.h:1329

◆ HyperTraceLbrEnable()

BOOLEAN HyperTraceLbrEnable ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Enable LBR tracing for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
201{
202 //
203 // Check if LBR is already enabled or not
204 //
205 // We allow re-enabling LBR even if it is already enabled to support scenarios where
206 // the LBR is deactivated as a result of a #DB and wants to re-enable it again
207 /*
208 if (g_LastBranchRecordEnabled)
209 {
210 HyperTraceLbrSetKernelStatus(HyperTraceOperationRequest, DEBUGGER_ERROR_LBR_ALREADY_ENABLED);
211 return FALSE;
212 }
213 */
214
215 //
216 // Check for ARCHITECTURAL LBR support first, if not supported then check for LEGACY LBR support
217 //
219 {
220 //
221 // If the CPU does not support architectural LBR, we can check for legacy LBR support as a fallback
222 //
224 {
226 return FALSE;
227 }
228 }
229
230 //
231 // Check VMCS support for LBR if the initialization is being done for hypervisor environment
232 //
234 {
235 if ((g_ArchBasedLastBranchRecord && !g_Callbacks.VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()) ||
236 (!g_ArchBasedLastBranchRecord && !g_Callbacks.VmFuncCheckCpuSupportForSaveAndLoadDebugControls()))
237 {
239 return FALSE;
240 }
241 }
242
243 //
244 // Broadcast enabling LBR on all cores
245 //
247
248 //
249 // Check if LBR is enabled or not (for example in VMs, LBR flags are usually masked)
250 //
251 if (!LbrCheck())
252 {
254 return FALSE;
255 }
256
257 //
258 // Set the flag to indicate that LBR tracing is enabled
259 //
261
262 //
263 // Set successful status
264 //
266
267 return TRUE;
268}
BOOLEAN LbrCheckAndReadArchitecturalLbrDetails()
Check if the current CPU supports architectural LBR.
Definition Lbr.c:86
BOOLEAN LbrCheckAndReadLegacyLbrDetails()
Check if the current CPU supports LBR by examining the CPU family and model and looking up the corres...
Definition Lbr.c:177
#define DEBUGGER_ERROR_LBR_NOT_SUPPORTED_ON_VMCS
error, LBR not supported on VMCS
Definition ErrorCodes.h:618
#define DEBUGGER_ERROR_LBR_NOT_SUPPORTED
error, LBR is not supported by the processor
Definition ErrorCodes.h:612
HYPEREVADE_CALLBACKS g_Callbacks
List of callbacks.
Definition Transparency.h:23
VOID BroadcastEnableLbrOnAllCores()
Routines to enable LBR on all cores.
Definition Broadcast.c:20
BOOLEAN g_RunningOnHypervisorEnvironment
The flag indicating whether the initialization is being done for hypervisor environment or not.
Definition GlobalVariables.h:35
BOOLEAN g_ArchBasedLastBranchRecord
The flag indicating whether the architectural LBR is supported by the CPU or not if false it means th...
Definition GlobalVariables.h:42

◆ HyperTraceLbrExamplePerformTrace()

VOID HyperTraceLbrExamplePerformTrace ( )

Example of performing LBR trace.

Returns
VOID
21{
23 {
24 for (volatile int i = 0; i < 50; i++)
25 {
26 if (i % 2)
27 {
28 INT A = i * 2;
29 A += 5;
30 }
31 else
32 {
33 CpuNop();
34 CpuNop();
35 }
36 }
37
38 LogInfo("Dumping LBR Buffer...\n");
39
40 LbrStop();
41 LbrPrint(); // This will print the collected LBR branches to the log
42 }
43}
BOOLEAN LbrStart(UINT64 FilterOptions)
Start collecting LBR branches.
Definition Lbr.c:903
VOID LbrStop()
Stop collecting LBR branches.
Definition Lbr.c:983
VOID LbrPrint()
Print collected LBR branches.
Definition Lbr.c:1194
#define LBR_SELECT_WITHOUT_FILTER
Definition Lbr.h:27
VOID CpuNop(VOID)
Execute NOP.
Definition PlatformIntrinsics.c:508
int INT
Definition BasicTypes.h:43
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71

◆ HyperTraceLbrFlush()

BOOLEAN HyperTraceLbrFlush ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Flush LBR tracing for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
316{
317 //
318 // Check if LBR is already disabled or not
319 //
321 {
323 return FALSE;
324 }
325
326 //
327 // Disabling LBR
328 //
330
331 //
332 // Broadcast flushing LBR on all cores
333 //
335
336 //
337 // Set successful status
338 //
340
341 return TRUE;
342}
VOID BroadcastFlushLbrOnAllCores()
Routines to flush LBR on all cores.
Definition Broadcast.c:48

◆ HyperTraceLbrIsSupported()

BOOLEAN HyperTraceLbrIsSupported ( UINT32 * Capacity,
BOOLEAN * IsArchLbr )

Check if LBR is supported on the current CPU and get its capacity.

Parameters
CapacityPointer to a variable to receive the LBR capacity (number of entries)
IsArchLbrPointer to a variable to receive whether the supported LBR is architectural LBR or not (legacy LBR)
Returns
BOOLEAN
158{
159 //
160 // Check for ARCHITECTURAL LBR support first, if not supported then check for LEGACY LBR support
161 //
163 {
164 //
165 // If the CPU does not support architectural LBR, we can check for legacy LBR support as a fallback
166 //
168 {
169 return FALSE;
170 }
171 }
172
173 //
174 // Set capacity when the pointer is valid
175 //
176 if (Capacity != NULL)
177 {
178 *Capacity = (UINT32)g_LbrCapacity;
179 }
180
181 //
182 // Set IsArchLbr when the pointer is valid
183 //
184 if (IsArchLbr != NULL)
185 {
186 *IsArchLbr = g_ArchBasedLastBranchRecord;
187 }
188
189 return TRUE;
190}
unsigned int UINT32
Definition BasicTypes.h:54
ULONGLONG g_LbrCapacity
The global variable to hold the LBR capacity of the current CPU.
Definition GlobalVariables.h:60

◆ HyperTraceLbrPerformDump()

BOOLEAN HyperTraceLbrPerformDump ( HYPERTRACE_LBR_DUMP_PACKETS * LbrDumpRequest)

Perform actions related to HyperTrace LBR dumping.

Parameters
LbrDumpRequest
Returns
BOOLEAN
458{
459 ULONG ProcessorsCount;
460
461 //
462 // Check if LBR is enabled or not before dumping
463 //
465 {
467 return FALSE;
468 }
469
470 //
471 // Get the number of processors in the system to validate the requested core id for dumping
472 //
473 ProcessorsCount = KeQueryActiveProcessorCount(0);
474
475 //
476 // Check if core id is valid
477 //
478 if (LbrDumpRequest->CoreId >= ProcessorsCount)
479 {
481 return FALSE;
482 }
483
484 //
485 // Check if next core is valid in the case of dumping all cores
486 //
487 if (LbrDumpRequest->CoreId == ProcessorsCount - 1)
488 {
489 LbrDumpRequest->NextCoreIsValid = FALSE;
490 }
491 else
492 {
493 LbrDumpRequest->NextCoreIsValid = TRUE;
494 }
495
496 //
497 // Set ARCH or LEGACY LBR flag in the dump request structure based on the type of LBR supported by the CPU
498 //
500
501 //
502 // Set the current LBR capacity in the dump request structure based on the type of LBR supported by the CPU
503 //
504 LbrDumpRequest->CurrentLbrCapacity = (UINT8)g_LbrCapacity;
505
506 //
507 // Copy the LBR stack entries of the requested core into the dump request structure to be sent back to usermode
508 //
509 RtlCopyMemory(&LbrDumpRequest->LbrStack, &g_LbrStateList[LbrDumpRequest->CoreId], sizeof(LBR_STACK_ENTRY));
510
511 //
512 // Set successful status
513 //
515
516 return TRUE;
517}
VOID HyperTraceLbrDumpSetKernelStatus(HYPERTRACE_LBR_DUMP_PACKETS *HyperTraceLbrDumpOperationRequest, UINT32 Status)
Set the kernel status in the HyperTrace LBR dump operation request structure.
Definition LbrApi.c:88
unsigned char UINT8
Definition BasicTypes.h:52
unsigned long ULONG
Definition BasicTypes.h:31
#define DEBUGGER_ERROR_INVALID_CORE_ID
error, the core id is invalid
Definition ErrorCodes.h:69
struct _LBR_STACK_ENTRY LBR_STACK_ENTRY
The structure to hold the LBR stack for a single processor core, including the branch entries and the...
LBR_STACK_ENTRY * g_LbrStateList
This will be a dynamically allocated array to hold LBR states for each core.
Definition GlobalVariables.h:54
BOOLEAN NextCoreIsValid
Definition RequestStructures.h:1325
UINT8 CurrentLbrCapacity
Definition RequestStructures.h:1328
LBR_STACK_ENTRY LbrStack
Definition RequestStructures.h:1327
BOOLEAN ArchBasedLBR
Definition RequestStructures.h:1326
UINT32 CoreId
Definition RequestStructures.h:1324

◆ HyperTraceLbrPerformOperation()

BOOLEAN HyperTraceLbrPerformOperation ( HYPERTRACE_LBR_OPERATION_PACKETS * LbrOperationRequest)

Perform actions related to HyperTrace LBR operations.

Parameters
LbrOperationRequest
Returns
BOOLEAN
528{
529 BOOLEAN Status = TRUE;
530
531 //
532 // Check if the hypertrace module is initialized before performing any operation
533 //
535 {
537 return FALSE;
538 }
539
540 //
541 // Perform the requested operation
542 //
543 switch (LbrOperationRequest->LbrOperationType)
544 {
546
547 // LogInfo("HyperTrace: Enabling LBR tracing...\n");
548
549 HyperTraceLbrEnable(LbrOperationRequest);
550
551 break;
552
554
555 // LogInfo("HyperTrace: Disabling LBR tracing...\n");
556
557 HyperTraceLbrDisable(LbrOperationRequest);
558
559 break;
560
562
563 // LogInfo("HyperTrace: Flushing LBR tracing...\n");
564
565 HyperTraceLbrFlush(LbrOperationRequest);
566
567 break;
568
570
571 // LogInfo("HyperTrace: Updating LBR filter options...\n");
572
573 HyperTraceLbrUpdateFilterOptions(LbrOperationRequest);
574
575 break;
576
577 default:
578
579 Status = FALSE;
581
582 break;
583 }
584
585 return Status;
586}
BOOLEAN HyperTraceLbrEnable(HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
Enable LBR tracing for HyperTrace.
Definition LbrApi.c:200
BOOLEAN HyperTraceLbrDisable(HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
Disable LBR tracing for HyperTrace.
Definition LbrApi.c:278
BOOLEAN HyperTraceLbrFlush(HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
Flush LBR tracing for HyperTrace.
Definition LbrApi.c:315
BOOLEAN HyperTraceLbrUpdateFilterOptions(HYPERTRACE_LBR_OPERATION_PACKETS *HyperTraceOperationRequest)
Update LBR filter options for HyperTrace.
Definition LbrApi.c:425
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define DEBUGGER_ERROR_INVALID_HYPERTRACE_OPERATION_TYPE
error, invalid HyperTrace operation type is specified in the request
Definition ErrorCodes.h:594
#define DEBUGGER_ERROR_HYPERTRACE_NOT_INITIALIZED
error, HyperTrace is not initialized
Definition ErrorCodes.h:588
@ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FILTER
Definition RequestStructures.h:1290
@ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_FLUSH
Definition RequestStructures.h:1288
@ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_DISABLE
Definition RequestStructures.h:1287
@ HYPERTRACE_LBR_OPERATION_REQUEST_TYPE_ENABLE
Definition RequestStructures.h:1286
BOOLEAN g_HyperTraceCallbacksInitialized
The flag indicating whether the hypertrace module callbacks is initialized or not.
Definition GlobalVariables.h:29
HYPERTRACE_LBR_OPERATION_REQUEST_TYPE LbrOperationType
Definition RequestStructures.h:1303

◆ HyperTraceLbrPrint()

BOOLEAN HyperTraceLbrPrint ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Print LBR tracing for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
387{
388 //
389 // Check if LBR is already disabled or not
390 //
392 {
394 return FALSE;
395 }
396
397 // LogInfo("Dumping LBR Buffer...\n");
398
399 //
400 // Save the LBR state
401 //
402 LbrSave();
403
404 //
405 // This will print the collected LBR branches to the log
406 //
407 LbrPrint();
408
409 //
410 // The operation was successful
411 //
413
414 return TRUE;
415}
VOID LbrSave()
Save LBR branches.
Definition Lbr.c:1091

◆ HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls()

BOOLEAN HyperTraceLbrQueryStateOfLbrSaveAndLoadVmExitAndEntryControls ( UINT32 CoreId)

Query the state of LBR save and load VM exit and entry controls.

Parameters
CoreIdThe index of the processor core to query
Returns
BOOLEAN
54{
55 UNREFERENCED_PARAMETER(CoreId); // Right now there is no core specifc controls for LBR
56
58}

◆ HyperTraceLbrRestore()

BOOLEAN HyperTraceLbrRestore ( )

Restore (re-enable) LBR collection on the current core with previous filter options.

Returns
BOOLEAN
144{
146}
BOOLEAN HyperTraceLbrRestoreByFilter(UINT64 FilterOptions)
Restore (re-enable) LBR collection on the current core with the specified filter options.
Definition LbrApi.c:124
UINT64 g_LbrFilterOptions
The global variable to hold the current LBR filter options bitmask (for both architectural and legacy...
Definition GlobalVariables.h:72

◆ HyperTraceLbrRestoreByFilter()

BOOLEAN HyperTraceLbrRestoreByFilter ( UINT64 FilterOptions)

Restore (re-enable) LBR collection on the current core with the specified filter options.

Parameters
FilterOptionsA bitmask of filter options to apply to the LBR branches
Returns
BOOLEAN
125{
126 //
127 // Only restore (re-enable) LBR once it is already initialized
128 //
130 {
131 return FALSE;
132 }
133
134 return LbrStart(FilterOptions);
135}

◆ HyperTraceLbrSave()

BOOLEAN HyperTraceLbrSave ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Save LBR tracing for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
353{
354 //
355 // Check if LBR is already disabled or not
356 //
358 {
360 return FALSE;
361 }
362
363 // LogInfo("Saving LBR Buffer...\n");
364
365 //
366 // Save the LBR state
367 //
368 LbrSave();
369
370 //
371 // The operation was successful
372 //
374
375 return TRUE;
376}

◆ HyperTraceLbrSetKernelStatus()

VOID HyperTraceLbrSetKernelStatus ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceLbrOperationRequest,
UINT32 Status )

Set the kernel status in the HyperTrace LBR operation request structure.

Parameters
HyperTraceLbrOperationRequestPointer to the HyperTrace LBR operation request packet
StatusThe kernel status code to write into the request
Returns
VOID
72{
73 if (HyperTraceLbrOperationRequest != NULL)
74 {
75 HyperTraceLbrOperationRequest->KernelStatus = Status;
76 }
77}
UINT32 KernelStatus
Definition RequestStructures.h:1305

◆ HyperTraceLbrUpdateFilterOptions()

BOOLEAN HyperTraceLbrUpdateFilterOptions ( HYPERTRACE_LBR_OPERATION_PACKETS * HyperTraceOperationRequest)

Update LBR filter options for HyperTrace.

Parameters
HyperTraceOperationRequest
Returns
BOOLEAN
426{
427 //
428 // Check if LBR is already disabled or not
429 //
431 {
433 return FALSE;
434 }
435
436 //
437 // Update the LBR filter options based on the request
438 //
439 BroadcastFilterLbrOptionsOnAllCores((UINT64)HyperTraceOperationRequest->LbrFilterOptions);
440
441 //
442 // The operation was successful
443 //
445
446 return TRUE;
447}
VOID BroadcastFilterLbrOptionsOnAllCores(UINT64 LbrFilterOptions)
Routines to filter LBR option on all cores.
Definition Broadcast.c:64
UINT32 LbrFilterOptions
Definition RequestStructures.h:1304