Bitdefender Hypervisor Memory Introspection
introcpu.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _INTRO_CPU_H_
6 #define _INTRO_CPU_H_
7 
8 #include "introtypes.h"
9 #include "processor.h"
10 
14 typedef union _INTERRUPT_GATE
15 {
16  QWORD Raw[2];
17  struct
18  {
25  };
27 
31 typedef union _INTERRUPT_GATE32
32 {
34  struct
35  {
40  };
42 
46 typedef struct _SEGMENT_DESCRIPTOR32
47 {
48  QWORD Limit1 : 16;
49  QWORD Base1 : 24;
50  QWORD Attr1 : 8;
52  QWORD Attr2 : 4;
53  QWORD Base : 8;
55 
59 typedef struct _XSAVE_AREA
60 {
63 } XSAVE_AREA;
64 
65 #pragma pack(push)
66 #pragma pack(1)
67 
71 typedef struct _DTR
72 {
75 } DTR, *PDTR;
76 
77 #pragma pack(pop)
78 
79 //
80 // IA32_LBR_SELECT & IA32_LBR_TOS aren't actually architectural, they are specific
81 // to micro architectures >= Nehalem/Westmere
82 //
83 #define MSR_LBR_0_FROM_IP 0x00000680
84 #define MSR_LBR_1_FROM_IP 0x00000681
85 #define MSR_LBR_2_FROM_IP 0x00000682
86 #define MSR_LBR_3_FROM_IP 0x00000683
87 #define MSR_LBR_4_FROM_IP 0x00000684
88 #define MSR_LBR_5_FROM_IP 0x00000685
89 #define MSR_LBR_6_FROM_IP 0x00000686
90 #define MSR_LBR_7_FROM_IP 0x00000687
91 #define MSR_LBR_8_FROM_IP 0x00000688
92 #define MSR_LBR_9_FROM_IP 0x00000689
93 #define MSR_LBR_A_FROM_IP 0x0000068A
94 #define MSR_LBR_B_FROM_IP 0x0000068B
95 #define MSR_LBR_C_FROM_IP 0x0000068C
96 #define MSR_LBR_D_FROM_IP 0x0000068D
97 #define MSR_LBR_E_FROM_IP 0x0000068E
98 #define MSR_LBR_F_FROM_IP 0x0000068F
99 
100 #define MSR_LBR_0_TO_IP 0x000006C0
101 #define MSR_LBR_1_TO_IP 0x000006C1
102 #define MSR_LBR_2_TO_IP 0x000006C2
103 #define MSR_LBR_3_TO_IP 0x000006C3
104 #define MSR_LBR_4_TO_IP 0x000006C4
105 #define MSR_LBR_5_TO_IP 0x000006C5
106 #define MSR_LBR_6_TO_IP 0x000006C6
107 #define MSR_LBR_7_TO_IP 0x000006C7
108 #define MSR_LBR_8_TO_IP 0x000006C8
109 #define MSR_LBR_9_TO_IP 0x000006C9
110 #define MSR_LBR_A_TO_IP 0x000006CA
111 #define MSR_LBR_B_TO_IP 0x000006CB
112 #define MSR_LBR_C_TO_IP 0x000006CC
113 #define MSR_LBR_D_TO_IP 0x000006CD
114 #define MSR_LBR_E_TO_IP 0x000006CE
115 #define MSR_LBR_F_TO_IP 0x000006CF
116 
117 #define MSR_LER_FROM_IP 0x000001DD
118 #define MSR_LER_TO_IP 0x000001DE
119 
120 #define LBR_STACK_SIZE 16
121 
122 
123 //
124 // Cpu registers/structures access
125 //
126 INTSTATUS
128  _In_ QWORD CpuNumber,
129  _Out_ QWORD *Efer
130  );
131 
132 INTSTATUS
133 IntRipRead(
134  _In_ DWORD CpuNumber,
135  _Out_ QWORD *Rip
136  );
137 
138 INTSTATUS
140  _In_ DWORD CpuNumber,
141  _Out_ QWORD *Base,
142  _Out_opt_ WORD *Limit
143  );
144 
145 INTSTATUS
147  _In_ DWORD CpuNumber,
148  _In_ DWORD Entry,
149  _Out_ QWORD *Handler
150  );
151 
152 INTSTATUS
154  _In_ DWORD CpuNumber,
155  _Out_ QWORD *GdtBase,
156  _Out_opt_ WORD *GdtLimit
157  );
158 
159 INTSTATUS
160 IntFsRead(
161  _In_ DWORD CpuNumber,
162  _Out_ QWORD *FsValue
163  );
164 
165 INTSTATUS
166 IntGsRead(
167  _In_ DWORD CpuNumber,
168  _Out_ QWORD *GsValue
169  );
170 
171 INTSTATUS
172 IntCr0Read(
173  _In_ DWORD CpuNumber,
174  _Out_ QWORD *Cr0Value
175  );
176 
177 INTSTATUS
178 IntCr3Read(
179  _In_ DWORD CpuNumber,
180  _Out_ QWORD *Cr3Value);
181 
182 INTSTATUS
183 IntCr4Read(
184  _In_ DWORD CpuNumber,
185  _Out_ QWORD *Cr4Value
186  );
187 
188 INTSTATUS
189 IntCr8Read(
190  _In_ DWORD CpuNumber,
191  _Out_ QWORD *Cr8Value
192  );
193 
194 INTSTATUS
196  _In_ DWORD CpuNumber,
197  _Out_opt_ QWORD *SysCs,
198  _Out_opt_ QWORD *SysEip,
199  _Out_opt_ QWORD *SysEsp
200  );
201 
202 INTSTATUS
204  _In_ DWORD CpuNumber,
205  _Out_opt_ QWORD *SysStar,
206  _Out_opt_ QWORD *SysLstar
207  );
208 
209 INTSTATUS
211  _In_ DWORD CpuNumber,
212  _Out_ QWORD *DebugCtl
213  );
214 
215 INTSTATUS
216 IntLbrRead(
217  _In_ DWORD BuffersSize,
218  _Out_writes_(BuffersSize) QWORD *LbrFrom,
219  _Out_writes_(BuffersSize) QWORD *LbrTo
220  );
221 
222 INTSTATUS
223 IntLerRead(
224  _Out_ QWORD *LerFrom,
225  _Out_ QWORD *LerTo
226  );
227 
228 DWORD
230  void
231  );
232 
233 INTSTATUS
234 IntGetGprs(
235  _In_ DWORD CpuNumber,
236  _Out_ PIG_ARCH_REGS Regs
237  );
238 
239 INTSTATUS
240 IntSetGprs(
241  _In_ DWORD CpuNumber,
242  _In_ PIG_ARCH_REGS Regs
243  );
244 
245 INTSTATUS
247  _In_ DWORD CpuNumber,
248  _Out_ DWORD *Ring
249  );
250 
251 INTSTATUS
253  _In_ DWORD CpuNumber,
254  _Out_ DWORD *Mode
255  );
256 
257 INTSTATUS
258 IntGetSegs(
259  _In_ DWORD CpuNumber,
260  _Out_ PIG_SEG_REGS Regs
261  );
262 
263 INTSTATUS
265  _Out_ DWORD *Size
266  );
267 
268 INTSTATUS
270  _In_ DWORD CpuNumber,
271  _Out_ XSAVE_AREA *XsaveArea
272  );
273 
274 INTSTATUS
276  _In_ DWORD CpuNumber,
277  _In_ XSAVE_AREA *XsaveArea
278  );
279 
286 #define IntFreeXsaveArea(xa) HpFreeAndNullWithTag(&(xa).XsaveArea, IC_TAG_XSAVE)
287 
288 INTSTATUS
289 IntGetXcr0(
290  _In_ DWORD CpuNumber,
291  _Out_ QWORD *Xcr0Value
292  );
293 
294 INTSTATUS
296  _In_ DWORD CpuNumber,
297  _Out_ QWORD *Pcr
298  );
299 
300 INTSTATUS
302  _In_ DWORD CpuNumber,
303  _Out_ DWORD *EptpIndex
304  );
305 
306 INTSTATUS
308  _In_ DWORD CpuNumber,
309  _Out_ PIG_ARCH_REGS Regs
310  );
311 
312 INTSTATUS
314  _Out_ QWORD *MaxGpfn
315  );
316 
317 #endif // _INTRO_CPU_H_
struct _SEGMENT_DESCRIPTOR32 SEGMENT_DESCRIPTOR32
Segment descriptor for 32-bit systems.
WORD Offset_15_0
Definition: introcpu.h:19
#define _Out_
Definition: intro_sal.h:22
INTSTATUS IntIdtFindBase(DWORD CpuNumber, QWORD *Base, WORD *Limit)
Returns the IDT base and limit for a guest CPU.
Definition: introcpu.c:102
WORD Limit
Definition: introcpu.h:73
Describes an XSAVE area format.
Definition: glueiface.h:93
INTSTATUS IntGetXcr0(DWORD CpuNumber, QWORD *Xcr0Value)
Get the value of the guest XCR0 register.
Definition: introcpu.c:1030
Segment descriptor for 32-bit systems.
Definition: introcpu.h:46
INTSTATUS IntIdtGetEntry(DWORD CpuNumber, DWORD Entry, QWORD *Handler)
Get the handler of an interrupt from the IDT.
Definition: introcpu.c:145
#define _In_
Definition: intro_sal.h:21
INTSTATUS IntFsRead(DWORD CpuNumber, QWORD *FsValue)
Reads the IA32_FS_BASE guest MSR.
Definition: introcpu.c:252
QWORD Base
Definition: introcpu.h:74
uint16_t WORD
Definition: intro_types.h:48
INTSTATUS IntGetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Get the current guest GPR state.
Definition: introcpu.c:827
DWORD IntGetCurrentCpu(void)
Returns the current CPU number.
Definition: introcpu.c:802
INTSTATUS IntLbrRead(DWORD BuffersSize, QWORD *LbrFrom, QWORD *LbrTo)
Definition: introcpu.c:720
Holds segment register state.
Definition: glueiface.h:64
int INTSTATUS
The status data type.
Definition: introstatus.h:24
INTSTATUS IntGetMaxGpfn(QWORD *MaxGpfn)
Get the last physical page frame number accessible by the guest.
Definition: introcpu.c:1273
INTSTATUS IntRipRead(DWORD CpuNumber, QWORD *Rip)
Reads the value of the guest RIP.
Definition: introcpu.c:49
INTSTATUS IntGetAllRegisters(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Returns the entire guest register state. This will return the GPRs, control registers, and IDT and GDT base and limit. This also bypasses the cache used by IntGetGprs.
Definition: introcpu.c:1218
#define _Out_writes_(expr)
Definition: intro_sal.h:28
struct _DTR * PDTR
DWORD Offset_63_32
Definition: introcpu.h:23
INTSTATUS IntGetCurrentMode(DWORD CpuNumber, DWORD *Mode)
Read the current CS type.
Definition: introcpu.c:977
#define _Out_opt_
Definition: intro_sal.h:30
union _INTERRUPT_GATE32 INTERRUPT_GATE32
An 32-bit interrupt gate as defined by the Intel docs.
INTSTATUS IntFindKernelPcr(DWORD CpuNumber, QWORD *Pcr)
Finds the address of the Windows kernel _KPCR.
Definition: introcpu.c:1116
INTSTATUS IntSysenterRead(DWORD CpuNumber, QWORD *SysCs, QWORD *SysEip, QWORD *SysEsp)
Queries the IA32_SYSENTER_CS, IA32_SYSENTER_EIP, and IA32_SYSENTER_ESP guest MSRs.
Definition: introcpu.c:571
XSAVE area container.
Definition: introcpu.h:59
An 32-bit interrupt gate as defined by the Intel docs.
Definition: introcpu.h:31
unsigned long long QWORD
Definition: intro_types.h:53
INTSTATUS IntCr0Read(DWORD CpuNumber, QWORD *Cr0Value)
Reads the value of the guest CR0.
Definition: introcpu.c:363
QWORD Raw[2]
Definition: introcpu.h:16
INTSTATUS IntDebugCtlRead(DWORD CpuNumber, QWORD *DebugCtl)
Queries the IA32_DEBUGCTL guest MSR.
Definition: introcpu.c:684
INTSTATUS IntGsRead(DWORD CpuNumber, QWORD *GsValue)
Reads the IA32_GS_BASE guest MSR.
Definition: introcpu.c:289
An 64-bit interrupt gate as defined by the Intel docs.
Definition: introcpu.h:14
A descriptor table register. Valid for IDTR and GDTR.
Definition: introcpu.h:71
INTSTATUS IntSetXsaveArea(DWORD CpuNumber, XSAVE_AREA *XsaveArea)
Sets the contents of the guest XSAVE area.
Definition: introcpu.c:1097
uint32_t DWORD
Definition: intro_types.h:49
INTSTATUS IntGetXsaveAreaSize(DWORD *Size)
Get the size of the guest XSAVE area on the current CPU.
Definition: introcpu.c:1014
INTSTATUS IntCr8Read(DWORD CpuNumber, QWORD *Cr8Value)
Reads the value of the guest CR8.
Definition: introcpu.c:519
INTSTATUS IntSyscallRead(DWORD CpuNumber, QWORD *SysStar, QWORD *SysLstar)
Queries the IA32_STAR, and IA32_LSTAR guest MSRs.
Definition: introcpu.c:635
union _INTERRUPT_GATE INTERRUPT_GATE
An 64-bit interrupt gate as defined by the Intel docs.
WORD Offset_31_16
Definition: introcpu.h:22
DWORD Size
The size of the XSAVE area. XsaveArea has at least Size bytes.
Definition: introcpu.h:61
INTSTATUS IntSetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Sets the values of the guest GPRs.
Definition: introcpu.c:905
INTSTATUS IntLerRead(QWORD *LerFrom, QWORD *LerTo)
Definition: introcpu.c:776
DWORD Reserved2
Definition: introcpu.h:24
union _INTERRUPT_GATE * PINTERRUPT_GATE
union _INTERRUPT_GATE32 * PINTERRUPT_GATE32
INTSTATUS IntCr3Read(DWORD CpuNumber, QWORD *Cr3Value)
Reads the value of the guest CR3.
Definition: introcpu.c:415
INTSTATUS IntCr4Read(DWORD CpuNumber, QWORD *Cr4Value)
Reads the value of the guest CR4.
Definition: introcpu.c:467
struct _DTR DTR
A descriptor table register. Valid for IDTR and GDTR.
IG_XSAVE_AREA * XsaveArea
The contents of the XSAVE area.
Definition: introcpu.h:62
INTSTATUS IntGdtFindBase(DWORD CpuNumber, QWORD *GdtBase, WORD *GdtLimit)
Returns the GDT base and limit for a guest CPU.
Definition: introcpu.c:206
Holds register state.
Definition: glueiface.h:30
INTSTATUS IntGetSegs(DWORD CpuNumber, PIG_SEG_REGS Regs)
Read the guest segment registers.
Definition: introcpu.c:995
INTSTATUS IntGetCurrentEptIndex(DWORD CpuNumber, DWORD *EptpIndex)
Get the EPTP index of the currently loaded EPT.
Definition: introcpu.c:1238
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
Definition: introcpu.c:959
struct _SEGMENT_DESCRIPTOR32 * PSEGMENT_DESCRIPTOR32
INTSTATUS IntEferRead(QWORD CpuNumber, QWORD *Efer)
Reads the value of the guest IA32 EFER MSR.
Definition: introcpu.c:12
INTSTATUS IntGetXsaveArea(DWORD CpuNumber, XSAVE_AREA *XsaveArea)
Get the contents of the guest XSAVE area.
Definition: introcpu.c:1048
struct _XSAVE_AREA XSAVE_AREA
XSAVE area container.