Bitdefender Hypervisor Memory Introspection
lixmm.h File Reference
#include "lixprocess.h"

Go to the source code of this file.

Data Structures

struct  _LIX_VMA
 

Typedefs

typedef struct _LIX_VMA LIX_VMA
 
typedef struct _LIX_VMAPLIX_VMA
 

Functions

INTSTATUS IntLixMmGetInitMm (QWORD *InitMm)
 Find the address of the "init_mm" variable inside the kernel. More...
 
INTSTATUS IntLixMmFindVmaRange (QWORD Gva, LIX_TASK_OBJECT *Task, QWORD *VmaStart, QWORD *VmaEnd)
 Finds the VMA limits that contain an address. More...
 
INTSTATUS IntLixMmFetchVma (LIX_TASK_OBJECT *Task, QWORD Address, LIX_VMA *Vma)
 Retrieve information about a VMA structure containing a user mode address. More...
 
LIX_VMAIntLixMmFindVma (LIX_TASK_OBJECT *Task, QWORD Vma)
 Finds a protected VMA inside a process VMA list. More...
 
LIX_VMAIntLixMmFindVmaByRange (const LIX_TASK_OBJECT *Process, QWORD Address)
 Finds if a memory address inside a process is being protected and returns the corresponding LIX_VMA structure. More...
 
INTSTATUS IntLixMmPopulateVmas (LIX_TASK_OBJECT *Task)
 Populate the Introcore VMAs linked list by iterating the one inside the guest. More...
 
void IntLixMmDestroyVmas (LIX_TASK_OBJECT *Task)
 Remove protection for the VMAs belonging to a process. More...
 
void IntLixMmListVmas (QWORD Mm, LIX_TASK_OBJECT *Process)
 
INTSTATUS IntLixVmaInsert (void *Detour)
 Detour handler for "__vma_link_rb" function. More...
 
INTSTATUS IntLixVmaChangeProtection (void *Detour)
 Detour handler for "change_protection" function. More...
 
INTSTATUS IntLixVmaAdjust (void *Detour)
 Detour handler for in-guest functions adjusting VMA ranges. More...
 
INTSTATUS IntLixVmaExpandDownwards (void *Detour)
 Detour handler for "expand_downwards" function. More...
 
INTSTATUS IntLixVmaRemove (void *Detour)
 Detour handler for functions that unmap memory for processes. More...
 

Typedef Documentation

◆ LIX_VMA

typedef struct _LIX_VMA LIX_VMA

Describes one VMA structure.

◆ PLIX_VMA

typedef struct _LIX_VMA * PLIX_VMA

Function Documentation

◆ IntLixMmDestroyVmas()

void IntLixMmDestroyVmas ( LIX_TASK_OBJECT Task)

Remove protection for the VMAs belonging to a process.

Parameters
[in]TaskThe process whose VMAs will be unprotected.

Definition at line 1016 of file lixmm.c.

Referenced by IntLixMmPopulateVmas(), and IntLixTaskDeactivateExploitProtection().

◆ IntLixMmFetchVma()

INTSTATUS IntLixMmFetchVma ( LIX_TASK_OBJECT Task,
QWORD  Address,
LIX_VMA Vma 
)

Retrieve information about a VMA structure containing a user mode address.

Parameters
[in]TaskThe process on whose mm space the address should be searched.
[in]AddressThe searched address.
[out]VmaUpon successful return will contain information about the requested VMA.
Returns
INT_STATUS_SUCCESS on success.
INT_STATUS_INVALID_PARAMETER_* if any parameter is invalid.
INT_STATUS_NOT_FOUND if the requested VMA was not found.

Definition at line 581 of file lixmm.c.

Referenced by IntLixCredAnalyzeStack(), IntLixMmFindVmaRange(), and IntLixStackDumpUmStackTrace().

◆ IntLixMmFindVma()

LIX_VMA* IntLixMmFindVma ( LIX_TASK_OBJECT Task,
QWORD  Vma 
)

Finds a protected VMA inside a process VMA list.

Parameters
[in]TaskThe process in whose list the Vma should be found.
[in]VmaThe Gva of a VMA object.
Returns
NULL if the VMA was not found.
The LIX_VMA object associated with the Vma parameter.

Definition at line 871 of file lixmm.c.

Referenced by IntLixVmaAdjustInternal(), IntLixVmaChangeProtection(), IntLixVmaExpandDownwards(), IntLixVmaInsert(), and IntLixVmaRemove().

◆ IntLixMmFindVmaByRange()

LIX_VMA* IntLixMmFindVmaByRange ( const LIX_TASK_OBJECT Process,
QWORD  Address 
)

Finds if a memory address inside a process is being protected and returns the corresponding LIX_VMA structure.

Parameters
[in]Process
[in]Address
Returns
NULL if the address is not being protected.
The LIX_VMA structure containing the address.

Definition at line 699 of file lixmm.c.

Referenced by IntExceptGetVictimEpt(), and IntLixVmaHandlePageExecution().

◆ IntLixMmFindVmaRange()

INTSTATUS IntLixMmFindVmaRange ( QWORD  Gva,
LIX_TASK_OBJECT Task,
QWORD VmaStart,
QWORD VmaEnd 
)

Finds the VMA limits that contain an address.

