HyperDbg Debugger
Loading...
Searching...
No Matches
Lbr.h File Reference

Message logging and tracing implementation. More...

Go to the source code of this file.

Classes

union  _CPUID28_EAX
union  _CPUID28_EBX
union  _CPUID28_ECX
struct  _CPUID28_LEAFS
union  _IA32_LBR_CTL_REGISTER
 The structure to hold the IA32_LBR_CTL MSR, which is used to enable and configure the LBR feature. More...
struct  _CPU_LBR_MAP
 The structure to hold the mapping of CPU model to its LBR capacity. More...

Macros

#define MSR_LEGACY_LBR_SELECT   0x000001C8
#define MSR_LBR_TOS   0x000001C9
#define MSR_LASTBRANCH_0_FROM_IP   0x00000680
#define MSR_LASTBRANCH_0_TO_IP   0x000006C0
#define MSR_LASTBRANCH_INFO_0   0x00000DC0
#define LBR_SELECT_WITHOUT_FILTER   0x00000000
#define IA32_LBR_0_FROM_IP   0x1500
#define IA32_LBR_0_TO_IP   0x1600
#define IA32_LBR_0_INFO   0x1200
#define CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION   0x1c
#define IA32_LBR_CTL   0x000014CE

Typedefs

typedef union _CPUID28_EAX CPUID28_EAX
typedef union _CPUID28_EAXPCPUID28_EAX
typedef union _CPUID28_EBX CPUID28_EBX
typedef union _CPUID28_EBXPCPUID28_EBX
typedef union _CPUID28_ECX CPUID28_ECX
typedef union _CPUID28_ECXPCPUID28_ECX
typedef struct _CPUID28_LEAFS CPUID28_LEAFS
typedef struct _CPUID28_LEAFSPCPUID28_LEAFS
typedef union _IA32_LBR_CTL_REGISTER IA32_LBR_CTL_REGISTER
 The structure to hold the IA32_LBR_CTL MSR, which is used to enable and configure the LBR feature.
typedef union _IA32_LBR_CTL_REGISTERPIA32_LBR_CTL_REGISTER
typedef struct _CPU_LBR_MAP CPU_LBR_MAP
 The structure to hold the mapping of CPU model to its LBR capacity.
typedef struct _CPU_LBR_MAPPCPU_LBR_MAP

Functions

BOOLEAN LbrCheckAndReadLegacyLbrDetails ()
 Check if the current CPU supports LBR by examining the CPU family and model and looking up the corresponding LBR capacity.
BOOLEAN LbrCheckAndReadArchitecturalLbrDetails ()
 Check if the current CPU supports architectural LBR.
BOOLEAN LbrStart (UINT64 FilterOptions)
 Start collecting LBR branches.
BOOLEAN LbrCheck ()
 Check if LBR is enabled or not.
VOID LbrFilter (UINT64 FilterOptions)
 Filter LBR branches based on the provided options.
VOID LbrStop ()
 Stop collecting LBR branches.
VOID LbrFlush ()
 Flush LBR MSRs by disabling LBR and clearing all LBR entries.
VOID LbrSave ()
 Save LBR branches.
VOID LbrPrint ()
 Print collected LBR branches.

Variables

CPU_LBR_MAP CPU_LBR_MAPS []
 The global variable to hold the mapping of CPU model to its LBR capacity.

Detailed Description

Message logging and tracing implementation.

Author
Hari Mishal (harim.nosp@m.isha.nosp@m.l6@gm.nosp@m.ail..nosp@m.com)

Modified from LIBIHT project (Thomasaon Zhao et al) with Windows style updates.

Version
0.18
Date
2025-12-02

Macro Definition Documentation

◆ CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION

#define CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION   0x1c

◆ IA32_LBR_0_FROM_IP

#define IA32_LBR_0_FROM_IP   0x1500

◆ IA32_LBR_0_INFO

#define IA32_LBR_0_INFO   0x1200

◆ IA32_LBR_0_TO_IP

#define IA32_LBR_0_TO_IP   0x1600

◆ IA32_LBR_CTL

#define IA32_LBR_CTL   0x000014CE

◆ LBR_SELECT_WITHOUT_FILTER

#define LBR_SELECT_WITHOUT_FILTER   0x00000000

