Bitdefender Hypervisor Memory Introspection
winprocesshp.c File Reference
#include "winprocesshp.h"
#include "guests.h"
#include "vasmonitor.h"
#include "winummodule.h"

Go to the source code of this file.

Macros

#define IS_INVALID_PTR(ptr)
 
#define PROCESSES_MAX_COUNT   65535
 

Functions

void IntWinProcLstUnsafeReInit (void)
 Reinitializes the Windows process lists and trees, without doing any cleanup. More...
 
void IntWinProcLstInsertProcess (WIN_PROCESS_OBJECT *Process)
 Inserts a WIN_PROCESS_OBJECT structure into the process lists and trees. More...
 
void IntWinProcLstRemoveProcess (WIN_PROCESS_OBJECT *Process)
 Removes a WIN_PROCESS_OBJECT structure from the process lists and trees. More...
 
PWIN_PROCESS_OBJECT IntWinProcFindObjectByEprocess (QWORD Eprocess)
 Finds a process by the address of its _EPROCESS structure. More...
 
PWIN_PROCESS_OBJECT IntWinProcFindObjectByPid (DWORD Pid)
 Finds a process by its ID. More...
 
PWIN_PROCESS_OBJECT IntWinProcFindObjectByName (CHAR const *Name, BOOLEAN MustBeSystem)
 Finds a process by name. More...
 
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3 (QWORD Cr3)
 Finds a process by its kernel CR3. More...
 
PWIN_PROCESS_OBJECT IntWinProcFindObjectByUserCr3 (QWORD Cr3)
 Finds a process by its user CR3. More...
 
INTSTATUS IntWinProcIsPsActiveProcessHead (QWORD Gva)
 Checks if a guest memory area is the list head of the process list (PsActiveProcessHead) More...
 
INTSTATUS IntWinProcAdd (QWORD Eprocess, QWORD Aux)
 Adds a new process to the Introcore list of processes. More...
 
INTSTATUS IntWinProcIterateGuestProcesses (PFUNC_IterateListCallback Callback, QWORD Aux)
 Iterates the in-guest process list and calls Callback for each entry. More...
 
INTSTATUS IntWinProcGetNameFromEprocess (QWORD Eprocess, CHAR *Name)
 Reads a process name from the guest memory. More...
 
INTSTATUS IntWinProcGetNameFromInternalEprocess (QWORD Eprocess, CHAR *Name)
 Get a process name from the internal Introcore buffers. More...
 
BOOLEAN IntWinProcIsEnoughHeapAvailable (void)
 Checks if enough heap is available in order to protect a new process. More...
 
void IntWinProcRbTreeNodeFree (RBNODE *Node)
 The NodeFree routine for the process RBTREE structures. More...
 
int IntWinProcRbTreeNodeCompareCr3 (RBNODE const *Left, RBNODE const *Right)
 
int IntWinProcRbTreeNodeCompareUserCr3 (RBNODE const *Left, RBNODE const *Right)
 
int IntWinProcRbTreeNodeCompareEproc (RBNODE const *Left, RBNODE const *Right)
 
INTSTATUS IntWinProcGetAgentsAsCli (PCHAR CommandLine, DWORD Length)
 Returns the name and ID for all the processes injected as agents inside the guest. More...
 
void IntWinProcDump (void)
 Prints information about all the processes in the system. More...
 
void IntWinProcDumpVads (const char *ProcessName)
 Prints information about the VADs loaded in a process. More...
 
void IntWinProcDumpEgFlags (void)
 Prints the mitigation flags of a process. More...
 
INTSTATUS IntWinProcMapEprocess (QWORD Eprocess, void **Ptr)
 Maps a _EPROCESS structure. More...
 

Variables

LIST_HEAD gWinProcesses = LIST_HEAD_INIT(gWinProcesses)
 The list of all the processes inside the guest. More...
 
RBTREE gWinProcTreeCr3 = RB_TREE_INIT(gWinProcTreeCr3, IntWinProcRbTreeNodeFree, IntWinProcRbTreeNodeCompareCr3)
 Tree of all the processes inside the guest, using the kernel CR3 as the key. More...
 
RBTREE gWinProcTreeUserCr3
 Tree of all the processes inside the guest, using the user-mode CR3 as the key/. More...
 
RBTREE gWinProcTreeEprocess
 Tree of all the processes inside the guest, using the _EPROCESS address as the key. More...
 

Macro Definition Documentation

◆ IS_INVALID_PTR

