Bitdefender Hypervisor Memory Introspection
winvad.h File Reference
#include "detours.h"
#include "winprocess.h"

Go to the source code of this file.

Data Structures

struct  _VAD_PAGE
 A representation of a memory page included in a VAD structure. More...
 
struct  _VAD
 A representation of a Windows VAD structure. More...
 

Macros

#define PROT_READ   1
 One of the Introcore VAD protection constants. This means that the page is readable. More...
 
#define PROT_WRITE   2
 One of the Introcore VAD protection constants. This means that the page is writable. More...
 
#define PROT_EXEC   4
 One of the Introcore VAD protection constants. This means that the page is executable. More...
 

Typedefs

typedef struct _VAD_PAGE VAD_PAGE
 A representation of a memory page included in a VAD structure. More...
 
typedef struct _VAD_PAGEPVAD_PAGE
 
typedef struct _VAD VAD
 A representation of a Windows VAD structure. More...
 
typedef struct _VADPVAD
 
typedef INTSTATUS(* PFUNC_WinVadTraversalCallback) (QWORD VadNodeGva, DWORD Level, void *Context)
 Callback type used for in-guest VAD tree traversals. More...
 

Enumerations

enum  WIN_VAD_PROT {
  VAD_PROT_NOACCESS = 0x0000, VAD_PROT_READONLY = 0x0001, VAD_PROT_EXECUTE = 0x0002, VAD_PROT_EXECUTE_READ = 0x0003,
  VAD_PROT_READWRITE = 0x0004, VAD_PROT_WRITECOPY = 0x0005, VAD_PROT_EXECUTE_READWRITE = 0x0006, VAD_PROT_EXECUTE_WRITECOPY = 0x0007,
  VAD_PROT_NOCACHE = 0x0008, VAD_PROT_GUARD = 0x0010, VAD_PROT_WRITECOMBINE = 0x0020
}
 VAD protection flags as used by the Windows kernel. These represent the values in the Protection portion of the VadFlags field inside a _MMVAD_SHORT structure. More...
 

Functions

void IntWinVadProcessInit (WIN_PROCESS_OBJECT *Process)
 Initializes a WIN_PROCESS_OBJECT.VadTree. More...
 
VADIntWinVadFindByVa (WIN_PROCESS_OBJECT *Process, QWORD Va)
 Finds a VAD that contains a given guest virtual address. More...
 
INTSTATUS IntWinVadHandleInsert (void const *Detour)
 The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertVad guest API. More...
 
INTSTATUS IntWinVadHandleInsertPrivate (void const *Detour)
 The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertPrivateVad guest API. More...
 
INTSTATUS IntWinVadHandleInsertMap (void const *Detour)
 The detour handler that will be invoked when a VAD is inserted in the guest VAD tree.This is the detour handler for the MiGetWsAndInsertVad guest API. More...
 