◆ MSR_LASTBRANCH_0_FROM_IP

#define MSR_LASTBRANCH_0_FROM_IP   0x00000680

◆ MSR_LASTBRANCH_0_TO_IP

#define MSR_LASTBRANCH_0_TO_IP   0x000006C0

◆ MSR_LASTBRANCH_INFO_0

#define MSR_LASTBRANCH_INFO_0   0x00000DC0

◆ MSR_LBR_TOS

#define MSR_LBR_TOS   0x000001C9

◆ MSR_LEGACY_LBR_SELECT

#define MSR_LEGACY_LBR_SELECT   0x000001C8

Typedef Documentation

◆ CPU_LBR_MAP

typedef struct _CPU_LBR_MAP CPU_LBR_MAP

The structure to hold the mapping of CPU model to its LBR capacity.

◆ CPUID28_EAX

typedef union _CPUID28_EAX CPUID28_EAX

◆ CPUID28_EBX

typedef union _CPUID28_EBX CPUID28_EBX

◆ CPUID28_ECX

typedef union _CPUID28_ECX CPUID28_ECX

◆ CPUID28_LEAFS

typedef struct _CPUID28_LEAFS CPUID28_LEAFS

◆ IA32_LBR_CTL_REGISTER

The structure to hold the IA32_LBR_CTL MSR, which is used to enable and configure the LBR feature.

MSR Address: 0x14CEH (Hex) / 5326 (Dec)

◆ PCPU_LBR_MAP

typedef struct _CPU_LBR_MAP * PCPU_LBR_MAP

◆ PCPUID28_EAX

typedef union _CPUID28_EAX * PCPUID28_EAX

◆ PCPUID28_EBX

typedef union _CPUID28_EBX * PCPUID28_EBX

◆ PCPUID28_ECX

typedef union _CPUID28_ECX * PCPUID28_ECX

◆ PCPUID28_LEAFS

typedef struct _CPUID28_LEAFS * PCPUID28_LEAFS

◆ PIA32_LBR_CTL_REGISTER

Function Documentation

◆ LbrCheck()

BOOLEAN LbrCheck ( )

Check if LBR is enabled or not.

Returns
BOOLEAN
877{
878 BOOLEAN IsOnVmxRootMode = FALSE;
879
881 {
882 IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
883 }
884
885 if (IsOnVmxRootMode)
886 {
887 return LbrCheckOnVmxRootMode();
888 }
889 else
890 {
892 }
893}
BOOLEAN LbrCheckOnNativeOrVmxNonRootMode()
Check if LBR is enabled while in native mode or VMX non-root mode.
Definition Lbr.c:853
BOOLEAN LbrCheckOnVmxRootMode()
Check if LBR is enabled while in VMX root-mode.
Definition Lbr.c:830
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define FALSE
Definition BasicTypes.h:113
HYPEREVADE_CALLBACKS g_Callbacks
List of callbacks.
Definition Transparency.h:23
BOOLEAN g_RunningOnHypervisorEnvironment
The flag indicating whether the initialization is being done for hypervisor environment or not.
Definition GlobalVariables.h:35

◆ LbrCheckAndReadArchitecturalLbrDetails()

BOOLEAN LbrCheckAndReadArchitecturalLbrDetails ( )

Check if the current CPU supports architectural LBR.

