Bitdefender Hypervisor Memory Introspection
winummoduleblock.c File Reference

This file contains the logic that blocks Windows module loads in case of a double agent attack. More...

#include "winummoduleblock.h"
#include "hook.h"
#include "swapmem.h"
#include "introcpu.h"
#include "winummodule.h"

Go to the source code of this file.

Data Structures

struct  _WIN_MOD_BLOCK_OBJECT
 Windows module block object. More...
 
struct  _REASON_CALLBACK_LIST_OBJECT
 A reason callback structure (this can contain multiple callbacks to be invoked for a certain dllMain reason). More...
 
struct  _REASON_CALLBACK_OBJECT
 A reason callback context (invoked for a given dllMain reason). More...
 

Typedefs

typedef struct _WIN_MOD_BLOCK_OBJECT WIN_MOD_BLOCK_OBJECT
 Windows module block object. More...
 
typedef struct _WIN_MOD_BLOCK_OBJECTPWIN_MOD_BLOCK_OBJECT
 
typedef struct _REASON_CALLBACK_LIST_OBJECT REASON_CALLBACK_LIST_OBJECT
 A reason callback structure (this can contain multiple callbacks to be invoked for a certain dllMain reason). More...
 
typedef struct _REASON_CALLBACK_LIST_OBJECTPREASON_CALLBACK_LIST_OBJECT
 
typedef struct _REASON_CALLBACK_OBJECT REASON_CALLBACK_OBJECT
 A reason callback context (invoked for a given dllMain reason). More...
 
typedef struct _REASON_CALLBACK_OBJECTPREASON_CALLBACK_OBJECT
 

Functions

