Bitdefender Hypervisor Memory Introspection
|
#include "winummodule.h"
#include "alerts.h"
#include "hook.h"
#include "swapmem.h"
#include "unpacker.h"
#include "winprocesshp.h"
#include "winummoduleblock.h"
#include "winumdoubleagent.h"
#include "winthread.h"
Go to the source code of this file.
Macros | |
#define | MAX_IAT_ENTRIES 4096 |
Functions | |
static INTSTATUS | IntWinModHookPoly (PWIN_PROCESS_MODULE Module) |
Hooks the given module against unpacks. More... | |
static BOOLEAN | IntWinModIsProtected (const WIN_PROCESS_MODULE *Module, const PROTECTED_DLL_INFO *ProtectedList, size_t ProtectedCount) |
Check if the given module is in the provided list of protected modules. More... | |
static INTSTATUS | IntWinProcSendDllEvent (PWIN_PROCESS_MODULE Module, BOOLEAN Loaded) |
Send a DLL load/unload event to the integrator. More... | |
static INTSTATUS | IntWinProcSendAllDllEventsForSubsystem (PWIN_PROCESS_SUBSYSTEM Subsystem) |
Send a module load event for each loaded module inside a subsystem. More... | |
INTSTATUS | IntWinProcSendAllDllEventsForProcess (PWIN_PROCESS_OBJECT Process) |
Send DLL load events for all modules loaded in all subsystems of a process. More... | |
static void | IntWinModCheckSpecialCases (PWIN_PROCESS_MODULE Module) |
Check if the process is DominoJava process. More... | |
static INTSTATUS | IntWinModHandleMainModuleInMemory (void *Context, QWORD Cr3, QWORD ModuleBase, QWORD PhysicalAddress, PBYTE Data, DWORD DataSize, DWORD Flags) |
Callback called when the main module headers are present in physical memory. More... | |
static int | IntWinModComparePaths (const WIN_PROCESS_MODULE *Module, const WCHAR *SystemDirPath, const WCHAR *TestModule) |
Tests whether the Module's path is the same as the TestModules' path inside the provided SystemDirPath. More... | |
static QWORD | IntWinModGetProtectionOptionForModule (WIN_PROCESS_MODULE *Module) |
Get the protection options for provided module. More... | |
static INTSTATUS | IntWinModIsKernelWriteInjection (EXCEPTION_KM_ORIGINATOR *Originator, BOOLEAN *IsInjection) |
Verifies if the current KM-UM write is due to an injection. More... | |
static INTSTATUS | IntWinModFillDriverInjectionData (QWORD ReturnRip, EXCEPTION_KM_ORIGINATOR *Originator) |
Fills the return driver data in the Originator when the write is caused by an injection which was made by a driver. This function will retrieve data about the driver which called ZwWriteVirtualMemory or other APIs which result in KM-UM writes from MmCopyVirtualMemory. The data is filled into the Originator exactly as in the case where the given driver is the return driver on the stack. More... | |
static INTSTATUS | IntWinModFillProcessInjectionData (QWORD CurrentThread, EXCEPTION_KM_ORIGINATOR *Originator) |
Fills the originating process data in the Originator when the write is caused by an injection which was made by a process in the current process. More... | |
static INTSTATUS | IntWinModFillInjectionData (EXCEPTION_KM_ORIGINATOR *Originator) |
Fills the originating caller which led to the detected injection and respectively the current KM-UM writes. More... | |
static INTSTATUS | IntWinModHandleKernelWrite (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Handle writes inside a protected user-mode module from kernel-mode. More... | |
static INTSTATUS | IntWinModHandleUserWrite (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Handle user-mode writes inside a protected user-mode module. More... | |
INTSTATUS | IntWinModHandleWrite (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Handle writes inside a protected user-mode module wrapper. Will dispatch appropriately to either the kernel or user write handler. More... | |
static INTSTATUS | IntWinModHookModule (PWIN_PROCESS_MODULE Module) |
Hook a user-mode module against attacks. More... | |
INTSTATUS | IntWinModUnHookModule (PWIN_PROCESS_MODULE Module) |
Remove the protection from the indicated module. More... | |
INTSTATUS | IntWinModHandlePreInjection (void *Context, QWORD Cr3, QWORD VirtualAddress) |
Module base page-fault pre-injection callback. More... | |
static INTSTATUS | IntWinModHandleModuleHeadersInMemory (void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, PBYTE Data, DWORD DataSize, DWORD Flags) |
Called as soon as the module headers are swapped in memory. More... | |
static INTSTATUS | IntWinModHandleModulePathInMemory (WIN_PROCESS_MODULE *Module, WINUM_PATH *Path) |
Handles a module path in memory. More... | |
INTSTATUS | IntWinModHandleLoadFromVad (WIN_PROCESS_OBJECT *Process, const VAD *Vad) |
Handle a module load from a VAD. More... | |
static INTSTATUS | IntWinModHandleUnload (PWIN_PROCESS_SUBSYSTEM Subsystem, QWORD VirtualBase) |
Handle a module unload from the given subsystem. More... | |
INTSTATUS | IntWinModHandleUnloadFromVad (PWIN_PROCESS_OBJECT Process, PVAD Vad) |
Handle a module unload. More... | |
static BOOLEAN | IntWinModWriteValidHandler (QWORD Cr3, QWORD Address, void *Context) |
Checks if a write inside a code section is legitimate or not. More... | |
INTSTATUS | IntWinModPolyHandler (QWORD Cr3, QWORD VirtualAddress, PINSTRUX Instrux, void *Context) |
Handle an unpack event for the indicated address. More... | |
INTSTATUS | IntWinModRemoveModule (PWIN_PROCESS_MODULE Module) |
Removes a Windows module. More... | |
void | IntWinModulesChangeProtectionFlags (PWIN_PROCESS_SUBSYSTEM Subsystem) |
Change the protection flags applied to the process modules that are currently loaded. More... | |
PWIN_PROCESS_MODULE | IntWinUmModFindByAddress (PWIN_PROCESS_OBJECT Process, QWORD Gva) |
Searches for a user-mode module which contains the indicated guest virtual address. More... | |
Variables | |
const PROTECTED_DLL_INFO | gProtectedModules [] |
const PROTECTED_DLL_INFO | gProtectedNetModules [] |
const PROTECTED_DLL_INFO | gProtectedWowModules [] |
#define MAX_IAT_ENTRIES 4096 |
Referenced by IntWinModHookModule().
|
static |
Check if the process is DominoJava process.
This is a workaround for a DominoJava process which uses the j9jit and Java DLLs. If the loaded module is a known DominoJava module, this function will set a flag in the Process (IsDominoJava).
[in] | Module | The module to be checked. |
Definition at line 224 of file winummodule.c.
Referenced by IntWinModHandleModulePathInMemory().
|
static |
Tests whether the Module's path is the same as the TestModules' path inside the provided SystemDirPath.
[in] | Module | The module whose path is to be compared. |
[in] | SystemDirPath | The system directory path. |
[in] | TestModule | The path to be compared with the Module. |
Definition at line 342 of file winummodule.c.
|
static |
Fills the return driver data in the Originator when the write is caused by an injection which was made by a driver. This function will retrieve data about the driver which called ZwWriteVirtualMemory or other APIs which result in KM-UM writes from MmCopyVirtualMemory. The data is filled into the Originator exactly as in the case where the given driver is the return driver on the stack.
[in] | ReturnRip | The RIP where the ZwWriteVirtualMemory call returns. |
[in,out] | Originator | The Originator structure which will be filled with appropiate data based on the driver which caused the injection. |
Definition at line 474 of file winummodule.c.
Referenced by IntWinModFillInjectionData().
|
static |
Fills the originating caller which led to the detected injection and respectively the current KM-UM writes.
On x64, this function will decide based on KTHREAD.PreviousMode whether the caller is a kernel driver, in which case the return RIP is retrieved from a "fake TrapFrame", found inside the RBP register, or a process, in which case we can get the current thread's owner process which is the process which performed the injection in the first place. On x86, the algorithm is basically the same, but for drivers the return can be fetched from the real TrapFrame from KTHREAD, constructed at the moment of the call.
[in,out] | Originator | The Originator structure which will be filled with appropiate data based on the driver or process which caused the injection. |
Definition at line 579 of file winummodule.c.
Referenced by IntWinModHandleKernelWrite().
|
static |
Fills the originating process data in the Originator when the write is caused by an injection which was made by a process in the current process.
When the process A injects into process B, the kernel will attach A's thread to the process B in order to perform the requested writes. The thread owner remains A, so we'll consider the thread owner, that is the original ETHREAD.Process field, to be the originating process.
[in] | CurrentThread | The thread in which context the current write occurs. |
[in,out] | Originator | The Originator structure which will be filled with appropiate data based on the process which caused the injection. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_FOUND | If there is no process owning the current thread. |
Definition at line 531 of file winummodule.c.
Referenced by IntWinModFillInjectionData().
|
static |
Get the protection options for provided module.
[in] | Module | The module object. |
The | protection options for provided module. |
Definition at line 391 of file winummodule.c.
Referenced by IntWinModHandleKernelWrite(), and IntWinModHandleUserWrite().
|
static |
Handle writes inside a protected user-mode module from kernel-mode.
[in] | Context | The module (PWIN_PROCESS_MODULE structure). |
[in] | Hook | The GPA hook handle. |
[in] | Address | The written guest physical address. |
[out] | Action | The desired action. |
INT_STATUS_SUCCESS | On success. |
Definition at line 730 of file winummodule.c.
Referenced by IntWinModHandleWrite().
INTSTATUS IntWinModHandleLoadFromVad | ( | WIN_PROCESS_OBJECT * | Process, |
const VAD * | Vad | ||
) |
Handle a module load from a VAD.
This function gets called each time an VadImageMap VAD is being loaded. It will create a module entry and it will activate protection on it, if needed.
[in] | Process | The process. |
[in] | Vad | The VAD being loaded. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 1587 of file winummodule.c.
Referenced by IntWinVadFetchImageName(), and IntWinVadHandleFilePathInMemory().
|
static |
Callback called when the main module headers are present in physical memory.
This function will enable the unpacker on the main module, if the option is enabled.
[in] | Context | The module structure. |
[in] | Cr3 | The virtual address space. |
[in] | ModuleBase | The guest virtual address of the swapped page (headers). |
[in] | PhysicalAddress | The physical address of the first swapped in page. |
[in] | Data | Buffer containing the data. |
[in] | DataSize | The size of the Data buffer. |
[in] | Flags | Swa in flags - check out SWAPMEM_FLG* for more info. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_INVALID_INTERNAL_STATE | If an invalid internal state is detected. |
Definition at line 250 of file winummodule.c.
Referenced by IntWinModHandleModulePathInMemory().
|
static |
Called as soon as the module headers are swapped in memory.
This function will be called whenever the loaded-module entry is present in the physical memory: either on insertion inside the modules list, either after a page-fault is injected inside the guest. This function will hook the module, if necessary.
[in] | Context | The module structure. |
[in] | Cr3 | The virtual address space. |
[in] | VirtualAddress | The guest virtual address of the swapped page (headers). |
[in] | PhysicalAddress | The physical address of the first swapped in page. |
[in] | Data | Buffer containing the data. |
[in] | DataSize | The size of the Data buffer. |
[in] | Flags | Swa in flags - check out SWAPMEM_FLG* for more info. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_INVALID_INTERNAL_STATE | If an invalid internal state is detected. |
Definition at line 1312 of file winummodule.c.
Referenced by IntWinModHandleModulePathInMemory().
|
static |
Handles a module path in memory.
This function gets called once the path of the indicated module is present in memory. Once we have the path, we can:
[in] | Module | The module. |
[in] | Path | The module path. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_INTERNAL_STATE | If an invalid internal state is encountered. |
Definition at line 1395 of file winummodule.c.
Referenced by IntWinModHandleLoadFromVad().
Module base page-fault pre-injection callback.
This callback is used as a pre-injection callback for the user-mode modules headers swap-in. This function will check if the virtual address we inject a PF for is indeed valid (it has a valid VAD assigned) inside the process space. If it does, the PF injection can be done. If it doesn't, we cannot inject a PF for that address, as it would result in a process crash.
[in] | Context | The PWIN_PROCESS_MODULE structure describing the module. |
[in] | Cr3 | The Cr3. |
[in] | VirtualAddress | The address the PF is injected for. |
INT_STATUS_SUCCESS | If the address maps to valid VAD. |
INT_STATUS_NOT_NEEDED_HINT | If a valid VAD does not exits. This will block the PF injection. |
Definition at line 1265 of file winummodule.c.
Referenced by IntWinDagentCheckSuspiciousDllLoad(), and IntWinModHandleModulePathInMemory().
|
static |
Handle a module unload from the given subsystem.
This function will handle an unload on the module located at address VirtualBase. This function will search for a module loaded at the given address inside the given subsystem, it will remove it from the list of loaded modules, it will remove protection from it and it will delete it.
[in] | Subsystem | The subsystem. |
[in] | VirtualBase | The base address of the module being unloaded. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_NEEDED_HINT | If a module with the given address is not found. |
Definition at line 1704 of file winummodule.c.
Referenced by IntWinModHandleUnloadFromVad().
INTSTATUS IntWinModHandleUnloadFromVad | ( | PWIN_PROCESS_OBJECT | Process, |
PVAD | Vad | ||
) |
Handle a module unload.
This function is called whenever an VadImageMap VAD is deleted. Since those VADs describe modules, we will call the unload function whenever such a VAD is destroyed.
[in] | Process | The process owning the VAD. |
[in] | Vad | The deleted Vad. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_NEEDED_HINT | If the VAD does not describe any known loaded module. |
Definition at line 1762 of file winummodule.c.
Referenced by IntWinVadDestroyObject().
|
static |
Handle user-mode writes inside a protected user-mode module.
This function will check if the write being done inside a module is legitimate or not. Usually, in order to determine this, we use the exceptions mechanism. However, there are a few optimizations here:
[in] | Context | The module (PWIN_PROCESS_MODULE structure). |
[in] | Hook | The GPA hook handle. |
[in] | Address | The written guest physical address. |
[out] | Action | The desired action. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 855 of file winummodule.c.
Referenced by IntWinModHandleWrite().
INTSTATUS IntWinModHandleWrite | ( | void * | Context, |
void * | Hook, | ||
QWORD | Address, | ||
INTRO_ACTION * | Action | ||
) |
Handle writes inside a protected user-mode module wrapper. Will dispatch appropriately to either the kernel or user write handler.
[in] | Context | The module (PWIN_PROCESS_MODULE structure). |
[in] | Hook | The GPA hook handle. |
[in] | Address | The written guest physical address. |
[out] | Action | The desired action. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 1036 of file winummodule.c.
Referenced by IntWinModHookModule().
|
static |
Hook a user-mode module against attacks.
This function will iterate all the sections inside the given module and all code & read-only sections will be protected against writes using the EPT. Writes inside this module will be handled by IntWinModHandleWrite.
[in] | Module | The module to be protected. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_INTERNAL_STATE | If an invalid internal state is detected. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 1079 of file winummodule.c.
Referenced by IntWinModHandleModuleHeadersInMemory(), and IntWinModulesChangeProtectionFlags().
|
static |
Hooks the given module against unpacks.
When an unpack is detected inside the given module, the IntWinModPolyHandler callback will be called, which will just send an alerts.
[in] | Module | The module to monitor against unpacks. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1851 of file winummodule.c.
Referenced by IntWinModHandleMainModuleInMemory(), and IntWinModulesChangeProtectionFlags().
|
static |
Verifies if the current KM-UM write is due to an injection.
This function will parse the originator's stacktrace in order to find whether the detoured MmCopyVirtualMemory is on the stack. If it is on the stack, we consider the current write to be due to an injection.
[in] | Originator | The extracted originator of the current KM-UM write. |
[out] | IsInjection | Will be set to TRUE if this write is considered to be due to an injection. |
Definition at line 431 of file winummodule.c.
Referenced by IntWinModHandleKernelWrite().
|
static |
Check if the given module is in the provided list of protected modules.
[in] | Module | The module to check. |
[in] | ProtectedList | A list of protected DLL info. |
[in] | ProtectedCount | Number of entries inside the ProtectedList. |
Definition at line 61 of file winummodule.c.
Referenced by IntWinModHandleModulePathInMemory(), and IntWinModulesChangeProtectionFlags().
INTSTATUS IntWinModPolyHandler | ( | QWORD | Cr3, |
QWORD | VirtualAddress, | ||
PINSTRUX | Instrux, | ||
void * | Context | ||
) |
Handle an unpack event for the indicated address.
This function is called when an unpack is detected on the indicated page. It will just send a an unpack alert.
[in] | Cr3 | The virtual address space the unpack took place in. |
[in] | VirtualAddress | The guest virtual address where the unpack was detected. |
[in] | Instrux | The instruction at VirtualAddress. |
[in] | Context | A PWIN_PROCESS_MODULE structure identifying the module. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 1940 of file winummodule.c.
Referenced by IntWinModHookPoly().
INTSTATUS IntWinModRemoveModule | ( | PWIN_PROCESS_MODULE | Module | ) |
Removes a Windows module.
This function will cleanup all the resources associated with the indicated module, including:
[in] | Module | The module to be removed. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 2043 of file winummodule.c.
Referenced by IntWinModHandleUnload(), and IntWinProcRemoveSubsystem().
void IntWinModulesChangeProtectionFlags | ( | PWIN_PROCESS_SUBSYSTEM | Subsystem | ) |
Change the protection flags applied to the process modules that are currently loaded.
This function will iterate all the loaded modules inside the given subsystem and it will update the protection policy on them. This function must be called when the process protection flags are modified.
[in] | Subsystem | The subsystem we update the protection in. |
Definition at line 2138 of file winummodule.c.
Referenced by IntWinProcChangeProtectionFlags().
INTSTATUS IntWinModUnHookModule | ( | PWIN_PROCESS_MODULE | Module | ) |
Remove the protection from the indicated module.
[in] | Module | The module to disable protection for. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is used. |
Definition at line 1205 of file winummodule.c.
Referenced by IntWinModHandleUnload(), IntWinModulesChangeProtectionFlags(), and IntWinProcRemoveSubsystem().
Checks if a write inside a code section is legitimate or not.
This function is used by the unpacker to check if a write is legitimate or note - if the write is inside a code section but within the IAT, the write is deemed legitimate.
[in] | Cr3 | The virtual address space. |
[in] | Address | The written guest virtual address. |
[in] | Context | The written module. |
Definition at line 1804 of file winummodule.c.
Referenced by IntWinModHookPoly().
INTSTATUS IntWinProcSendAllDllEventsForProcess | ( | PWIN_PROCESS_OBJECT | Process | ) |
Send DLL load events for all modules loaded in all subsystems of a process.
[in] | Process | The process for which we will send DLL load events. |
INT_STATUS_SUCCESS | On success. |
Definition at line 198 of file winummodule.c.
Referenced by IntWinDagentHandleDoubleAgent(), and IntWinModHandleUserWrite().
|
static |
Send a module load event for each loaded module inside a subsystem.
This function is called when we statically identify the modules of a process. It will iterate loaded module inside the provided subsystem and it will send a DLL load event.
[in] | Subsystem | The subsystem for which we will send the DLL load events. |
INT_STATUS_SUCCESS | On success. |
Definition at line 166 of file winummodule.c.
Referenced by IntWinProcSendAllDllEventsForProcess().
|
static |
Send a DLL load/unload event to the integrator.
This function will send an introEventModuleEvent event for the given module, if the modules events INTRO_OPT_EVENT_MODULES flag is enabled.
[in] | Module | The module that was just loaded or unloaded. |
[in] | Loaded | True if the module has been loaded, false if it has been unloaded. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_NEEDED_HINT | If Introcore is unloading or if the module events are not enabled. |
INT_STATUS_ALREADY_INITIALIZED_HINT | If we already sent an event for this module. |
Definition at line 89 of file winummodule.c.
Referenced by IntWinProcSendAllDllEventsForSubsystem().
PWIN_PROCESS_MODULE IntWinUmModFindByAddress | ( | PWIN_PROCESS_OBJECT | Process, |
QWORD | Gva | ||
) |
Searches for a user-mode module which contains the indicated guest virtual address.
NOTE: This function will search in all subsystems.
[in] | Process | The process. |
[in] | Gva | The guest virtual address we are searching for. |
Definition at line 2304 of file winummodule.c.
Referenced by IntExceptGetVictimProcess(), IntExceptUserGetOriginator(), IntWinDagentHandleSuspModExecution(), IntWinStackTraceGetUser(), IntWinStackTraceGetUser32(), IntWinStackTraceGetUser64(), and IntWinThrHandleQueueApc().
const PROTECTED_DLL_INFO gProtectedModules[] |
Base name of every protected DLL. Note that only modules that won't be unloaded can be protected for now, as module unloading is not yet supported.
Definition at line 20 of file winummodule.c.
const PROTECTED_DLL_INFO gProtectedNetModules[] |
Setting a flag for the protection mask of a process will enable extended libraries protection.
Definition at line 33 of file winummodule.c.
const PROTECTED_DLL_INFO gProtectedWowModules[] |
Full path to every DLL that must be protected.
Definition at line 43 of file winummodule.c.