#define IS_INVALID_PTR (   ptr)
Value:
(gGuest.Guest64 && 0xffffffff00000000 == ((ptr) & 0xffffffff00000000)) || \
(!gGuest.Guest64 && 0xffffffff == (ptr)) \
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
Definition: wddefs.h:76
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50

Referenced by IntWinProcIsPsActiveProcessHead().

◆ PROCESSES_MAX_COUNT

#define PROCESSES_MAX_COUNT   65535

Function Documentation

◆ IntWinProcAdd()

INTSTATUS IntWinProcAdd ( QWORD  Eprocess,
QWORD  Aux 
)

Adds a new process to the Introcore list of processes.

This function is used for statically detecting processes that were spawned before Introcore started.

This does some preliminary checks and then delegates much of the work to IntWinProcCreateProcessObject. If any of the Delete, Exiting, or VmDeleted flags are set, or if the HasAddrSpace flag is not set, the process is ignored as it is no longer active and won't become active again, but the OS did not remove it from the list of processes yet.

If possible, this function will try to find the parent of the current process.

Parameters
[in]EprocessGuest virtual address of the _EPROCESS structure for the new process.
[in]AuxIgnored.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 396 of file winprocesshp.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinProcDump()

void IntWinProcDump ( void  )

Prints information about all the processes in the system.

Definition at line 864 of file winprocesshp.c.

Referenced by DbgDumpProcesses().

◆ IntWinProcDumpEgFlags()

void IntWinProcDumpEgFlags ( void  )

Prints the mitigation flags of a process.

Definition at line 1005 of file winprocesshp.c.

◆ IntWinProcDumpVads()

void IntWinProcDumpVads ( const char *  ProcessName)

Prints information about the VADs loaded in a process.

Parameters
[in]ProcessNameNULL-terminated string with a process name. May be NULL. If it is not NULL, only the processes with a matching name will be printed.

Definition at line 977 of file winprocesshp.c.

Referenced by DbgDumpVads().

◆ IntWinProcFindObjectByCr3()

◆ IntWinProcFindObjectByEprocess()

◆ IntWinProcFindObjectByName()

PWIN_PROCESS_OBJECT IntWinProcFindObjectByName ( CHAR const *  Name,
BOOLEAN  MustBeSystem 
)

Finds a process by name.

Parameters
[in]NameNULL-terminated string with the name of the process.
[in]MustBeSystemTrue if the process must be a system process.
Returns
A pointer to a WIN_PROCESS_OBJECT for the found process, or NULL if no process exists.

Definition at line 157 of file winprocesshp.c.

Referenced by IntWinAgentHandleDriverVmcall().

◆ IntWinProcFindObjectByPid()

PWIN_PROCESS_OBJECT IntWinProcFindObjectByPid ( DWORD  Pid)

Finds a process by its ID.

Parameters
[in]PidProcess ID to search for.
Returns
A pointer to a WIN_PROCESS_OBJECT for the found process, or NULL if no process exists.

Definition at line 126 of file winprocesshp.c.

Referenced by IntWinGetStartUpTime(), and IntWinProcAdd().

◆ IntWinProcFindObjectByUserCr3()

PWIN_PROCESS_OBJECT IntWinProcFindObjectByUserCr3 ( QWORD  Cr3)

Finds a process by its user CR3.

If KPTI is not active, or the process has the same CR3 for both kernel and user mode, this is the same as IntWinProcFindObjectByCr3.

Parameters
[in]Cr3Process user CR3 to search for.
Returns
A pointer to a WIN_PROCESS_OBJECT for the found process, or NULL if no process exists.

Definition at line 225 of file winprocesshp.c.

Referenced by IntGetGprs().

◆ IntWinProcGetAgentsAsCli()

INTSTATUS IntWinProcGetAgentsAsCli ( PCHAR  CommandLine,
DWORD  Length 
)

Returns the name and ID for all the processes injected as agents inside the guest.

This is useful for the killer agent.

Parameters
[out]CommandLineOn success, will contain a NULL-terminated string with the names and IDs of the agent processes.
[in]LengthThe size of the CommandLine buffer.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_DATA_BUFFER_TOO_SMALLif there is not enough space in the CommandLine buffer.

Definition at line 812 of file winprocesshp.c.

Referenced by IntWinFormatAgentKillerCommandLine().

◆ IntWinProcGetNameFromEprocess()

INTSTATUS IntWinProcGetNameFromEprocess ( QWORD  Eprocess,
CHAR Name 
)

Reads a process name from the guest memory.