static INTSTATUS IntWinModBlockHandleExecution (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
 This function is invoked when a hooked section belonging to the analyzed module starts executing. More...
 
static INTSTATUS IntModBlockHandlePreInjection (void *Context, QWORD Cr3, QWORD VirtualAddress)
 This function is invoked before injecting the #PF used to read the module headers. More...
 
static INTSTATUS IntModBlockHandleBlockModHeadersInMemory (WIN_MOD_BLOCK_OBJECT *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, BYTE *Data, DWORD DataSize, DWORD Flags)
 This function is invoked when the module headers have been successfully read. More...
 
INTSTATUS IntWinModBlockBlockModuleLoad (WIN_PROCESS_MODULE *Module, WIN_MOD_BLOCK_FLAG Flags, PFUNC_IntWinModBlockCallback Callback, PFUNC_IntWinModBlockHeadersCallback HeadersCallback, PFUNC_IntWinModBlockCleanup CleanupCallback, void **BlockObject)
 This function is invoked when a suspicious dll is loaded in order to analyze and block the dll load if required. More...
 
INTSTATUS IntWinModBlockRegisterCallbackForReason (void *BlockObject, DWORD Reason, PFUNC_IntWinModBlockCallback Callback)
 Registers a callback that is invoked when the blocked module's DllMain function is called with a given reason parameter. More...
 
INTSTATUS IntWinModBlockRemoveBlockObject (void *BlockObject)
 This function is used in order to destroy a WIN_MOD_BLOCK_OBJECT structure. More...
 

Detailed Description

This file contains the logic that blocks Windows module loads in case of a double agent attack.

The introspection provides a mechanism to block double agent attacks (controlled by PROC_OPT_PROT_DOUBLE_AGENT). This file implements the logic used to block a module load if deemed malicious by the internal heuristic.

Definition in file winummoduleblock.c.

Typedef Documentation

◆ PREASON_CALLBACK_LIST_OBJECT

◆ PREASON_CALLBACK_OBJECT

◆ PWIN_MOD_BLOCK_OBJECT

◆ REASON_CALLBACK_LIST_OBJECT

A reason callback structure (this can contain multiple callbacks to be invoked for a certain dllMain reason).

◆ REASON_CALLBACK_OBJECT

A reason callback context (invoked for a given dllMain reason).

◆ WIN_MOD_BLOCK_OBJECT

Windows module block object.

Function Documentation

◆ IntModBlockHandleBlockModHeadersInMemory()

static INTSTATUS IntModBlockHandleBlockModHeadersInMemory ( WIN_MOD_BLOCK_OBJECT Context,
QWORD  Cr3,
QWORD  VirtualAddress,
QWORD  PhysicalAddress,
BYTE Data,
DWORD  DataSize,
DWORD  Flags 
)
static

This function is invoked when the module headers have been successfully read.

After the module headers have been successfully read, this function will iterate trough all the sections and and place an execute hook (invoking IntWinModBlockHandleExecution for all the sections that are executable and non-discardable). Also, this function will invoke the WIN_MOD_BLOCK_OBJECT::HeadersCallback callback, provided as context.

Parameters
[in]ContextThe WIN_MOD_BLOCK_OBJECT structure of the module in question.
[in]Cr3The virtual address space.
[in]VirtualAddressThe base virtual address read.
[in]PhysicalAddressThe physical address of the first page (VirtualAddress) read.
[in]DataBuffer containing the read data. This will be freed once the callback returns!
[in]DataSizeSize of the Data buffer.
[in]FlagsSwap flags. Check out SWAPMEM_FLG* for more info.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 325 of file winummoduleblock.c.

Referenced by IntWinModBlockBlockModuleLoad().

◆ IntModBlockHandlePreInjection()

static INTSTATUS IntModBlockHandlePreInjection ( void *  Context,
QWORD  Cr3,
QWORD  VirtualAddress 
)
static

This function is invoked before injecting the #PF used to read the module headers.

We have to make sure that the VAD corresponding to this module is already inserted in the RB tree inside the guest. If we inject a #PF but the VAD is not queued yet, we will end up crashing the process, because it would receive a #PF for an address which is still invalid (because the VAD is not inserted in the tree yet).

Parameters
[in]ContextThe WIN_MOD_BLOCK_OBJECT structure of the module in question.
[in]Cr3The virtual address space.
[in]VirtualAddressThe guest GVA
Return values
INT_STATUS_SUCCESSThe VAD is inside the tree so we can safely inject the #PF.
INT_STATUS_NOT_NEEDED_HINTThe VAD is NOT inside the tree, bail out (do not inject the #PF).

Definition at line 276 of file winummoduleblock.c.

Referenced by IntWinModBlockBlockModuleLoad().

◆ IntWinModBlockBlockModuleLoad()

INTSTATUS IntWinModBlockBlockModuleLoad ( WIN_PROCESS_MODULE Module,
WIN_MOD_BLOCK_FLAG  Flags,
PFUNC_IntWinModBlockCallback  Callback,
PFUNC_IntWinModBlockHeadersCallback  HeadersCallback,
PFUNC_IntWinModBlockCleanup  CleanupCallback,
void **  BlockObject 
)

This function is invoked when a suspicious dll is loaded in order to analyze and block the dll load if required.

This function reads the module headers, hooks the executable sections and invokes the provided Callback in order to obtain a required action. Depending on the provided Flags, this function could block the module load or kill the process if an error occurred while blocking the load.

Parameters
[in]ModuleThe WIN_PROCESS_MODULE structure of the module in question.
[in]FlagsThe flags that will indicate what kind of action should be taken if the module is deemed unsafe.
[in]CallbackThe callback that will provided the detection logic.
[in]HeadersCallbackThis callback is invoked when the module headers have been successfully read.
[in]CleanupCallbackThis callback is invoked before destroying the WIN_MOD_BLOCK_OBJECT associated with this module.
[in,out]BlockObjectThe WIN_MOD_BLOCK_OBJECT associated with the given module.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INVALID_INTERNAL_STATEWIN_PROCESS_MODULE::StaticScan must NOT be TRUE.
INT_STATUS_INSUFFICIENT_RESOURCESA memory allocation failed.

Definition at line 454 of file winummoduleblock.c.

Referenced by IntWinDagentCheckSuspiciousDllLoad().

◆ IntWinModBlockHandleExecution()

static INTSTATUS IntWinModBlockHandleExecution ( void *  Context,
void *  Hook,
QWORD  Address,
INTRO_ACTION Action 
)
static

This function is invoked when a hooked section belonging to the analyzed module starts executing.

After obtaining information such as dllHandle, reason, etc. this functions invokes WIN_MOD_BLOCK_OBJECT::Callback which uses some heuristics in order to determine if this is a double agent case or not. If the execution is deemed unsafe, the WIN_MOD_BLOCK_OBJECT::ReasonCallbacksList will be iterated invoking the callbacks. If the final required action is not introGuestAllowed, depending on the provided flags (winModBlockFlagUnloadAfterExec, winModBlockFlagDoNotUnload and winModBlockFlagKillOnError), the module load could be blocked or the entire process could be terminated in case of an error.

Parameters
[in]ContextThe WIN_MOD_BLOCK_OBJECT structure of the module in question.
[in]HookThe GPA hook handle.
[in]AddressThe accessed address.
[in,out]ActionDesired action.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 77 of file winummoduleblock.c.

Referenced by IntModBlockHandleBlockModHeadersInMemory().

◆ IntWinModBlockRegisterCallbackForReason()

INTSTATUS IntWinModBlockRegisterCallbackForReason ( void *  BlockObject,
DWORD  Reason,
PFUNC_IntWinModBlockCallback  Callback 
)

Registers a callback that is invoked when the blocked module's DllMain function is called with a given reason parameter.

There can be any number of callbacks for any reason. Take into account that the reason equal to 0xFFFFFFFF (WINMODBLOCK_INVALID_VALUE) is reserved and an error will be returned if one tries to call this function for that specific reason.

Parameters
[in]BlockObjectThe WIN_MOD_BLOCK_OBJECT associated with the given module.
[in]ReasonThe DllMain provided reason.
[in]CallbackA callback which is invoked at every execution inside the suspicious DLL of DllMain when the reason parameter in DllMain equals to the given Reason parameter. See PFUNC_IntWinModBlockCallback in callbacks section for more details. If the returned Action by the registered callback is introGuestAllowed, the block object will be removed. Please note that even if the maximum priority of action is taken (e.g. introGuestRetry has more priority), if the main callback (registered through IntWinModBlockBlockModuleLoad) returns introGuestAllowed, then no other callback registered through IntWinModBlockRegisterCallbackForReason gets called and the block object is removed!
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INSUFFICIENT_RESOURCESA memory allocation failed.

Definition at line 558 of file winummoduleblock.c.

Referenced by IntWinDagentCheckSuspiciousDllLoad().

◆ IntWinModBlockRemoveBlockObject()

INTSTATUS IntWinModBlockRemoveBlockObject ( void *  BlockObject)

This function is used in order to destroy a WIN_MOD_BLOCK_OBJECT structure.

This functions invokes the cleanup callback provided when to IntWinModBlockBlockModuleLoad after which all the structures used by the the WIN_MOD_BLOCK_OBJECT are safely destroyed.

Parameters
[in]BlockObjectThe WIN_MOD_BLOCK_OBJECT structure to be destroyed.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 664 of file winummoduleblock.c.

Referenced by IntWinDagentCheckSuspiciousDllLoad(), IntWinModBlockHandleExecution(), and IntWinModUnHookModule().