Bitdefender Hypervisor Memory Introspection
lixksym.c File Reference
#include "lixksym.h"
#include "guests.h"

Go to the source code of this file.

Data Structures

struct  _KALLSYMS_BUFFERS
 Describes the structure of the internal kallsyms buffers and other data required for the semantic reconstruction. More...
 

Macros

#define KSYM_NUM_SYMBOLS_CAP   200000
 The maximum number of symbols allowed to be in kallsyms. More...
 
#define KSYM_TOKEN_TABLE_SIZE_CAP   2000
 The maximum size allowed for the tokens table size. More...
 
#define KSYM_NAMES_CACHE_SIZE_CAP   2000000
 The maximum size allowed for the names. More...
 
#define KSYM_TOKEN_ARRAY_CACHE_SIZE   256
 The size of tokens array cache. More...
 
#define KSYM_MARKERS_RANGE_MAX   0x3000
 The maximum value for [ksym_marker, ksym_marker + 1] range. More...
 

Typedefs

typedef struct _KALLSYMS_BUFFERS KALLSYMS_BUFFERS
 Describes the structure of the internal kallsyms buffers and other data required for the semantic reconstruction. More...
 
typedef struct _KALLSYMS_BUFFERSPKALLSYMS_BUFFERS
 

Functions

static DWORD IntKsymExpandSymbol (DWORD Offset, DWORD MaxLength, char *Name)
 Expands a kallsyms symbol name. More...
 
static QWORD IntKsymGetAddress (INT32 Index)
 Returns the address of the symbol located at the given index in the symbols table. More...
 
static INTSTATUS IntKsymRelativeFindOffsetTableStart (QWORD *Address)
 Finds the start of 'kallsyms_offsets' memory region. More...
 
static INTSTATUS IntKsymRelativeFindOffsetTableEnd (QWORD StartAddress)
 Finds the end of 'kallsyms_offsets' memory region. More...
 
static INTSTATUS IntKsymInitRelative (void)
 Initializes the kallsyms subsystem for kernels compiled with CONFIG_KALLSYMS_BASE_RELATIVE. More...
 
static INTSTATUS IntKsymInitAbsolute (void)
 Initializes the kallsyms subsystem for kernels compiled without CONFIG_KALLSYMS_BASE_RELATIVE. More...
 
static INTSTATUS IntKsymFindMarkersTableEnd (QWORD StartAddress, QWORD *EndAddress)
 Finds the end of 'kallsyms_markers' table. More...
 
static INTSTATUS IntKsymFindMarkersReducedTableEnd (QWORD StartAddress, QWORD *EndAddress)
 Finds the end of 'kallsyms_markers' table. More...
 
static INTSTATUS IntKsymFindNamesTableEnd (QWORD StartAddress, QWORD *EndAddress)
 Finds the end of 'kallsyms_names' table. More...
 
static INTSTATUS IntKsymFindIndexesTableStart (QWORD TokenTableStart, QWORD *IndexesTableStart)
 Finds the start of 'kallsyms_token_index' table. More...
 
INTSTATUS IntKsymInit (void)
 Initialize the kallsyms subsystem based on the os info provided by LIX_FIELD(Info, HasKsym*). More...
 
void IntKsymUninit (void)
 
INTSTATUS IntKsymFindByAddress (QWORD Gva, DWORD Length, char *SymName, QWORD *SymStart, QWORD *SymEnd)
 Finds the symbol which is located at the given address. More...
 
QWORD IntKsymFindByName (const char *Name, QWORD *SymEnd)
 Searches the given Name in kallsyms and returns the Start & End offset. More...
 

Variables

static KALLSYMS_BUFFERS gKallsymsBuffers
 Contains information about kallsyms required for the semantic reconstruction. More...
 

Macro Definition Documentation

◆ KSYM_MARKERS_RANGE_MAX

#define KSYM_MARKERS_RANGE_MAX   0x3000

The maximum value for [ksym_marker, ksym_marker + 1] range.

Definition at line 13 of file lixksym.c.

Referenced by IntKsymFindMarkersReducedTableEnd().

◆ KSYM_NAMES_CACHE_SIZE_CAP

#define KSYM_NAMES_CACHE_SIZE_CAP   2000000

The maximum size allowed for the names.

Definition at line 11 of file lixksym.c.

Referenced by IntKsymInit().

◆ KSYM_NUM_SYMBOLS_CAP

#define KSYM_NUM_SYMBOLS_CAP   200000

The maximum number of symbols allowed to be in kallsyms.

Definition at line 9 of file lixksym.c.

Referenced by IntKsymRelativeFindOffsetTableEnd().

◆ KSYM_TOKEN_ARRAY_CACHE_SIZE

#define KSYM_TOKEN_ARRAY_CACHE_SIZE   256

The size of tokens array cache.

Definition at line 12 of file lixksym.c.

◆ KSYM_TOKEN_TABLE_SIZE_CAP

#define KSYM_TOKEN_TABLE_SIZE_CAP   2000

The maximum size allowed for the tokens table size.

