Bitdefender Hypervisor Memory Introspection
thread_safeness.c File Reference
#include "thread_safeness.h"
#include "guests.h"
#include "introcpu.h"
#include "lixprocess.h"
#include "memtables.h"
#include "ptfilter.h"
#include "utils.h"
#include "vecore.h"
#include "winprocesshp.h"
#include "winthread.h"
#include "swapgs.h"

Go to the source code of this file.

Macros

#define KSTACK_PAGE_COUNT_X86   8
 Stack page count to check on 32-bit systems. More...
 
#define KSTACK_PAGE_COUNT_X64   16
 Stack page count to check on 64-bit systems. More...
 

Functions

static DWORD IntThrGetStackSize (QWORD Rsp)
 
static BOOLEAN IntThrSafeIsStackPtrInIntro (QWORD StackFrameStart, QWORD StackFrameEnd, QWORD Options, QWORD ProcessGva)
 Checks if a pointer from the stack points to a section of code injected or modified by Introcore inside the guest. More...
 
static BOOLEAN IntThrSafeIsLiveRIPInIntro (const IG_ARCH_REGS *Registers, QWORD Options)
 Checks if the RIP on one of the guests VCPU points inside an Introcore owned code section. More...
 
static INTSTATUS IntThrSafeMoveReturn (QWORD StackFrameStart, QWORD StackFrameEnd)
 Will check if it is safe for Introcore to move the return value on the stack. More...
 
static INTSTATUS IntThrSafeMoveRip (IG_ARCH_REGS *Registers, DWORD CpuNumber)
 Will check if it is safe for Introcore to modify the RIP value. More...
 
static INTSTATUS IntThrSafeWinInspectWaitingThread (QWORD Ethread, QWORD Options)
 Inspects a waiting thread from a Windows guest. More...
 
static INTSTATUS IntThrSafeLixInspectWaitingThread (QWORD TaskStruct, QWORD Options)
 Inspects a waiting thread from a Linux guest. More...
 
static INTSTATUS IntThrSafeLixGetCurrentStack (DWORD CpuNumber, QWORD *Stack)
 Get the current stack value for a VCPU for a Linux guest. More...
 
static INTSTATUS IntThrSafeWinGetCurrentStack (DWORD CpuNumber, QWORD *CurrentStack, QWORD *StackBase, QWORD *StackLimit)
 Get the current stack values for a VCPU for a Windows guest. More...
 
static INTSTATUS IntThrSafeLixInspectRunningThreadOnCpu (DWORD Cpu, const IG_ARCH_REGS *Regs, QWORD Options)
 Inspects the running threads of a VCPU. More...
 
static INTSTATUS IntThrSafeWinInspectRunningThreadOnCpu (DWORD Cpu, const IG_ARCH_REGS *Regs, QWORD Options)
 Inspects the running threads of a VCPU. More...
 
static INTSTATUS IntThrSafeInspectRunningThreads (QWORD Options)
 Inspects the currently running threads. More...
 
static INTSTATUS IntThrSafeWinInspectWaitingFromGuestList (QWORD Eprocess, QWORD Options)
 
INTSTATUS IntThrSafeCheckThreads (QWORD Options)
 Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of code owned by Introcore. More...
 

Variables

static BOOLEAN gSafeToUnload = FALSE
 

Macro Definition Documentation

◆ KSTACK_PAGE_COUNT_X64

#define KSTACK_PAGE_COUNT_X64   16

Stack page count to check on 64-bit systems.

Definition at line 19 of file thread_safeness.c.

Referenced by IntThrGetStackSize().

◆ KSTACK_PAGE_COUNT_X86

#define KSTACK_PAGE_COUNT_X86   8

Stack page count to check on 32-bit systems.

Definition at line 18 of file thread_safeness.c.

Referenced by IntThrGetStackSize().

Function Documentation

◆ IntThrGetStackSize()

◆ IntThrSafeCheckThreads()

INTSTATUS IntThrSafeCheckThreads ( QWORD  Options)

Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of code owned by Introcore.

This is done by iterating the in-guest thread lists. This function assumes that all the VCPUs are paused.