INTSTATUS IntWinVadHandleVirtualProtect (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD has the protection rights changed.This is the detour handler for the MiProtectVirtualMemory guest API, which usually gets called as a result of a user-mode application calling an API like VirtualProtect. More...
 
INTSTATUS IntWinVadHandleDeleteVaRange (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiDeleteVirtualAddresses guest API. More...
 
INTSTATUS IntWinVadHandleFinishVadDeletion (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiFinishVadDeletion guest API. More...
 
INTSTATUS IntWinVadImportProcessTree (WIN_PROCESS_OBJECT *Process)
 Scans the guest VAD tree and imports the nodes into our VAD tree. More...
 
INTSTATUS IntWinVadRemoveProcessTree (WIN_PROCESS_OBJECT *Process)
 Removes the VAD tree from a process. More...
 
void IntWinVadStopExploitMonitor (WIN_PROCESS_OBJECT *Process)
 Disables the exploit monitoring for a process. More...
 
INTSTATUS IntWinVadShortDump (QWORD VadNodeGva, DWORD Level, void *Context)
 Prints a _MMVAD_SHORT structure. More...
 
QWORD IntWinVadFindNodeInGuestSpace (QWORD VadRoot, QWORD StartPage, QWORD EndPage, DWORD Level, QWORD OldStartPage, BOOLEAN LastBranchRight)
 Searches for a VAD node inside a guest VAD tree. More...
 
INTSTATUS IntWinVadInOrderRecursiveTraversal (QWORD VadNodeGva, DWORD Level, PFUNC_WinVadTraversalCallback Callback, void *Context)
 Traverses a guest VAD tree. More...
 
BOOLEAN IntWinVadDump (VAD const *Vad, void *Context)
 Prints a VAD structure. More...
 
INTSTATUS IntWinVadWalkTree (PWIN_PROCESS_OBJECT Process, PFUNC_RbTreeWalkCallback Callback)
 Walks the VAD tree of a process. More...
 
INTSTATUS IntWinVadHandleCommit (void const *Detour)
 The detour handler that will be invoked when an existing VAD is committed by the guest.This is the detour handler for the MiCommitExistingVad guest API. Due to the way we ignore certain VADs, this can be invoked either when protection is changed for a known VAD, in which case we have to adjust our protection; or, when protection is changed for a previously unknown VAD in a way that makes it relevant for Introcore, in which case we treat as a newly created VAD. More...
 
VADIntWinVadFindAndUpdateIfNecessary (WIN_PROCESS_OBJECT *Process, QWORD StartHint, QWORD LengthHint)
 Searches for a VAD in the Introcore VAD tree. If no VAD is found, or if the found one does not fully contain the searched range, it will re-scan the guest tree in order to find a matching VAD. If the VAD is taken from the guest, it is inserted in the VAD tree of the given process. More...
 
INTSTATUS IntWinPatchVadHandleCommit (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiCommitExistingVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the values of winKmFieldPcrCurrentThread, winKmFieldThreadAttachedProcess, winKmFieldThreadProcess, and winKmFieldProcessSpare. For 32-bit kernels it will also patch the stack location at which the VmProtection parameter is located. More...
 
BOOLEAN IntWinVadIsInTree (const VAD *Vad)
 Checks if a VAD is inserted in a guest VAD tree. More...
 
INTSTATUS IntWinVadPatchInsertPrivate (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiInsertPrivateVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchInsertMap (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiGetWsAndInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchVirtualProtect (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiProtectVirtualMemory guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchDeleteVaRange (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiDeleteVirtualAddresses guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchFinishVadDeletion (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiFinishVadDeletion guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchInsert (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadProcImportMainModuleVad (WIN_PROCESS_OBJECT *Process)
 Imports the VAD that describes the main module of a process. More...
 
void IntWinVadDestroyObject (VAD **Vad)
 Frees a VAD and all the resources held by it. More...
 
INTSTATUS IntWinVadFetchByRange (QWORD VadRoot, QWORD StartPage, QWORD EndPage, VAD *Vad)
 Fetches and returns a VAD object containing the range represented by [StartPage, EndPage]. More...
 

Macro Definition Documentation

◆ PROT_EXEC

#define PROT_EXEC   4

One of the Introcore VAD protection constants. This means that the page is executable.

Definition at line 16 of file winvad.h.

Referenced by IntWinVadDump(), IntWinVadHandleInsertGeneric(), IntWinVadHandleProtectGeneric(), IntWinVadVadProtectionToIntroProtection(), and IntWinVadVmProtectionToIntroProtection().

◆ PROT_READ

#define PROT_READ   1

One of the Introcore VAD protection constants. This means that the page is readable.

Definition at line 12 of file winvad.h.

Referenced by IntWinVadDump(), IntWinVadVadProtectionToIntroProtection(), and IntWinVadVmProtectionToIntroProtection().

◆ PROT_WRITE

#define PROT_WRITE   2

One of the Introcore VAD protection constants. This means that the page is writable.

Definition at line 14 of file winvad.h.

Referenced by IntWinVadDump(), IntWinVadHandleInsertGeneric(), IntWinVadVadProtectionToIntroProtection(), and IntWinVadVmProtectionToIntroProtection().

Typedef Documentation

◆ PFUNC_WinVadTraversalCallback

typedef INTSTATUS(* PFUNC_WinVadTraversalCallback) (QWORD VadNodeGva, DWORD Level, void *Context)

Callback type used for in-guest VAD tree traversals.

This will be invoked for every node in the tree.

Parameters
[in]VadNodeGvaThe guest virtual address of the tree node for which this callback was invoked.
[in]LevelThe level at which this node is located inside the tree.
[in]ContextOptional context passed by the caller.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value. Note that errors are logged, but the status does not affect the iteration process in any way and errors are not propagated back to the caller.

Definition at line 182 of file winvad.h.

◆ PVAD

typedef struct _VAD * PVAD

◆ PVAD_PAGE

typedef struct _VAD_PAGE * PVAD_PAGE

◆ VAD

typedef struct _VAD VAD

A representation of a Windows VAD structure.

This can be obtained from a _MMVAD_SHORT or a _MMVAD_LONG Windows structure.

◆ VAD_PAGE

typedef struct _VAD_PAGE VAD_PAGE

A representation of a memory page included in a VAD structure.

Enumeration Type Documentation

◆ WIN_VAD_PROT

VAD protection flags as used by the Windows kernel. These represent the values in the Protection portion of the VadFlags field inside a _MMVAD_SHORT structure.

Note that these are bit flags and valid values can be constructing by combining these, so valid values extend past this enum.

Enumerator
VAD_PROT_NOACCESS 
VAD_PROT_READONLY 
VAD_PROT_EXECUTE 
VAD_PROT_EXECUTE_READ 
VAD_PROT_READWRITE 
VAD_PROT_WRITECOPY 
VAD_PROT_EXECUTE_READWRITE 
VAD_PROT_EXECUTE_WRITECOPY 
VAD_PROT_NOCACHE 
VAD_PROT_GUARD 
VAD_PROT_WRITECOMBINE 

Definition at line 24 of file winvad.h.

Function Documentation

◆ IntWinVadDestroyObject()

void IntWinVadDestroyObject ( VAD **  Vad)

Frees a VAD and all the resources held by it.

This will remove any pending IntSwapMemReadData transactions, will remove all the VAD_PAGE structures for the VAD, and if this VAD maps a module, that module will be unloaded, as well as dereferencing the WINUM_PATH cache entry.

Parameters
[in,out]VadHolds a pointer to the VAD to be destroyed. On return, this will point to NULL.

Definition at line 285 of file winvad.c.

Referenced by IntWinProcRemoveProcess(), IntWinVadHandleDeleteGeneric(), IntWinVadHandleInsertGeneric(), and IntWinVadRbTreeNodeFree().

◆ IntWinVadDump()

BOOLEAN IntWinVadDump ( VAD const *  Vad,
void *  Context 
)

Prints a VAD structure.

Parameters
[in]VadPointer to the structure to be printed.
[in]ContextIgnored.
Return values
Falseif Vad is NULL; otherwise True.

Definition at line 1706 of file winvad.c.

Referenced by IntWinProcDump(), and IntWinProcDumpVads().

◆ IntWinVadFetchByRange()

INTSTATUS IntWinVadFetchByRange ( QWORD  VadRoot,
QWORD  StartPage,
QWORD  EndPage,
VAD Vad 
)

Fetches and returns a VAD object containing the range represented by [StartPage, EndPage].

Note: The VAD is just completed with the relevant information, there's no need to call IntWinVadDestroyObject on the returned VAD.

Parameters
[in]VadRootThe vad root from where to start the search. It is read from the guest, as the VadRoot field in the EPROCESS structure.
[in]StartPageThe page which represents the start of the range that must be contained in the returned VAD.
[in]EndPageThe page which represents the end of the range that must be contained in the returned VAD.
[out]VadThe returned VAD object.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INVALID_PARAMETER_1If the given VadRoot is equal to 0.
INT_STATUS_INVALID_PARAMETER_4If the given VAD object is NULL.
INT_STATUS_NOT_FOUNDIf there is no such VAD in the tree represented by the given root such that it contains [StartPage, EndPage].

Definition at line 3877 of file winvad.c.

Referenced by IntWinDpiValidateThreadStart(), and IntWinStackHandleUserStackPagedOut().

◆ IntWinVadFindAndUpdateIfNecessary()

VAD* IntWinVadFindAndUpdateIfNecessary ( WIN_PROCESS_OBJECT Process,
QWORD  StartHint,
QWORD  LengthHint 
)

Searches for a VAD in the Introcore VAD tree. If no VAD is found, or if the found one does not fully contain the searched range, it will re-scan the guest tree in order to find a matching VAD. If the VAD is taken from the guest, it is inserted in the VAD tree of the given process.

Parameters
[in]ProcessThe process for which the search is done.
[in]StartHintThe start page of the range by which to search for the VAD.
[in]LengthHintThe length of the range by which to search for the VAD. The last page in the range will be StartHint + LengthHint -1, rounded down to page size.
Returns
The found VAD structure, or the newly created VAD structure. NULL if the VAD is not found neither in the Introcore tree, nor the guest tree.

Definition at line 2122 of file winvad.c.

Referenced by IntExceptGetVictimProcess(), and IntWinProcHandleCopyMemory().

◆ IntWinVadFindByVa()

VAD* IntWinVadFindByVa ( WIN_PROCESS_OBJECT Process,
QWORD  Va 
)

Finds a VAD that contains a given guest virtual address.

Parameters
[in]ProcessThe process that owns the VAD tree in which the search is done.
[in]VaThe VA for which the search is done.
Returns
A pointer to a VAD that contains the given guest virtual address, or NULL if no VAD is found.

Definition at line 602 of file winvad.c.

Referenced by IntWinVadHandleCommit().

◆ IntWinVadFindNodeInGuestSpace()

QWORD IntWinVadFindNodeInGuestSpace ( QWORD  VadRoot,
QWORD  StartPage,
QWORD  EndPage,
DWORD  Level,
QWORD  OldStartPage,
BOOLEAN  LastBranchRight 
)

Searches for a VAD node inside a guest VAD tree.

This performs an in-order recursive traversal of the guest VAD tree.

The [StartPage, EndPage] range is inclusive.

Parameters
[in]VadRootThe root of the VAD tree. This is usually the value of the VadRoot field of an _EPROCESS structure.
[in]StartPageThe first page of the searched VAD.
[in]EndPageThe last page of the searched VAD.
[in]LevelThe level for which this function is invoked. Should be 0 when starting a new search.
[in]OldStartPageThe start page for the VAD at the previous level. Should be 0 when starting a new search.
[in]LastBranchRightTrue if the last branch taken was the right one. Should be False when starting a new search.
Returns
The guest virtual address of the searched VAD, or 0 if no VAD was found.

Definition at line 1825 of file winvad.c.

Referenced by DbgVadFind(), IntWinVadFetchByRange(), IntWinVadHandleProtectGeneric(), IntWinVadProcImportMainModuleVad(), and IntWinVadRescanVad().

◆ IntWinVadImportProcessTree()

INTSTATUS IntWinVadImportProcessTree ( WIN_PROCESS_OBJECT Process)

Scans the guest VAD tree and imports the nodes into our VAD tree.

Parameters
[in,out]ProcessThe process for which the scan is done. On success, WIN_PROCESS_OBJECT.VadTree will be populated wit the relevant VADs.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Process is NULL.
INT_STATUS_NOT_NEEDED_HINTif the process VAD root is not yet initialized. This means that the process does not have any VADs yet, and we will detect all the VADs we need dynamically when they are created.

Definition at line 2768 of file winvad.c.

Referenced by IntWinProcChangeProtectionFlags(), and IntWinVadReimportProcessTree().

◆ IntWinVadInOrderRecursiveTraversal()

INTSTATUS IntWinVadInOrderRecursiveTraversal ( QWORD  VadNodeGva,
DWORD  Level,
PFUNC_WinVadTraversalCallback  Callback,
void *  Context 
)

Traverses a guest VAD tree.

This function is recursive and will call itself for every node in the tree, starting from VadNodeGva. The tree is traversed in order. Recursion is stopped after we go past level 64.

Parameters
[in]VadNodeGvaThe guest virtual address of the node for which this function was called. When starting a new traversal this should be the root of the tree.
[in]LevelThe level for which this function is called. It is used in order to know when to stop the traversal, for trees that seem to have more levels than we can handle. Should be 0 when starting a new search.
[in]CallbackCallback to be invoked for every node in the tree. Errors returned by this callback are not propagated back to the caller.
[in]ContextOptional context to be passed to Callback each time it is invoked.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if VadNodeGva is not a valid kernel pointer.
INT_STATUS_INVALID_PARAMETER_3if Callback is NULL.

Definition at line 1920 of file winvad.c.

Referenced by DbgDumpVadRoot(), and IntWinVadImportProcessTree().

◆ IntWinVadIsInTree()

BOOLEAN IntWinVadIsInTree ( const VAD Vad)

Checks if a VAD is inserted in a guest VAD tree.

This function checks that the node for the provided VAD has a valid parent, and that the parent it points to has the VAD either as the Left, or as the Right child.

Parameters
[in]VadThe VAD that will be checked.
Return values
Trueif the VAD is inserted in a tree.
Falseif the VAD is not inserted in a tree.

Definition at line 3437 of file winvad.c.

Referenced by IntModBlockHandlePreInjection(), and IntWinModHandlePreInjection().

◆ IntWinVadProcessInit()

void IntWinVadProcessInit ( WIN_PROCESS_OBJECT Process)

Initializes a WIN_PROCESS_OBJECT.VadTree.

This will call RbPreInit and RbInit for the tree and set IntWinVadRbTreeNodeFree as the RBTREE.NodeFree function and IntWinVadRbTreeNodeCompare as the RBTREE.NodeCompare function.

Parameters
[in,out]ProcessThe process for which the VAD tree will be initialized.

Definition at line 462 of file winvad.c.

Referenced by IntWinProcCreateProcessObject().

◆ IntWinVadProcImportMainModuleVad()

INTSTATUS IntWinVadProcImportMainModuleVad ( WIN_PROCESS_OBJECT Process)

Imports the VAD that describes the main module of a process.

Parameters
[in,out]ProcessThe process that owns the VAD.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Process is NULL.

Definition at line 3816 of file winvad.c.

Referenced by IntWinProcCreateProcessObject().

◆ IntWinVadRemoveProcessTree()

INTSTATUS IntWinVadRemoveProcessTree ( WIN_PROCESS_OBJECT Process)

Removes the VAD tree from a process.

Parameters
[in,out]ProcessThe process for which the tree is removed.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Process is NULL.

Definition at line 1351 of file winvad.c.

Referenced by IntWinProcChangeProtectionFlags(), and IntWinVadReimportProcessTree().

◆ IntWinVadShortDump()

INTSTATUS IntWinVadShortDump ( QWORD  VadNodeGva,
DWORD  Level,
void *  Context 
)

Prints a _MMVAD_SHORT structure.

Parameters
[in]VadNodeGvaThe guest virtual address of the _MMVAD_SHORT structure.
[in]LevelThe level at which the node is located inside the VAD tree.
[in]ContextIgnored.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1659 of file winvad.c.

Referenced by DbgDumpVadRoot().

◆ IntWinVadStopExploitMonitor()

void IntWinVadStopExploitMonitor ( WIN_PROCESS_OBJECT Process)

Disables the exploit monitoring for a process.

Parameters
[in,out]ProcessThe process for which to stop the exploit protection.

Definition at line 1811 of file winvad.c.

Referenced by IntWinProcChangeProtectionFlags().

◆ IntWinVadWalkTree()

INTSTATUS IntWinVadWalkTree ( PWIN_PROCESS_OBJECT  Process,
PFUNC_RbTreeWalkCallback  Callback 
)

Walks the VAD tree of a process.

Parameters
[in]ProcessThe process for which the walk is done.
[in]CallbackCallback to be invoked for each node in the tree. If the callback returns False, the walk is stopped. No context is passed to Callback.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1is Process is NULL.
INT_STATUS_INVALID_PARAMETER_2is Callback is NULL.

Definition at line 2025 of file winvad.c.

Referenced by IntWinProcDump(), and IntWinProcDumpVads().