This reads the name from the _EPROCESS ImageFileName field. If the process name has more than 15 characters, only the first 15 characters will be available.

Parameters
[in]EprocessThe guest virtual address of the _EPROCESS structure.
[out]NameOn success, will contain a NULL-terminated string with the process name. Must be at least IMAGE_BASE_NAME_LEN in size.
Returns
A pointer to a WIN_PROCESS_OBJECT for the found process, or NULL if no process exists.

Definition at line 615 of file winprocesshp.c.

◆ IntWinProcGetNameFromInternalEprocess()

INTSTATUS IntWinProcGetNameFromInternalEprocess ( QWORD  Eprocess,
CHAR Name 
)

Get a process name from the internal Introcore buffers.

Parameters
[in]EprocessThe guest virtual address of the _EPROCESS structure.
[out]NameOn success, will contain a NULL-terminated string with the process name. Must be at least IMAGE_BASE_NAME_LEN in size.
Return values
INT_STATUS_SUCCESSif a process was found for the provided _EPROCESS address.
INT_STATUS_NOT_FOUNDif no process was found.

Definition at line 648 of file winprocesshp.c.

Referenced by IntWinProcDump().

◆ IntWinProcIsEnoughHeapAvailable()

BOOLEAN IntWinProcIsEnoughHeapAvailable ( void  )

Checks if enough heap is available in order to protect a new process.

We consider that enough memory is available if a percentage of MIN_HEAP_SIZE_PERCENT is free from the total amount of available memory.

Returns
True if enough memory is available, False if not.

Definition at line 685 of file winprocesshp.c.

Referenced by IntWinProcProtect().

◆ IntWinProcIsPsActiveProcessHead()

INTSTATUS IntWinProcIsPsActiveProcessHead ( QWORD  Gva)

Checks if a guest memory area is the list head of the process list (PsActiveProcessHead)

Gva must point to the ActiveProcessLinks field of the System _EPROCESS.

The check is based on a series of invariants:

  • Gva must not be inside the kernel image
  • The Flink and Blink fields must point in the kernel space.
  • Flink->Blink and Blink->Flink must point back to Gva.
  • The _EPROCESS must be readable.
  • The PID must be 4.
  • The Type field from the _DISPATCHER_HEADER must be 3.
  • The process name must be "System".
Parameters
[in]GvaGuest virtual address to check.
Return values
INT_STATUS_SUCCESSif Gva points to PsActiveProcessHead.
INT_STATUS_INVALID_OBJECT_TYPEif Gva does not point to PsActiveProcessHead.

Definition at line 258 of file winprocesshp.c.

Referenced by IntWinGuestFindKernelObjectsInternal().

◆ IntWinProcIterateGuestProcesses()

INTSTATUS IntWinProcIterateGuestProcesses ( PFUNC_IterateListCallback  Callback,
QWORD  Aux 
)

Iterates the in-guest process list and calls Callback for each entry.

This function will stop if it iterates more than 10000 entries, as in that case something is most likely wrong.

Parameters
[in]CallbackFunction to invoke for each entry in the process list.
[in]AuxOptional argument to pass to Callback.
Return values
INT_STATUS_SUCCESSin case of success. Note that errors returned by Callback are not propagated and success is still reported.
INT_STATUS_INVALID_PARAMETER_1if Callback is NULL.
INT_STATUS_NOT_INITIALIZED_HINTif PsActiveProcessHead is not set yet.
INT_STATUS_OUT_OF_RANGEif more than 10000 processes are found in the list.

Definition at line 501 of file winprocesshp.c.

Referenced by IntThrSafeCheckThreads(), and IntWinGuestFinishInit().

◆ IntWinProcLstInsertProcess()

void IntWinProcLstInsertProcess ( WIN_PROCESS_OBJECT Process)

Inserts a WIN_PROCESS_OBJECT structure into the process lists and trees.

This will add the process to the gWinProcesses list, and gWinProcTreeCr3, gWinProcTreeUserCr3, and gWinProcTreeEprocess trees.

Parameters
[in]ProcessThe process to be inserted.

Definition at line 46 of file winprocesshp.c.

Referenced by IntWinProcCreateProcessObject().

◆ IntWinProcLstRemoveProcess()

void IntWinProcLstRemoveProcess ( WIN_PROCESS_OBJECT Process)

Removes a WIN_PROCESS_OBJECT structure from the process lists and trees.

This will remove the process from the gWinProcesses list, and gWinProcTreeCr3, gWinProcTreeUserCr3, and gWinProcTreeEprocess trees.