Parameters
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values
Return values
INT_STATUS_SUCCESSin case of success; this means that no guest state points to code or data owned by Introcore
INT_STATUS_NOT_SUPPORTEDif the type of the guest OS is not known or supported
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state

Definition at line 986 of file thread_safeness.c.

Referenced by IntGuestIsSafeToDisable(), IntHookPtsCheckIntegrity(), IntLixApiHookAll(), IntPtiDeliverDriverForUnload(), IntVeDeliverDriverForUnload(), and IntWinGuestFinishInit().

◆ IntThrSafeInspectRunningThreads()

static INTSTATUS IntThrSafeInspectRunningThreads ( QWORD  Options)
static

Inspects the currently running threads.

Parameters
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values.
Return values
INT_STATUS_SUCCESSin case of success; this means that none of the active threads are using introcore code or data.
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state.

Definition at line 890 of file thread_safeness.c.

Referenced by IntThrSafeCheckThreads().

◆ IntThrSafeIsLiveRIPInIntro()

static BOOLEAN IntThrSafeIsLiveRIPInIntro ( const IG_ARCH_REGS Registers,
QWORD  Options 
)
static

Checks if the RIP on one of the guests VCPU points inside an Introcore owned code section.

Parameters
[in]RegistersRegister state to be checked
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values
Returns
True if the RIP is inside an Introcore code region, false if it is not

Definition at line 190 of file thread_safeness.c.

Referenced by IntThrSafeInspectRunningThreads().

◆ IntThrSafeIsStackPtrInIntro()

static BOOLEAN IntThrSafeIsStackPtrInIntro ( QWORD  StackFrameStart,
QWORD  StackFrameEnd,
QWORD  Options,
QWORD  ProcessGva 
)
static

Checks if a pointer from the stack points to a section of code injected or modified by Introcore inside the guest.

Parameters
[in]StackFrameStartThe start of the stack frame to be checked.
[in]StackFrameEndThe end of the stack frame to be checked.
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values.
[in]ProcessGvaThe guest virtual address at which the task is found. Ignored for Windows guests.
Returns
True if a pointer on the stack is inside an Introcore code or data region, False if it is not

Definition at line 41 of file thread_safeness.c.

Referenced by IntThrSafeLixInspectRunningThreadOnCpu(), IntThrSafeLixInspectWaitingThread(), IntThrSafeWinInspectRunningThreadOnCpu(), and IntThrSafeWinInspectWaitingThread().

◆ IntThrSafeLixGetCurrentStack()

static INTSTATUS IntThrSafeLixGetCurrentStack ( DWORD  CpuNumber,
QWORD Stack 
)
static

Get the current stack value for a VCPU for a Linux guest.

This is done by reading the stack information saved in the kernel's task structure

Parameters
[in]CpuNumberThe VCPU for which the query is done
[out]StackThe stack, as saved by the kernel
Returns
INT_STATUS_SUCCESS in case of success, or other INTSTATUS values in case of error

Definition at line 594 of file thread_safeness.c.

Referenced by IntThrSafeLixInspectRunningThreadOnCpu().

◆ IntThrSafeLixInspectRunningThreadOnCpu()

static INTSTATUS IntThrSafeLixInspectRunningThreadOnCpu ( DWORD  Cpu,
const IG_ARCH_REGS Regs,
QWORD  Options 
)
static

Inspects the running threads of a VCPU.

Parameters
[in]CpuThe VCPU for which the checks are done
[in]RegsRegister state
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values
Return values
INT_STATUS_SUCCESSin case of success; this means that none of the active threads are using Introcore code or data
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state

Definition at line 698 of file thread_safeness.c.

Referenced by IntThrSafeInspectRunningThreads().

◆ IntThrSafeLixInspectWaitingThread()

static INTSTATUS IntThrSafeLixInspectWaitingThread ( QWORD  TaskStruct,
QWORD  Options 
)
static

Inspects a waiting thread from a Linux guest.

Parameters
[in]TaskStructThe guest virtual address at which the task to be inspected is found.
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values.
Return values
INT_STATUS_SUCCESSin case of success; this means that none of the. active threads are using Introcore code or data.
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state.

Definition at line 511 of file thread_safeness.c.

Referenced by IntThrSafeCheckThreads().