Returns
BOOLEAN
87{
88 ULONG a, b, c, d;
89
90 CPUID_EAX_07 Edx07 = {0};
91
92 CPUID28_EAX Eax1c = {0};
93 CPUID28_EBX Ebx1c = {0};
94 CPUID28_ECX Ecx1c = {0};
95
96 //
97 // Check for Architectural LBR support
98 //
99 //
100 xcpuidex(CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0x00, &a, &b, &c, &d);
101
102 Edx07.Edx.AsUInt = d;
103
104 //
105 // CPUID.07H.00H:EDX[19] == 1 means arch LBR is supported
106 //
107 if (Edx07.Edx.AsUInt & (1 << 19))
108 {
110 }
111 else
112 {
113 //
114 // Architectural LBR is not supported by the CPU
115 //
117
118 return FALSE;
119 }
120
121 //
122 // Being here means the CPU supports architectural LBR, we can read the LBR capabilities from CPUID 0x1c leaf
123 //
125
126 //
127 // Assign LBR leafs to structure for easier access
128 //
129 Eax1c.AsUInt = a;
130 Ebx1c.AsUInt = b;
131 Ecx1c.AsUInt = c;
132
133 //
134 // Store the CPUID.1CH leaf information in a global structure for later use
135 //
136 g_Cpuid28Leafs.Eax = Eax1c;
137 g_Cpuid28Leafs.Ebx = Ebx1c;
138 g_Cpuid28Leafs.Ecx = Ecx1c;
139 g_Cpuid28Leafs.Edx = d;
140
141 //
142 // Read LBR capacity from CPUID.1CH.00H:EAX[7:0]
143 // Based on Intel SDM: For each bit n set in this field, the IA32_LBR_DEPTH.DEPTH value 8 * (n + 1) is supported
144 //
145 if (Eax1c.LbrDepthMask)
146 {
147 //
148 // Get the highest set bit in LbrDepthMask to determine the maximum supported LBR depth
149 //
150 ULONG HighestSetBit = 0;
151 for (ULONG i = 0; i < 8; i++)
152 {
153 if (Eax1c.LbrDepthMask & (1 << i))
154 {
155 HighestSetBit = i;
156 }
157 }
158 g_LbrCapacity = 8 * (HighestSetBit + 1);
159 }
160 else
161 {
162 //
163 // If LbrDepthMask is 0, it means the CPU supports architectural LBR but does not specify the depth, we can assume a default value (e.g., 16 or 32) or treat it as unsupported
164 //
165 g_LbrCapacity = MAXIMUM_LBR_CAPACITY; // Assuming a default capacity of MAXIMUM_LBR_CAPACITY if not specified
166 }
167
168 return TRUE;
169}
#define CPUID_ARCH_LAST_BRANCH_RECORD_INFORMATION
Definition Lbr.h:36
union _CPUID28_EBX CPUID28_EBX
union _CPUID28_ECX CPUID28_ECX
union _CPUID28_EAX CPUID28_EAX
#define xcpuidex(code, subleaf, a, b, c, d)
Definition TraceApi.h:39
#define TRUE
Definition BasicTypes.h:114
unsigned long ULONG
Definition BasicTypes.h:31
#define MAXIMUM_LBR_CAPACITY
Maximum LBR capacity that is supported by processors.
Definition LbrDefinitions.h:27
ULONGLONG g_LbrCapacity
The global variable to hold the LBR capacity of the current CPU.
Definition GlobalVariables.h:60
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
CPUID28_LEAFS g_Cpuid28Leafs
The global variable to hold CPUID leaf 0x28 information (Architectural LBR Enumeration Leaf).
Definition GlobalVariables.h:66
UINT32 AsUInt
Definition Lbr.h:64
UINT32 LbrDepthMask
Definition Lbr.h:57
UINT32 AsUInt
Definition Lbr.h:79
UINT32 AsUInt
Definition Lbr.h:94

◆ LbrCheckAndReadLegacyLbrDetails()

BOOLEAN LbrCheckAndReadLegacyLbrDetails ( )

Check if the current CPU supports LBR by examining the CPU family and model and looking up the corresponding LBR capacity.

Returns
BOOLEAN
178{
179 ULONG a, b, c, d;
180 ULONG Family, Model;
181 ULONGLONG i;
182
183 xcpuid(1, &a, &b, &c, &d);
184
185 Family = ((a >> 8) & 0xF) + ((a >> 20) & 0xFF);
186 Model = ((a >> 4) & 0xF) | ((a >> 12) & 0xF0);
187
188 for (i = 0; i < sizeof(CPU_LBR_MAPS) / sizeof(CPU_LBR_MAPS[0]); ++i)
189 {
190 if (Model == CPU_LBR_MAPS[i].Model)
191 {
192 g_LbrCapacity = CPU_LBR_MAPS[i].LbrCapacity;
193 break;
194 }
195 }
196
197 if (g_LbrCapacity == 0)
198 {
199 return FALSE;
200 }
201
202 return TRUE;
203}
CPU_LBR_MAP CPU_LBR_MAPS[]
The global variable to hold the mapping of CPU model to its LBR capacity.
Definition Lbr.c:21
#define xcpuid(code, a, b, c, d)
Definition TraceApi.h:29