Parameters
[in]ProcessThe process to be removed.

Definition at line 73 of file winprocesshp.c.

Referenced by IntWinProcDeleteProcessObject(), and IntWinProcUninit().

◆ IntWinProcLstUnsafeReInit()

void IntWinProcLstUnsafeReInit ( void  )

Reinitializes the Windows process lists and trees, without doing any cleanup.

This resets the gWinProcesses lists, and the gWinProcTreeCr3, gWinProcTreeUserCr3, and gWinProcTreeEprocess trees. This function does no cleanup, so if there are any processes inside the list or trees those will not be freed, the hooks placed in their context will not be removed, etc.

Definition at line 22 of file winprocesshp.c.

◆ IntWinProcMapEprocess()

INTSTATUS IntWinProcMapEprocess ( QWORD  Eprocess,
void **  Ptr 
)

Maps a _EPROCESS structure.

This will map the minimum necessary size for Introcore to parse an _EPROCESS. IntVirtMemUnmap must be used to unmap a mapped process.

Parameters
[in]EprocessGuest virtual address of the _EPROCESS structure to be mapped.
[out]PtrOn success, will contain a pointer to the mapped memory.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1142 of file winprocesshp.c.

Referenced by IntWinProcAdd(), IntWinProcHandleCreateInternal(), and IntWinProcSwapIn().

◆ IntWinProcRbTreeNodeCompareCr3()

int IntWinProcRbTreeNodeCompareCr3 ( RBNODE const *  Left,
RBNODE const *  Right 
)

Definition at line 735 of file winprocesshp.c.

Referenced by IntWinProcLstUnsafeReInit().

◆ IntWinProcRbTreeNodeCompareEproc()

int IntWinProcRbTreeNodeCompareEproc ( RBNODE const *  Left,
RBNODE const *  Right 
)

Definition at line 789 of file winprocesshp.c.

Referenced by IntWinProcLstUnsafeReInit().

◆ IntWinProcRbTreeNodeCompareUserCr3()

int IntWinProcRbTreeNodeCompareUserCr3 ( RBNODE const *  Left,
RBNODE const *  Right 
)

Definition at line 762 of file winprocesshp.c.

Referenced by IntWinProcLstUnsafeReInit().

◆ IntWinProcRbTreeNodeFree()

void IntWinProcRbTreeNodeFree ( RBNODE Node)

The NodeFree routine for the process RBTREE structures.

Definition at line 723 of file winprocesshp.c.

Referenced by IntWinProcLstUnsafeReInit().

Variable Documentation

◆ gWinProcesses

LIST_HEAD gWinProcesses = LIST_HEAD_INIT(gWinProcesses)

The list of all the processes inside the guest.

Definition at line 11 of file winprocesshp.c.

◆ gWinProcTreeCr3

Tree of all the processes inside the guest, using the kernel CR3 as the key.

Definition at line 13 of file winprocesshp.c.

◆ gWinProcTreeEprocess

RBTREE gWinProcTreeEprocess
Initial value:
RBTREE gWinProcTreeEprocess
Tree of all the processes inside the guest, using the _EPROCESS address as the key.
Definition: winprocesshp.c:18
void IntWinProcRbTreeNodeFree(RBNODE *Node)
The NodeFree routine for the process RBTREE structures.
Definition: winprocesshp.c:723
int IntWinProcRbTreeNodeCompareEproc(RBNODE const *Left, RBNODE const *Right)
Definition: winprocesshp.c:789
#define RB_TREE_INIT(Name, Free, Compare)
Initializes a RBTREE structure.
Definition: introcore.h:39

Tree of all the processes inside the guest, using the _EPROCESS address as the key.

Definition at line 18 of file winprocesshp.c.

◆ gWinProcTreeUserCr3

RBTREE gWinProcTreeUserCr3
Initial value:
int IntWinProcRbTreeNodeCompareUserCr3(RBNODE const *Left, RBNODE const *Right)
Definition: winprocesshp.c:762
void IntWinProcRbTreeNodeFree(RBNODE *Node)
The NodeFree routine for the process RBTREE structures.
Definition: winprocesshp.c:723
#define RB_TREE_INIT(Name, Free, Compare)
Initializes a RBTREE structure.
Definition: introcore.h:39
RBTREE gWinProcTreeUserCr3
Tree of all the processes inside the guest, using the user-mode CR3 as the key/.
Definition: winprocesshp.c:15

Tree of all the processes inside the guest, using the user-mode CR3 as the key/.

Definition at line 15 of file winprocesshp.c.