Bitdefender Hypervisor Memory Introspection
introcore.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _INTROCORE_H_
6 #define _INTROCORE_H_
7 
8 #include "introcrt.h"
9 #include "dumper.h"
10 #include "stats.h"
11 
13 #define INTRO_MATCH_TRUNCATED 0x00000001
14 
15 extern void *gLock;
16 extern void *gIntHandle;
17 
19 
20 extern const QWORD gByteMaskToBitMask[256];
21 
22 extern BOOLEAN gAbortLoad;
23 
24 extern QWORD gEventId;
25 
26 
39 #define RB_TREE_INIT(Name, Free, Compare) \
40  { \
41  &((Name).Nil), \
42  { \
43  &((Name).Nil), \
44  &((Name).Nil), \
45  &((Name).Nil), \
46  ncBlack \
47  }, \
48  Free, \
49  Compare, \
50  0 \
51  }
52 
53 
55 #ifdef USER_MODE
56 # define MIN_HEAP_SIZE_PERCENT (20)
57 #else
58 # define MIN_HEAP_SIZE_PERCENT (30)
59 #endif
60 
61 #define MAX_TRANSLATION_DEPTH 5
62 
63 typedef enum
67 {
73 } PAGING_MODE;
74 
81 
82 #define TRFLG_NONE 0x00000000
83 #define TRFLG_CACHING_ATTR 0x00000001
84 #define TRFLG_NORMAL_MODE 0x10000000
85 #define TRFLG_PAE_MODE 0x20000000
86 #define TRFLG_4_LEVEL_MODE 0x30000000
87 #define TRFLG_5_LEVEL_MODE 0x40000000
88 #define TRFLG_MODE_MASK 0xF0000000
89 #define TRFLG_ALL (TRFLG_CACHING_ATTR)
90 
91 #define TRFLG_PG_MODE (gGuest.LA57 ? TRFLG_5_LEVEL_MODE : \
93  gGuest.Guest64 ? TRFLG_4_LEVEL_MODE : \
94  gGuest.PaeEnabled ? TRFLG_PAE_MODE : \
95  TRFLG_NORMAL_MODE)
96 
98 
102 typedef struct _VA_TRANSLATION
103 {
120 
125  BOOLEAN IsUser;
146 
147 void
148 IntPreinit(
149  void
150  );
151 
152 INTSTATUS
153 IntInit(
154  _Inout_ GLUE_IFACE *GlueInterface,
155  _In_ UPPER_IFACE const *UpperInterface
156  );
157 
158 INTSTATUS
159 IntUninit(
160  void
161  );
162 
163 INTSTATUS
165  _In_ QWORD Gva,
166  _In_ DWORD Length,
168  _Out_writes_bytes_(Length) void *Buffer,
169  _Out_opt_ DWORD *RetLength
170  );
171 
172 INTSTATUS
174  _In_ QWORD Gva,
175  _In_ DWORD Length,
176  _In_opt_ QWORD Cr3,
177  _In_reads_bytes_(Length) void *Buffer
178  );
179 
180 INTSTATUS
182  _In_ QWORD KernelGva,
183  _In_ DWORD Length,
184  _Out_writes_bytes_(Length) void *Buffer,
185  _Out_opt_ DWORD *RetLength
186  );
187 
188 INTSTATUS
190  _In_ QWORD KernelGva,
191  _In_ DWORD Length,
192  _In_reads_bytes_(Length) void *Buffer
193  );
194 
195 INTSTATUS
198  _In_ DWORD Length,
199  _In_opt_ QWORD Cr3,
200  _In_ BYTE Value
201  );
202 
203 INTSTATUS
206  _In_ DWORD Length,
207  _Out_writes_bytes_(Length) void *Buffer,
208  _Out_opt_ DWORD *RetLength
209  );
210 
211 INTSTATUS
213  _In_ QWORD PhysicalAddress,
214  _In_ DWORD Length,
215  _In_reads_bytes_(Length) void *Buffer
216  );
217 
218 INTSTATUS
220  _In_ QWORD PhysicalAddress,
221  _In_ DWORD Length,
222  _Out_writes_bytes_(Length) void *Buffer,
223  _Out_opt_ DWORD *RetLength
224  );
225 
226 INTSTATUS
228  _In_ QWORD PhysicalAddress,
229  _In_ DWORD Length,
230  _In_reads_bytes_(Length) void *Buffer
231  );
232 
233 INTSTATUS
235  _In_ QWORD GuestVirtualAddress,
236  _Out_ QWORD *Data
237  );
238 
239 INTSTATUS
241  _In_ QWORD GuestVirtualAddress,
242  _Out_ DWORD *Data
243  );
244 
245 INTSTATUS
247  _In_ QWORD GuestVirtualAddress,
248  _Out_ void *Data
249  );
250 
251 INTSTATUS
253  _In_ QWORD GuestVirtualAddress,
254  _In_opt_ QWORD Cr3,
255  _Out_ QWORD *Data
256  );
257 
258 INTSTATUS
260  _In_ QWORD GuestVirtualAddress,
261  _In_opt_ QWORD Cr3,
262  _Out_ DWORD *Data
263  );
264 
265 INTSTATUS
267  _In_ QWORD GuestVirtualAddress,
268  _In_opt_ QWORD Cr3,
269  _Out_ void *Data
270  );
271 
272 INTSTATUS
274  _In_ QWORD GuestVirtualAddress,
275  _In_ QWORD Data
276  );
277 
278 INTSTATUS
280  _In_ QWORD GuestVirtualAddress,
281  _In_ DWORD Data
282  );
283 
284 INTSTATUS
286  _In_ QWORD GuestVirtualAddress,
287  _In_ QWORD Data
288  );
289 
290 INTSTATUS
292  _In_ QWORD GuestVirtualAddress,
293  _In_opt_ QWORD Cr3,
294  _In_ QWORD Data
295  );
296 
297 INTSTATUS
299  _In_ QWORD GuestVirtualAddress,
300  _In_opt_ QWORD Cr3,
301  _In_ DWORD Data
302  );
303 
304 INTSTATUS
306  _In_ QWORD GuestVirtualAddress,
307  _In_opt_ QWORD Cr3,
308  _In_ QWORD Data
309  );
310 
311 INTSTATUS
313  _In_ QWORD Gva,
314  _In_ DWORD MaxLength,
315  _In_opt_ QWORD Cr3,
316  _Out_writes_z_(MaxLength) void *Buffer
317  );
318 
319 INTSTATUS
321  _In_ QWORD Gva,
322  _In_ QWORD Cr3,
323  _In_ DWORD Flags,
324  _Out_ VA_TRANSLATION *Translation
325  );
326 
327 INTSTATUS
329  _In_ QWORD Gva,
330  _In_opt_ QWORD Cr3,
331  _Out_ QWORD *PhysicalAddress
332  );
333 
335 INTSTATUS
337  _In_ QWORD Gva,
338  _In_ DWORD Length,
339  _In_opt_ QWORD Cr3,
340  _In_ DWORD Flags,
341  _Outptr_result_bytebuffer_(Length) void **HostPtr
342  );
343 
344 INTSTATUS
346  _Inout_ _At_(*HostPtr, _Post_null_) void **HostPtr
347  );
348 
349 INTSTATUS
351  _In_ BYTE Vector,
352  _In_ QWORD Cr2,
353  _In_ DWORD ErrorCode,
354  _In_ DWORD CpuNumber
355  );
356 
357 INTSTATUS
359  void
360  );
361 
362 INTSTATUS
364  void
365  );
366 
367 void
369  _In_ PCHAR File,
370  _In_ DWORD Line
371  );
372 
373 #define IntEnterDebugger() IntEnterDebugger2(__FILE__, __LINE__)
374 
375 void
377  _In_ PCHAR File,
378  _In_ DWORD Line
379  );
380 
381 #define IntDbgEnterDebugger() IntDbgEnterDebugger2(__FILE__, __LINE__)
382 
383 INTSTATUS
385  _In_ void const *Detour
386  );
387 
388 //
389 // Internal API
390 //
391 BOOLEAN
393  _In_z_ const CHAR *Pattern,
394  _In_z_ const CHAR *String,
395  _In_ DWORD Flags
396  );
397 
398 BOOLEAN
400  _In_z_ const WCHAR *Pattern,
401  _In_z_ const WCHAR *String,
402  _In_ DWORD Flags
403  );
404 
405 BOOLEAN
407  _In_opt_ const void *Process,
408  _In_ QWORD Flag
409  );
410 
411 BOOLEAN
413  _In_ QWORD Flag
414  );
415 
416 BOOLEAN
418  _In_opt_ const void *Process,
419  _In_ QWORD Flag
420  );
421 
422 QWORD
424  _In_opt_ const void *Process
425  );
426 
427 BOOLEAN
429  _In_ QWORD Flag,
430  _Inout_ INTRO_ACTION *Action,
432  );
433 
434 BOOLEAN
436  _In_ QWORD Flag,
437  _In_ void const *Process,
438  _Inout_ INTRO_ACTION *Action,
440  );
441 
442 BOOLEAN
444  _In_ QWORD Flag,
445  _In_ void *Process,
446  _Inout_ INTRO_ACTION *Action
447  );
448 
449 BOOLEAN
451  _In_ QWORD Flag,
452  _Inout_ INTRO_ACTION *Action
453  );
454 
455 BOOLEAN
457  _In_ QWORD Flag
458  );
459 
460 char *
462  _In_z_ const WCHAR *WString
463  );
464 
465 
466 INTSTATUS
468  _In_ QWORD StrGva,
469  _In_ DWORD MinimumLength,
470  _In_ BOOLEAN AnsiOnly,
471  _Inout_ char **String,
472  _Out_opt_ DWORD *StringLength
473  );
474 
475 #endif // _INTROCORE_H_
#define _In_opt_
Definition: intro_sal.h:16
QWORD PhysicalAddress
The physical address to which VirtualAddress translates to.
Definition: introcore.h:107
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
PAGING_MODE PagingMode
The paging mode used for this translation.
Definition: introcore.h:140
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
Definition: introcore.c:2234
void * gLock
A lock that ensures that all the events are serialized inside introcore.
Definition: introcore.c:24
Exposes the functions used to used to dump (log) code and registers.
INTSTATUS IntPhysicalMemRead(QWORD PhysicalAddress, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest physical memory range, but only for a single page.
Definition: introcore.c:721
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
Definition: introcore.c:2803
uint8_t BYTE
Definition: intro_types.h:47
INTSTATUS IntKernVirtMemPatchWordSize(QWORD GuestVirtualAddress, QWORD Data)
Writes a guest pointer inside the guest kernel memory.
Definition: introcore.c:968
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
Definition: introcore.c:699
#define _In_
Definition: intro_sal.h:21
INTSTATUS IntKernVirtMemPatchDword(QWORD GuestVirtualAddress, DWORD Data)
Writes 4 bytes in the guest kernel memory.
Definition: introcore.c:950
BOOLEAN IntPolicyCoreTakeAction(QWORD Flag, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a core introspection option.
Definition: introcore.c:2693
INTSTATUS IntPhysicalMemWriteAnySize(QWORD PhysicalAddress, DWORD Length, void *Buffer)
Writes data to a guest physical memory range, regardless of how many pages it spans across...
Definition: introcore.c:789
INTSTATUS IntReadString(QWORD StrGva, DWORD MinimumLength, BOOLEAN AnsiOnly, char **String, DWORD *StringLength)
Reads a string from the guest kernel memory.
Definition: introcore.c:2880
BOOLEAN IsWritable
True if this page is writable.
Definition: introcore.h:132
#define _Out_writes_bytes_(expr)
Definition: intro_sal.h:38
INTSTATUS IntVirtMemPatchWordSize(QWORD GuestVirtualAddress, QWORD Cr3, QWORD Data)
Writes a guest pointer inside the guest memory.
Definition: introcore.c:1031
QWORD IntPolicyGetProcProt(const void *Process)
Gets the protection policy for a process.
Definition: introcore.c:2661
Interface that exposes basic services to the introspection engines.
Definition: upperiface.h:262
INTRO_ERROR_CONTEXT gErrorContext
Global storage for the error context used by GLUE_IFACE.NotifyIntrospectionErrorState.
Definition: introcore.c:43
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
Definition: introcore.c:2355
BYTE CachingAttribute
The caching attributes used for this translation.
Definition: introcore.h:144
INTSTATUS IntVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD Cr3, QWORD *Data)
Reads 8 bytes from the guest memory.
Definition: introcore.c:866
INTSTATUS IntVirtMemWrite(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer)
Writes data to a guest virtual memory range.
Definition: introcore.c:652
INTSTATUS IntKernVirtMemFetchWordSize(QWORD GuestVirtualAddress, void *Data)
Reads a guest pointer from the guest kernel memory.
Definition: introcore.c:847
int INTSTATUS
The status data type.
Definition: introstatus.h:24
QWORD gEventId
The ID of the current event.
Definition: glue.c:55
BOOLEAN IsExecutable
True if this page is executable.
Definition: introcore.h:136
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
Definition: introcore.c:2264
BOOLEAN IntMatchPatternUtf8(const CHAR *Pattern, const CHAR *String, DWORD Flags)
Matches a pattern using glob match.
Definition: introcore.c:2454
INTSTATUS IntPhysicalMemWrite(QWORD PhysicalAddress, DWORD Length, void *Buffer)
Writes data to a guest physical memory range, but only for a single page.
Definition: introcore.c:744
void IntEnterDebugger2(PCHAR File, DWORD Line)
Traps to a debugger.
Definition: introcore.c:2388
BOOLEAN IntPolicyIsCoreOptionFeedback(QWORD Flag)
Checks if a core protection option is in feedback-only mode.
Definition: introcore.c:2829
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
Definition: introcore.c:2320
void * gIntHandle
The guest handle provided by the integrator at initialization.
Definition: glue.c:49
Interface used for communicating between the introspection engine and the integrator.
Definition: glueiface.h:2078
INTSTATUS IntVirtMemFetchWordSize(QWORD GuestVirtualAddress, QWORD Cr3, void *Data)
Reads a guest pointer from the guest memory.
Definition: introcore.c:908
INTSTATUS IntVirtMemPatchQword(QWORD GuestVirtualAddress, QWORD Cr3, QWORD Data)
Writes 8 bytes in the guest memory.
Definition: introcore.c:989
INTSTATUS IntVirtMemFetchDword(QWORD GuestVirtualAddress, QWORD Cr3, DWORD *Data)
Reads 4 bytes from the guest memory.
Definition: introcore.c:887
BOOLEAN IntPolicyProcIsBeta(const void *Process, QWORD Flag)
Checks if a process protection policy is in log-only mode.
Definition: introcore.c:2569
BOOLEAN IntPolicyCoreIsOptionBeta(QWORD Flag)
Checks if one of the kernel protection options is in log-only mode.
Definition: introcore.c:2603
INTSTATUS IntGuestUninitOnBugcheck(void const *Detour)
Prepares Introcore unload in case of a guest crash in order to clean up the code and data injected in...
Definition: introcore.c:2522
BOOLEAN gAbortLoad
Set to True if introcore should abort the initialization process.
Definition: introcore.c:59
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
Definition: introcore.h:123
No paging.
Definition: introcore.h:68
#define _Inout_
Definition: intro_sal.h:20
INTSTATUS IntVirtMemSet(QWORD VirtualAddress, DWORD Length, QWORD Cr3, BYTE Value)
Definition: introcore.c:414
5-level paging
Definition: introcore.h:72
QWORD Flags
The entry that maps VirtualAddress to PhysicalAddress, together with all the control bits...
Definition: introcore.h:119
INTSTATUS IntKernVirtMemFetchDword(QWORD GuestVirtualAddress, DWORD *Data)
Reads 4 bytes from the guest kernel memory.
Definition: introcore.c:829
#define _Out_opt_
Definition: intro_sal.h:30
void IntDbgEnterDebugger2(PCHAR File, DWORD Line)
Traps to a debugger and dumps the Introcore state.
Definition: introcore.c:2411
BOOLEAN IntPolicyProcTakeAction(QWORD Flag, void const *Process, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a process protection option.
Definition: introcore.c:2732
The context of an error state.
Definition: intro_types.h:2415
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
Definition: introcore.c:811
QWORD MappingsEntries[MAX_TRANSLATION_DEPTH]
Contains the entry in which paging table.
Definition: introcore.h:115
BOOLEAN IntMatchPatternUtf16(const WCHAR *Pattern, const WCHAR *String, DWORD Flags)
Matches a pattern using glob match.
Definition: introcore.c:2491
QWORD Cr3
The Cr3 used for this translation.
Definition: introcore.h:122
unsigned long long QWORD
Definition: intro_types.h:53
const QWORD gByteMaskToBitMask[256]
Converts a byte number to a mask having the bits in those bytes set.
Definition: introcore.c:73
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
Definition: introcore.c:1999
INTSTATUS IntUninit(void)
Disables and uninitializes Introcore.
Definition: introcore.c:266
#define __must_check
Definition: introtypes.h:48
struct _VA_TRANSLATION VA_TRANSLATION
Encapsulates information about a virtual to physical memory translation.
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
Definition: introcore.c:1863
32-bit paging with PAE
Definition: introcore.h:70
char * PCHAR
Definition: intro_types.h:56
#define _Outptr_result_bytebuffer_(expr)
Definition: intro_sal.h:24
void IntPreinit(void)
Initializes the global variables used throughout the project.
Definition: introcore.c:166
4-level paging
Definition: introcore.h:71
struct _VA_TRANSLATION * PVA_TRANSLATION
INTSTATUS IntVirtMemFetchString(QWORD Gva, DWORD MaxLength, QWORD Cr3, void *Buffer)
Reads a NULL-terminated string from the guest.
Definition: introcore.c:1053
uint16_t WCHAR
Definition: intro_types.h:63
uint32_t DWORD
Definition: intro_types.h:49
enum _INTRO_ACTION INTRO_ACTION
Event actions.
#define _At_(expr, arg)
Definition: intro_sal.h:23
BOOLEAN IntPolicyProcForceBetaIfNeeded(QWORD Flag, void *Process, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the process log-only mode is active.
Definition: introcore.c:2773
#define _In_reads_bytes_(expr)
Definition: intro_sal.h:25
PAGING_MODE
Paging modes.
Definition: introcore.h:66
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
Definition: introcore.c:2134
#define _In_z_
Definition: intro_sal.h:17
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
Definition: introcore.c:627
QWORD PageSize
The page size used for this translation.
Definition: introcore.h:121
INTSTATUS IntPhysicalMemReadAnySize(QWORD PhysicalAddress, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest physical memory range, regardless of how many pages it spans across...
Definition: introcore.c:764
QWORD MappingsTrace[MAX_TRANSLATION_DEPTH]
Contains the physical address of each entry within the translation tables.
Definition: introcore.h:111
BOOLEAN IntPolicyProcIsFeedback(const void *Process, QWORD Flag)
Checks if a process protection policy is in feedback-only mode.
Definition: introcore.c:2627
QWORD VirtualAddress
The translated virtual address.
Definition: introcore.h:105
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
Definition: introcore.c:674
INTSTATUS IntKernVirtMemPatchQword(QWORD GuestVirtualAddress, QWORD Data)
Writes 8 bytes in the guest kernel memory.
Definition: introcore.c:932
#define _Out_writes_z_(expr)
Definition: intro_sal.h:37
Encapsulates information about a virtual to physical memory translation.
Definition: introcore.h:102
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
Definition: introcore.c:2845
32-bit paging
Definition: introcore.h:69
BOOLEAN Pointer64
Definition: introcore.h:124
char CHAR
Definition: intro_types.h:56
INTSTATUS IntVirtMemPatchDword(QWORD GuestVirtualAddress, QWORD Cr3, DWORD Data)
Writes 4 bytes in the guest memory.
Definition: introcore.c:1010
BOOLEAN IsUser
True if this page is accessible to user mode code.
Definition: introcore.h:128
INTSTATUS IntInit(GLUE_IFACE *GlueInterface, UPPER_IFACE const *UpperInterface)
Initializes introcore.
Definition: introcore.c:186
#define MAX_TRANSLATION_DEPTH
Maximum depth of the translation hierarchy.
Definition: introcore.h:61