◆ LbrFilter()

VOID LbrFilter ( UINT64 FilterOptions)

Filter LBR branches based on the provided options.

Parameters
FilterOptionsA bitmask of filter options to apply to the LBR branches
Returns
VOID
1071{
1072 // LogInfo("Updating LBR filter options: 0x%llx\n", FilterOptions);
1073
1074 //
1075 // First, we flush the LBR to clear out any existing entries that may not meet the new filter criteria
1076 //
1077 LbrFlush();
1078
1079 //
1080 // Then we apply the new filter options and re-enable LBR with the updated filter settings
1081 //
1082 LbrStart(FilterOptions);
1083}
VOID LbrFlush()
Flush LBR MSRs by disabling LBR and clearing all LBR entries.
Definition Lbr.c:1041
BOOLEAN LbrStart(UINT64 FilterOptions)
Start collecting LBR branches.
Definition Lbr.c:903

◆ LbrFlush()

VOID LbrFlush ( )

Flush LBR MSRs by disabling LBR and clearing all LBR entries.

Returns
VOID
1042{
1043 // LogInfo("Flush LBR on cpu core: %d\n", KeGetCurrentProcessorNumberEx(NULL));
1044
1045 //
1046 // Stop LBR collection and save any remaining entries
1047 //
1048 LbrStop();
1049
1050 //
1051 // Reset the LBR control registers to zero:
1052 // - ARCH LBR: zeroes IA32_LBR_CTL entirely (clears filters and disables collection)
1053 // - Legacy LBR: zeroes MSR_LEGACY_LBR_SELECT (resets branch filter to capture-all)
1054 //
1056
1057 //
1058 // Clear all remaining hardware state (TOS for legacy LBR, and all from/to MSR pairs)
1059 //
1061}
VOID LbrStop()
Stop collecting LBR branches.
Definition Lbr.c:983
VOID LbrClearHardwareState()
Zero out the LBR hardware state (TOS and all from/to MSR pairs).
Definition Lbr.c:386
VOID LbrResetControlRegisters()
Reset the LBR control registers to zero, covering both ARCH and legacy LBR across all execution envir...
Definition Lbr.c:673

◆ LbrPrint()

VOID LbrPrint ( )

Print collected LBR branches.