Definition at line 10 of file lixksym.c.

Referenced by IntKsymInit().

Typedef Documentation

◆ KALLSYMS_BUFFERS

Describes the structure of the internal kallsyms buffers and other data required for the semantic reconstruction.

◆ PKALLSYMS_BUFFERS

Function Documentation

◆ IntKsymExpandSymbol()

static DWORD IntKsymExpandSymbol ( DWORD  Offset,
DWORD  MaxLength,
char *  Name 
)
static

Expands a kallsyms symbol name.

If the name buffer is not large enough then the symbol name will be truncated to fit.

Parameters
[in]OffsetThe symbol name offset in KALLSYMS_BUFFERS::NamesBuffer array.
[in]MaxLengthThe maximum symbol length. Usually LIX_SYMBOL_NAME_LEN is enough.
[out]NameThe buffer where the name would be stored.
Returns
The offset of the next symbol

Definition at line 61 of file lixksym.c.

Referenced by IntKsymFindByAddress(), and IntKsymFindByName().

◆ IntKsymFindByAddress()

INTSTATUS IntKsymFindByAddress ( QWORD  Gva,
DWORD  Length,
char *  SymName,
QWORD SymStart,
QWORD SymEnd 
)

Finds the symbol which is located at the given address.

If there are multiple symbols starting at the same address only the last one will be taken into account.

Parameters
[in]GvaThe address of the searched symbol.
[in]LengthSymName buffer size.
[out]SymNameBuffer which will store the symbol name.
[out]SymStartThe symbol start address.
[out]SymEndThe symbol end address (makes sense only for function names).
Returns
INT_STATUS_SUCCESS if the symbol was found
INT_STATUS_NOT_FOUND if the symbol was not found
INT_STATUS_UNSUCCESSFUL if any error occurred
INT_STATUS_INVALID_PARAMETER if and invalid parameter was given.
INT_STATUS_INVALID_INTERNAL_STATE if the active OS type is not Linux.
INT_STATUS_NOT_INITIALIZED if this function is called before IntKsymInit or after IntKsymUninit.

Definition at line 1283 of file lixksym.c.

Referenced by DbgFindKsym(), IntDisasmBuffer(), IntDisasmGva(), IntExceptKernelLogLinuxInformation(), IntExceptPrintMsrInfo(), IntLixAgentError(), IntLixAgentThreadError(), IntLixDrvSendViolationEvent(), IntLixDumpStacktrace(), IntLixGuestAgentContentHandler(), IntLixGuestDetourDataHandler(), IntLixKernelHandleRead(), and IntLixPatchSwapgs().

◆ IntKsymFindByName()

QWORD IntKsymFindByName ( const char *  Name,
QWORD SymEnd 
)

Searches the given Name in kallsyms and returns the Start & End offset.

If the symbol represents a variable, then the SymEnd may be wrong (we return the address of the next symbol). Supports a very basic regex: '*' at the end means we will do a memcmp only until there.

Parameters
[in]NameThe name of the symbol to be found
[out]SymEndUpon successfully return will contain the address of the following symbol (if not NULL)
Returns
The GVA of the given symbol on success or 0 if the symbol was not found

Definition at line 1399 of file lixksym.c.

Referenced by DbgFindKsym(), IntDisasmLixFunction(), IntLixAgentResolveOffset(), IntLixApiHijackHook(), IntLixApiHook(), IntLixCrashFetchDmesgSymbol(), IntLixFindDataStart(), IntLixGetInitTask(), IntLixGuestAllocateDeploy(), IntLixGuestFindPgd(), IntLixGuestGetSystemState(), IntLixGuestInit(), IntLixGuestResolveExTableLimits(), IntLixGuestResolveSymbols(), IntLixMmGetInitMm(), IntLixPatchSwapgs(), IntLixResolveCurrentCpuOffset(), IntLixResolveCurrentProcessOffset(), IntLixResolveExeFileOffset(), IntLixResolveThreadStructOffset(), IntLixVdsoDynamicProtect(), IntLixVdsoResolveDynamicOffset(), and IntLixVdsoResolveImageAddress().

◆ IntKsymFindIndexesTableStart()

static INTSTATUS IntKsymFindIndexesTableStart ( QWORD  TokenTableStart,
QWORD IndexesTableStart 
)
static

Finds the start of 'kallsyms_token_index' table.

The first 5 indexes are computed based on token table; these indexes are used to find the 'kallsyms_token_index' region.

Parameters
[in]TokenTableStartThe start guest virtual address of 'kallsyms_token_table'.
[out]IndexesTableStartThe start guest virtual address of 'kallsyms_token_index'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the start of 'kallsyms_token_index' is not found.

Definition at line 919 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymFindMarkersReducedTableEnd()

static INTSTATUS IntKsymFindMarkersReducedTableEnd ( QWORD  StartAddress,
QWORD EndAddress 
)
static

Finds the end of 'kallsyms_markers' table.

The 'marker' size is equal to 4; if a sequence of 'markers' is unordered, then the end of 'kallsyms_markers' is found.