◆ IntThrSafeMoveReturn()

static INTSTATUS IntThrSafeMoveReturn ( QWORD  StackFrameStart,
QWORD  StackFrameEnd 
)
static

Will check if it is safe for Introcore to move the return value on the stack.

Parameters
[in]StackFrameStartThe start of the stack frame to be checked
[in]StackFrameEndThe end of the stack frame to be checked
Returns
True if operation can be done safely, False if it can not be done safely

Definition at line 250 of file thread_safeness.c.

Referenced by IntThrSafeLixInspectRunningThreadOnCpu(), IntThrSafeLixInspectWaitingThread(), IntThrSafeWinInspectRunningThreadOnCpu(), and IntThrSafeWinInspectWaitingThread().

◆ IntThrSafeMoveRip()

static INTSTATUS IntThrSafeMoveRip ( IG_ARCH_REGS Registers,
DWORD  CpuNumber 
)
static

Will check if it is safe for Introcore to modify the RIP value.

Parameters
[in]RegistersRegister state to be checked
[in]CpuNumberThe VCPU for which the check is done. Can be IG_CURRENT_VCPU
Returns
True if operation can be done safely, False if it can not be done safely

Definition at line 359 of file thread_safeness.c.

Referenced by IntThrSafeInspectRunningThreads().

◆ IntThrSafeWinGetCurrentStack()

static INTSTATUS IntThrSafeWinGetCurrentStack ( DWORD  CpuNumber,
QWORD CurrentStack,
QWORD StackBase,
QWORD StackLimit 
)
static

Get the current stack values for a VCPU for a Windows guest.

This is done by reading the stack information saved in the kernel's _KTHREAD structure

Parameters
[in]CpuNumberThe VCPU for which the query is done
[out]CurrentStackThe current stack pointer, as saved by the kernel
[out]StackBaseThe base of the stack, as saved by the kernel
[out]StackLimitThe limit of the stack, as saved by the kernel
Returns
INT_STATUS_SUCCESS in case of success, or other INTSTATUS values in case of error

Definition at line 631 of file thread_safeness.c.

Referenced by IntThrSafeWinInspectRunningThreadOnCpu().

◆ IntThrSafeWinInspectRunningThreadOnCpu()

static INTSTATUS IntThrSafeWinInspectRunningThreadOnCpu ( DWORD  Cpu,
const IG_ARCH_REGS Regs,
QWORD  Options 
)
static

Inspects the running threads of a VCPU.

Parameters
[in]CpuThe VCPU for which the checks are done
[in]RegsRegister state
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values
Return values
INT_STATUS_SUCCESSin case of success; this means that none of the active threads are using Introcore code or data
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state

Definition at line 782 of file thread_safeness.c.

Referenced by IntThrSafeInspectRunningThreads().

◆ IntThrSafeWinInspectWaitingFromGuestList()

static INTSTATUS IntThrSafeWinInspectWaitingFromGuestList ( QWORD  Eprocess,
QWORD  Options 
)
static

Definition at line 976 of file thread_safeness.c.

Referenced by IntThrSafeCheckThreads().

◆ IntThrSafeWinInspectWaitingThread()

static INTSTATUS IntThrSafeWinInspectWaitingThread ( QWORD  Ethread,
QWORD  Options 
)
static

Inspects a waiting thread from a Windows guest.

The check is skipped for threads that are in the KTHREAD_STATE.Running and KTHREAD_STATE.Terminated states, as those are either checked when checking the live state of a CPU (for running threads), or don't need to be checked (as they are terminated). The check is also skipped if the wait reason of a thread is not KWAIT_REASON.WrDispatchInt or KWAIT_REASON.WrQuantumEnd.

Parameters
[in]EthreadThe guest virtual address at which the thread to be inspected is found
[in]OptionsOptions that control the checks that will be made. Can be a combination of Thread safeness options values
Return values
INT_STATUS_SUCCESSin case of success; this means that none of the active threads are using Introcore code or data
INT_STATUS_CANNOT_UNLOADif it is not safe to unload given the current guest state

Definition at line 405 of file thread_safeness.c.

Referenced by IntThrSafeWinInspectWaitingFromGuestList().

Variable Documentation

◆ gSafeToUnload