Parameters
[in]GvaThe address that will be searched.
[in]TaskThe process the process on whose address space the search will be performed.
[out]VmaStartUpon successful return will contain the lower limit of the VMA.
[out]VmaEndUpon successful return will contain the upper limit of the VMA.
Returns
INT_STATUS_SUCCESS on success.
INT_STATUS_INVALID_PARAMETER_* if any parameter is invalid.

Definition at line 640 of file lixmm.c.

Referenced by IntLixTaskGetUserStack(), and IntLixTaskIsUserStackPivoted().

◆ IntLixMmGetInitMm()

INTSTATUS IntLixMmGetInitMm ( QWORD InitMm)

Find the address of the "init_mm" variable inside the kernel.

Searches the linux kernel for the 'init_mm' variable. This variable can be exported in kallsyms but some distros (Debian) disable variable exporting in kallsyms, and we must do it our way then.

Linux kernel v5.5 defines the init_mm as follows:

If the "init_mm" address couldn't be resolved via kallsyms then this function will perform a search inside the ".data" section and will apply the following heuristic in order to determine it's address:

  1. _sdata <= init_mm.pgd < _edata
  2. init_mm.mm_list must be a linked list which means the following two conditions must be met:
    • init_mm.mm_list->next->prev == init_mm
    • init_mm.mm_list->prev->next == init_mm
  3. init_mm.start_code == _etext
  4. init_mm.end_code == _etext
  5. init_mm.start_data == 0 || init_mm.start_data = _sdata
  6. init_mm.end_data == 0 || init_mm.end_data ~ _edata. In some cases the address of "_edata" symbol is just an approximate value.
Parameters
[out]InitMmUpon successful return will contain the address of the init_mm symbol.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_INVALID_PARAMETER_1 If the InitMm parameter does not point to a valid memory location.
INT_STATUS_NOT_FOUND If the symbol address was not found.

Definition at line 76 of file lixmm.c.

Referenced by IntLixGuestNew().

◆ IntLixMmListVmas()

void IntLixMmListVmas ( QWORD  Mm,
LIX_TASK_OBJECT Process 
)

Logs all VMAs from a mm_struct.

Parameters
[in]MmThe mm_struct GVA.
[in]ProcessPointer to a LIX_TASK_OBJECT structure.

Definition at line 1671 of file lixmm.c.

Referenced by IntLixTaskDump().

◆ IntLixMmPopulateVmas()

INTSTATUS IntLixMmPopulateVmas ( LIX_TASK_OBJECT Task)

Populate the Introcore VMAs linked list by iterating the one inside the guest.

This function will iterate the in-guest VMA list and attempt to protect the ones which are marked as executable.

Parameters
[in]TaskThe process whose VMA list should be populated.
Returns
INT_STATUS_SUCCESS On success.

Definition at line 1510 of file lixmm.c.

Referenced by IntLixTaskActivateExploitProtection().

◆ IntLixVmaAdjust()

INTSTATUS IntLixVmaAdjust ( void *  Detour)

Detour handler for in-guest functions adjusting VMA ranges.

This function checks the result of the "vma_adjust" call and adjust the protection for the affected VMAs.

Parameters
[in]DetourUnused.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_NOT_NEEDED_HINT If the process is either not recognized or it's not being protected.

Definition at line 2052 of file lixmm.c.

◆ IntLixVmaChangeProtection()

INTSTATUS IntLixVmaChangeProtection ( void *  Detour)

Detour handler for "change_protection" function.

This function is called whenever a VMA belonging to a protected memory space is making a transition from executable to non-executable and vice-versa. If the VMA if being marked as executable than this function will establish the protection, otherwise the protection will be removed and it will be marked as unprotected.

Parameters
[in]DetourUnused.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_NOT_NEEDED_HINT If the process is not recognized, it is not protected or the vma is not protected.

Definition at line 1753 of file lixmm.c.

◆ IntLixVmaExpandDownwards()

INTSTATUS IntLixVmaExpandDownwards ( void *  Detour)

Detour handler for "expand_downwards" function.

This function updates the protection for VMAs which are able to expand downwards (usually this is the case for stack VMAs). It checks if the lower limit has changed and updates the protected memory range.

Parameters
[in]DetourUnused.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_NOT_NEEDED_HINT If the process is not recognized, it is not protected or the vma is not protected.

Definition at line 1906 of file lixmm.c.

◆ IntLixVmaInsert()

INTSTATUS IntLixVmaInsert ( void *  Detour)

Detour handler for "__vma_link_rb" function.

This function is called when an executable VMA is being created. If the newly created VMA is already protected (by a previous vma_adjust call) then it will be ignored.

Parameters
[in]DetourUnused.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_NOT_NEEDED_HINT If the process is not recognized, it is not protected or the vma is not protected.

Definition at line 1692 of file lixmm.c.

◆ IntLixVmaRemove()

INTSTATUS IntLixVmaRemove ( void *  Detour)

Detour handler for functions that unmap memory for processes.

This functions removes the protection from a vma as it's being unmapped from the process memory space. Usually, the kernel function that will trigger this event is "(__)vma_rb_erase". Because the support for RHEL 6 required lots of hacks and workarounds, other functions may trigger this. However, every detour must provide this function the Gva of the removed VMA in R8 register and the Gva mm struct owning the VMA in R9 register.

Parameters
[in]DetourUnused.
Returns
INT_STATUS_SUCCESS On success.
INT_STATUS_NOT_NEEDED_HINT If the process is not recognized, it is not protected or the vma is not protected.

Definition at line 2111 of file lixmm.c.