NOTE: This function is used only on kernel version 5.x.x.

Parameters
[in]StartAddressThe start guest virtual address of 'kallsyms_markers'.
[out]EndAddressThe end guest virtual address of 'kallsyms_markers'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the end of 'kallsyms_markers' is not found.

Definition at line 758 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymFindMarkersTableEnd()

static INTSTATUS IntKsymFindMarkersTableEnd ( QWORD  StartAddress,
QWORD EndAddress 
)
static

Finds the end of 'kallsyms_markers' table.

The 'marker' size is equal to 8; if the 'marker' value if 0xffffffff, then the end of 'kallsyms_markers' is found.

Parameters
[in]StartAddressThe start guest virtual address of 'kallsyms_markers'.
[out]EndAddressThe end guest virtual address of 'kallsyms_markers'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the end of 'kallsyms_markers' is not found.

Definition at line 676 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymFindNamesTableEnd()

static INTSTATUS IntKsymFindNamesTableEnd ( QWORD  StartAddress,
QWORD EndAddress 
)
static

Finds the end of 'kallsyms_names' table.

Each 'name' entry contains the length and the content of it; for each name the current pointer is incremented with the length of the 'name' entry.

Parameters
[in]StartAddressThe start guest virtual address of 'kallsyms_names'.
[out]EndAddressThe end guest virtual address of 'kallsyms_names'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the end of 'kallsyms_names' is not found.

Definition at line 854 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymGetAddress()

static QWORD IntKsymGetAddress ( INT32  Index)
static

Returns the address of the symbol located at the given index in the symbols table.

Parameters
[in]IndexThe symbol index.
Return values
Theguest virtual address of the symbol.

Definition at line 164 of file lixksym.c.

Referenced by IntKsymFindByAddress(), and IntKsymFindByName().

◆ IntKsymInit()

INTSTATUS IntKsymInit ( void  )

Initialize the kallsyms subsystem based on the os info provided by LIX_FIELD(Info, HasKsym*).

Before calling this function the following subsystem must be fully initialized.

  • gGuest
  • Linux kernel layout
  • Mm subsystem
  • CAMI subsystem
Returns
INT_STATUS_SUCCESS if the initialization completed without any errors.
INT_STATUS_INSUFFICIENT_RESOURCES if there is not enough available memory.
INT_STATUS_NOT_FOUND if any guest structures were not found.
INT_STATUS_INVALID_DATA_STATE if any structure was found in an unexpected state.
INT_STATUS_INVALID_INTERNAL_STATE if the active OS type is not Linux.

Definition at line 1046 of file lixksym.c.

Referenced by IntLixGuestInit().

◆ IntKsymInitAbsolute()

static INTSTATUS IntKsymInitAbsolute ( void  )
static

Initializes the kallsyms subsystem for kernels compiled without CONFIG_KALLSYMS_BASE_RELATIVE.

Return values
INT_STATUS_SUCCESSIf the initialization completed without any errors.
INT_STATUS_NOT_FOUNDIf any structures were not found.

Definition at line 534 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymInitRelative()

static INTSTATUS IntKsymInitRelative ( void  )
static

Initializes the kallsyms subsystem for kernels compiled with CONFIG_KALLSYMS_BASE_RELATIVE.

Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf any structures were not found.

Definition at line 502 of file lixksym.c.

Referenced by IntKsymInit().

◆ IntKsymRelativeFindOffsetTableEnd()

static INTSTATUS IntKsymRelativeFindOffsetTableEnd ( QWORD  StartAddress)
static

Finds the end of 'kallsyms_offsets' memory region.

In order to find the end of 'kallsyms_offsets', the function tries to find the 'kallsyms_relative_base' or an offset that is equal to 0. The 'kallsyms_num_syms', 'kallsyms_relative_base' and 'kallsyms_relative_base' symbols are fetched.

Parameters
[in]StartAddressThe guest virtual address of 'kallsyms_offsets'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the end of 'kallsyms_offsets' is not found.

Definition at line 330 of file lixksym.c.

Referenced by IntKsymInitRelative().

◆ IntKsymRelativeFindOffsetTableStart()

static INTSTATUS IntKsymRelativeFindOffsetTableStart ( QWORD Address)
static

Finds the start of 'kallsyms_offsets' memory region.

The function searches for 16 ordered int's; then the whole page is checked if contains ordered int's.

Parameters
[in]AddressThe address of 'kallsyms_offsets'.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf the start of 'kallsyms_offsets' is not found.

Definition at line 195 of file lixksym.c.

Referenced by IntKsymInitRelative().

◆ IntKsymUninit()

void IntKsymUninit ( void  )

Tries to free the kallsyms internal buffers if they are initialized.

Definition at line 1256 of file lixksym.c.

Referenced by IntLixGuestNew(), and IntLixGuestUninit().

Variable Documentation

◆ gKallsymsBuffers

KALLSYMS_BUFFERS gKallsymsBuffers
static

Contains information about kallsyms required for the semantic reconstruction.

Definition at line 57 of file lixksym.c.