Returns
VOID
1195{
1196 ULONG CurrentIdx;
1197 LBR_STACK_ENTRY * State;
1198 UINT32 CurrentCore = 0;
1199 CHAR BrTypeName[LBR_BR_TYPE_NAME_MAX_LEN] = {0};
1200 UINT32 BrType = 0;
1201 //
1202 // Get the current core id
1203 //
1204 CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
1205
1206 //
1207 // Get the current processor LBR stack
1208 //
1209 State = &g_LbrStateList[CurrentCore];
1210
1211 Log("LBR Chronological Trace on core : 0x%x\n\n", CurrentCore);
1212
1213 for (ULONG i = 1; i <= g_LbrCapacity; i++)
1214 {
1216 {
1217 //
1218 // In ARCH LBR, there is not TOS index and everything is in order
1219 //
1220 CurrentIdx = i - 1;
1221 }
1222 else
1223 {
1224 CurrentIdx = (ULONG)(State->Tos + i) % (ULONG)g_LbrCapacity;
1225 }
1226
1227 if (State->BranchEntry[CurrentIdx].From == 0)
1228 {
1229 continue;
1230 }
1231
1233 {
1234 BrType = (UINT32)State->LastBranchInfo[CurrentIdx].BrType_OnlyArchLbr;
1235
1236 //
1237 // Get the branch type name for better readability when printing
1238 //
1239 LbrGetArchBranchType(BrType, BrTypeName);
1240
1241 //
1242 // Architectural LBR
1243 //
1244 Log("\t [%2u] Branch Mispredicted: %s, Branch type: %s, Cycle Count (Decimal): %04d (is valid? %s) - From: %016llx To: %016llx\n",
1245 CurrentIdx,
1246 State->LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
1247 BrTypeName,
1248 State->LastBranchInfo[CurrentIdx].CycleCount,
1249 State->LastBranchInfo[CurrentIdx].CycCntValid_OnlyArchLbr ? "true " : "false",
1250 State->BranchEntry[CurrentIdx].From,
1251 State->BranchEntry[CurrentIdx].To);
1252 }
1253 else
1254 {
1255 //
1256 // Legacy LBR
1257 //
1258 Log("\t [%2u] Branch Mispredicted: %s, Cycle Count (Decimal): %04d - From: %016llx To: %016llx\n",
1259 CurrentIdx,
1260 State->LastBranchInfo[CurrentIdx].Mispred ? "true " : "false",
1261 State->LastBranchInfo[CurrentIdx].CycleCount,
1262 State->BranchEntry[CurrentIdx].From,
1263 State->BranchEntry[CurrentIdx].To);
1264 }
1265 }
1266}
VOID LbrGetArchBranchType(UINT32 BrType, CHAR *BrTypeName)
Get the branch type name based on the LBR branch type value (only applicable for architectural LBR).
Definition Lbr.c:1148
unsigned int UINT32
Definition BasicTypes.h:54
char CHAR
Definition BasicTypes.h:33
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...
#define LBR_BR_TYPE_NAME_MAX_LEN
Definition LbrDefinitions.h:81
#define Log(format,...)
Log without any prefix.
Definition HyperDbgHyperLogIntrinsics.h:129
LBR_STACK_ENTRY * g_LbrStateList
This will be a dynamically allocated array to hold LBR states for each core.
Definition GlobalVariables.h:54
ULONGLONG From
Definition LbrDefinitions.h:156
ULONGLONG To
Definition LbrDefinitions.h:157
MSR_LBR_INFO LastBranchInfo[MAXIMUM_LBR_CAPACITY]
Definition LbrDefinitions.h:168
UINT8 Tos
Definition LbrDefinitions.h:169
LBR_BRANCH_ENTRY BranchEntry[MAXIMUM_LBR_CAPACITY]
Definition LbrDefinitions.h:167
UINT64 Mispred
Definition LbrDefinitions.h:141
UINT64 BrType_OnlyArchLbr
Definition LbrDefinitions.h:113
UINT64 CycCntValid_OnlyArchLbr
Definition LbrDefinitions.h:116
UINT64 CycleCount
Definition LbrDefinitions.h:95

◆ LbrSave()

VOID LbrSave ( )

Save LBR branches.

Returns
VOID
1092{
1093 UINT64 LbrTos;
1094 LBR_STACK_ENTRY * State;
1095 UINT32 CurrentCore = 0;
1096
1097 //
1098 // Get the current core id
1099 //
1100 CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
1101
1102 //
1103 // Get the current processor LBR stack
1104 //
1105 State = &g_LbrStateList[CurrentCore];
1106
1107 //
1108 // Read and store the current TOS index to know where the most recent branch is stored
1109 // Note that there is no TOS index in ARCH LBR since everything is in order
1110 //
1112 {
1113 xrdmsr(MSR_LBR_TOS, &LbrTos);
1114 State->Tos = (UINT8)LbrTos;
1115 }
1116
1117 //
1118 // Dump LBR entries into the current core's state structure
1119 //
1120 for (ULONG i = 0; i < (ULONG)g_LbrCapacity; i++)
1121 {
1123 {
1124 xrdmsr(IA32_LBR_0_FROM_IP + i, &State->BranchEntry[i].From);
1125 xrdmsr(IA32_LBR_0_TO_IP + i, &State->BranchEntry[i].To);
1127 }
1128 else
1129 {
1133 }
1134 }
1135}
#define IA32_LBR_0_FROM_IP
Definition Lbr.h:32
#define IA32_LBR_0_TO_IP
Definition Lbr.h:33
#define MSR_LASTBRANCH_INFO_0
Definition Lbr.h:26
#define IA32_LBR_0_INFO
Definition Lbr.h:34
#define MSR_LASTBRANCH_0_FROM_IP
Definition Lbr.h:24
#define MSR_LBR_TOS
Definition Lbr.h:23
#define MSR_LASTBRANCH_0_TO_IP
Definition Lbr.h:25
#define xrdmsr(msr, pval)
Definition TraceApi.h:25
unsigned char UINT8
Definition BasicTypes.h:52
UINT64 AsUInt
Definition LbrDefinitions.h:143

◆ LbrStart()

BOOLEAN LbrStart ( UINT64 FilterOptions)

Start collecting LBR branches.

Parameters
FilterOptionsA bitmask of filter options to apply to the LBR branches (e.g., filtering by branch type, privilege level, etc.)
Returns
BOOLEAN
904{
905 BOOLEAN IsOnVmxRootMode;
906 IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
907 ULONGLONG DbgCtlMsr = 0;
908
909 if (g_LbrCapacity == 0)
910 {
911 LogInfo("Err, LBR aborting, CPU model not supported\n");
912 return FALSE;
913 }
914
915 //
916 // Adjust and set filter options
917 //
918 LbrAdjustFilterOptions(FilterOptions, &Ia32LbrCtl);
919
920 //
921 // Clear hardware state before enabling LBR
922 //
924
926 {
927 IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
928
929 //
930 // DEBUGCTL is not involved in ARCH LBR - it has its own dedicated control register
931 // So for ARCH LBR we skip reading the previous value and build the register from scratch (replacing it)
932 //
934 {
935 if (IsOnVmxRootMode)
936 {
937 LbrGetValuesOnVmxRootMode(&DbgCtlMsr, &Ia32LbrCtl);
938 }
939 else
940 {
941 LbrGetValuesOnVmxNonRootMode(&DbgCtlMsr, &Ia32LbrCtl);
942 }
943 }
944
945 //
946 // Apply the appropriate bit to enable LBR based on whether it is architectural LBR or legacy LBR
947 //
949 {
950 LbrEnableArchBased(&Ia32LbrCtl);
951 }
952 else
953 {
954 LbrEnableLegacyBased(&DbgCtlMsr);
955 }
956
957 //
958 // Write the updated LBR control register values back based on the current VMX execution mode
959 //
960 if (IsOnVmxRootMode)
961 {
962 LbrSetValuesOnVmxRootMode(DbgCtlMsr, Ia32LbrCtl);
963 }
964 else
965 {
966 LbrSetValuesOnVmxNonRootMode(DbgCtlMsr, Ia32LbrCtl);
967 }
968 }
969 else
970 {
971 LbrStartOnNativeMode(Ia32LbrCtl);
972 }
973
974 return TRUE;
975}
VOID LbrGetValuesOnVmxNonRootMode(ULONGLONG *DbgCtlMsr, IA32_LBR_CTL_REGISTER *Ia32LbrCtl)
Read current LBR control register values while in VMX non-root mode (via VMCALL).
Definition Lbr.c:505
VOID LbrStartOnNativeMode(IA32_LBR_CTL_REGISTER Ia32LbrCtl)
Start LBR collection when running natively (outside any hypervisor environment).
Definition Lbr.c:451
VOID LbrAdjustFilterOptions(UINT64 FilterOptions, IA32_LBR_CTL_REGISTER *Ia32LbrCtl)
Adjust filter options.
Definition Lbr.c:770
VOID LbrEnableArchBased(IA32_LBR_CTL_REGISTER *Ia32LbrCtl)
Enable LBR collection on architectural (ARCH) based LBR.
Definition Lbr.c:422
VOID LbrSetValuesOnVmxRootMode(ULONGLONG DbgCtlMsr, IA32_LBR_CTL_REGISTER Ia32LbrCtl)
Write back modified LBR control register values while in VMX root-mode.
Definition Lbr.c:555
VOID LbrSetValuesOnVmxNonRootMode(ULONGLONG DbgCtlMsr, IA32_LBR_CTL_REGISTER Ia32LbrCtl)
Write back modified LBR control register values while in VMX non-root mode (via VMCALL).
Definition Lbr.c:581
VOID LbrGetValuesOnVmxRootMode(ULONGLONG *DbgCtlMsr, IA32_LBR_CTL_REGISTER *Ia32LbrCtl)
Read current LBR control register values while in VMX root-mode.
Definition Lbr.c:479
VOID LbrEnableLegacyBased(ULONGLONG *DbgCtlMsr)
Enable LBR collection on legacy based LBR.
Definition Lbr.c:434
union _IA32_LBR_CTL_REGISTER IA32_LBR_CTL_REGISTER
The structure to hold the IA32_LBR_CTL MSR, which is used to enable and configure the LBR feature.
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71

◆ LbrStop()

VOID LbrStop ( )

Stop collecting LBR branches.

Returns
VOID
984{
985 BOOLEAN IsOnVmxRootMode;
986 ULONGLONG DbgCtlMsr = NULL64_ZERO;
987 IA32_LBR_CTL_REGISTER Ia32LbrCtl = {0};
988
990 {
991 IsOnVmxRootMode = g_Callbacks.VmFuncVmxGetCurrentExecutionMode();
992
993 //
994 // Read the current LBR control register values based on the current VMX execution mode
995 //
996 if (IsOnVmxRootMode)
997 {
998 LbrGetValuesOnVmxRootMode(&DbgCtlMsr, &Ia32LbrCtl);
999 }
1000 else
1001 {
1002 LbrGetValuesOnVmxNonRootMode(&DbgCtlMsr, &Ia32LbrCtl);
1003 }
1004
1005 //
1006 // Apply the appropriate bit to disable LBR based on whether it is architectural LBR or legacy LBR
1007 //
1009 {
1010 LbrDisableArchBased(&Ia32LbrCtl);
1011 }
1012 else
1013 {
1014 LbrDisableLegacyBased(&DbgCtlMsr);
1015 }
1016
1017 //
1018 // Write the updated LBR control register values back based on the current VMX execution mode
1019 //
1020 if (IsOnVmxRootMode)
1021 {
1022 LbrSetValuesOnVmxRootMode(DbgCtlMsr, Ia32LbrCtl);
1023 }
1024 else
1025 {
1026 LbrSetValuesOnVmxNonRootMode(DbgCtlMsr, Ia32LbrCtl);
1027 }
1028 }
1029 else
1030 {
1032 }
1033}
VOID LbrDisableArchBased(IA32_LBR_CTL_REGISTER *Ia32LbrCtl)
Disable LBR collection on architectural (ARCH) based LBR.
Definition Lbr.c:530
VOID LbrStopOnNativeMode()
Stop LBR collection when running natively (outside any hypervisor environment).
Definition Lbr.c:605
VOID LbrDisableLegacyBased(ULONGLONG *DbgCtlMsr)
Disable LBR collection on legacy based LBR.
Definition Lbr.c:542
#define NULL64_ZERO
Definition BasicTypes.h:111

Variable Documentation

◆ CPU_LBR_MAPS

CPU_LBR_MAP CPU_LBR_MAPS[]
extern

The global variable to hold the mapping of CPU model to its LBR capacity.

21 {
22 {0x5c, 32},
23 {0x5f, 32},
24 {0x4e, 32},
25 {0x5e, 32},
26 {0x8e, 32},
27 {0x9e, 32},
28 {0x55, 32},
29 {0x66, 32},
30 {0x7a, 32},
31 {0x67, 32},
32 {0x6a, 32},
33 {0x6c, 32},
34 {0x7d, 32},
35 {0x7e, 32},
36 {0x8c, 32},
37 {0x8d, 32},
38 {0xa5, 32},
39 {0xa6, 32},
40 {0xa7, 32},
41 {0xa8, 32},
42 {0x86, 32},
43 {0x8a, 32},
44 {0x96, 32},
45 {0x9c, 32},
46 {0x3d, 16},
47 {0x47, 16},
48 {0x4f, 16},
49 {0x56, 16},
50 {0x3c, 16},
51 {0x45, 16},
52 {0x46, 16},
53 {0x3f, 16},
54 {0x2a, 16},
55 {0x2d, 16},
56 {0x3a, 16},
57 {0x3e, 16},
58 {0x1a, 16},
59 {0x1e, 16},
60 {0x1f, 16},
61 {0x2e, 16},
62 {0x25, 16},
63 {0x2c, 16},
64 {0x2f, 16},
65 {0x17, 4},
66 {0x1d, 4},
67 {0x0f, 4},
68 {0x37, 8},
69 {0x4a, 8},
70 {0x4c, 8},
71 {0x4d, 8},
72 {0x5a, 8},
73 {0x5d, 8},
74 {0x1c, 8},
75 {0x26, 8},
76 {0x27, 8},
77 {0x35, 8},
78 {0x36, 8}};