Bitdefender Hypervisor Memory Introspection
|
This file handles Windows Drivers related events (loading, unloading, writes, etc.) More...
#include "windriver.h"
#include "alerts.h"
#include "crc32.h"
#include "hook.h"
#include "swapmem.h"
#include "winpe.h"
#include "winagent.h"
#include "windrv_protected.h"
Go to the source code of this file.
Macros | |
#define | NTOSKRNL_RIP_PAGES_COUNT 20 |
#define | PATCHGUARD_RIP_COUNT 4 |
#define | MAX_KNOWN_DRIVER_READS 100000 |
Functions | |
static void | IntWinDrvSendEvent (KERNEL_DRIVER *Driver, BOOLEAN Loaded) |
Send a driver loaded/unloaded event. More... | |
INTSTATUS | IntWinDrvIsListHead (QWORD PsLoadedModuleListGva, void *PsLoadedModuleList, QWORD KernelLdr) |
Used to identify WINDOWS_GUEST::PsLoadedModuleList. More... | |
INTSTATUS | IntWinDrvIterateLoadedModules (PFUNC_IterateListCallback Callback, QWORD Aux) |
Used to iterate trough the WINDOWS_GUEST::PsLoadedModuleList. More... | |
INTSTATUS | IntWinDrvCreateFromAddress (QWORD ModuleInfo, QWORD Flags) |
Adds a driver to introspection's LoadedModuleList (gKernelDrivers). This way we avoid lots of mapping when searching a driver. More... | |
INTSTATUS | IntWinDrvRemoveFromAddress (QWORD ModuleInfo) |
Removes a driver from the introspection's loaded modules list (gKernelDrivers). More... | |
INTSTATUS | IntWinProtectReadNtEat (void) |
Used to place a read hook on the ntoskrnl.exe EAT. More... | |
INTSTATUS | IntWinUnprotectReadNtEat (void) |
Used to remove the EAT read hook from ntoskrnl.exe. More... | |
static INTSTATUS | IntWinDrvHeadersInMemory (void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags) |
This callback is called as soon as all the driver headers have been read using IntSwapMemReadData. More... | |
INTSTATUS | IntWinDrvProtect (KERNEL_DRIVER *Driver, QWORD ProtectionFlag) |
Used to enable protection for the given driver. More... | |
INTSTATUS | IntWinDrvUnprotect (KERNEL_DRIVER *Driver) |
Used to disable protection for the given driver. More... | |
INTSTATUS | IntWinDrvHandleDriverEntry (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Used to notify the introspection engine when the DriverEntry of a module starts executing. More... | |
static INTSTATUS | IntWinDrvSendAlert (KERNEL_DRIVER *Driver, EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason) |
Sends a driver related EPT violation alert. More... | |
INTSTATUS | IntWinDrvHandleWrite (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Used to notify the introspection engine when a write took place on a protected driver. More... | |
static KERNEL_DRIVER * | IntWinGetDriverByGva (QWORD Rip) |
Iterates all the loaded drivers to see if the Rip points inside any of them. More... | |
static INTSTATUS | IntWinDrvForceDisableReadNtEat (KERNEL_DRIVER *CurrentOriginator) |
This function is used to disable the INTRO_OPT_PROT_KM_NT_EAT_READS by removing the hook IntWinDrvHandleRead. More... | |
INTSTATUS | IntWinDrvHandleRead (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
Used to notify the introspection engine when a read took place on a protected driver (used only for ntoskrnl.exe). More... | |
static INTSTATUS | IntWinDrvFreeEntry (KERNEL_DRIVER *Driver, QWORD Reserved) |
Frees the memory allocate for the KERNEL_DRIVER structure. More... | |
INTSTATUS | IntWinDrvRemoveEntry (KERNEL_DRIVER *Driver) |
Removes the KERNEL_DRIVER from the internal structures. More... | |
INTSTATUS | IntWinDrvUpdateProtection (void) |
Used to update the protection for all the loaded modules (gKernelDrivers). More... | |
Variables | |
LIST_HEAD | gKernelDrivers |
List of all the drivers currently loaded inside the guest. More... | |
This file handles Windows Drivers related events (loading, unloading, writes, etc.)
Introcore provides a very good protection against kernel exploits by identifying already loaded drivers and intercepting driver load/unload events. Once a driver is identified, read/write hooks are placed in order to protect critical structures (such as the EAT, IAT, etc.). This file contains all the functions used to identify the kernel drivers, hook critical driver structures, handle driver related EPT violations and notify the integrator upon driver related events.
Definition in file windriver.c.
#define MAX_KNOWN_DRIVER_READS 100000 |
Referenced by IntWinDrvHandleRead().
#define NTOSKRNL_RIP_PAGES_COUNT 20 |
Referenced by IntWinDrvHandleRead().
#define PATCHGUARD_RIP_COUNT 4 |
Referenced by IntWinDrvHandleRead().
Adds a driver to introspection's LoadedModuleList (gKernelDrivers). This way we avoid lots of mapping when searching a driver.
[in] | ModuleInfo | The LDR_DATA_TABLE_ENTRY32 or LDR_DATA_TABLE_ENTRY64 corresponding to the module. |
[in] | Flags | If FLAG_DYNAMIC_DETECTION flag is set, we will execute-protect the first page of the module. This way, when the first instruction will get executed, we will be notified, and we'll have a chance to protect the driver's driver object. |
INT_STATUS_SUCCESS | On success. |
Definition at line 305 of file windriver.c.
Referenced by IntDriverLoadHandler(), and IntWinGuestFinishInit().
|
static |
This function is used to disable the INTRO_OPT_PROT_KM_NT_EAT_READS by removing the hook IntWinDrvHandleRead.
In some cases, a known driver could read the NT EAT so many times that a significant performance impact will be noticed (even if all the reads are allowed). After reaching a predetermined threshold, the INTRO_OPT_PROT_KM_NT_EAT_READS option will be disabled so that the system will not "hang" and the integrator will be notified.
[in] | CurrentOriginator | The last driver that read the EAT (in is not necessarily the driver that performed all the reads, although is highly likely). |
INT_STATUS_SUCCESS | On success. |
Definition at line 1436 of file windriver.c.
Referenced by IntWinDrvHandleRead().
|
static |
Frees the memory allocate for the KERNEL_DRIVER structure.
[in] | Driver | The driver to be freed. |
[in] | Reserved | Reserved for further use. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1659 of file windriver.c.
Referenced by IntWinDrvRemoveEntry().
INTSTATUS IntWinDrvHandleDriverEntry | ( | void * | Context, |
void * | Hook, | ||
QWORD | Address, | ||
INTRO_ACTION * | Action | ||
) |
Used to notify the introspection engine when the DriverEntry of a module starts executing.
This hook will be established on the page containing the EP of freshly loaded drivers. On the execution of the first EP instruction, we will be notified, and we will be able to retrieve the driver-object associated to that driver, and hook it, if needed.
[in] | Context | User-supplied context (may contain anything, including NULL). |
[in] | Hook | The GPA hook associated to this callback. |
[in] | Address | GPA address that was accessed. |
[out] | Action | Desired action (allow, block). |
INT_STATUS_SUCCESS | On success. |
Definition at line 1152 of file windriver.c.
Referenced by IntWinDrvCreateFromAddress().
INTSTATUS IntWinDrvHandleRead | ( | void * | Context, |
void * | Hook, | ||
QWORD | Address, | ||
INTRO_ACTION * | Action | ||
) |
Used to notify the introspection engine when a read took place on a protected driver (used only for ntoskrnl.exe).
[in] | Context | The driver for which the violation took place (KERNEL_DRIVER structure). |
[in] | Hook | The GPA hook associated to this callback. |
[in] | Address | GPA address that was accessed. |
[out] | Action | Desired action (allow, block). |
INT_STATUS_SUCCESS | On success. |
Definition at line 1483 of file windriver.c.
Referenced by IntWinProtectReadNtEat().
INTSTATUS IntWinDrvHandleWrite | ( | void * | Context, |
void * | Hook, | ||
QWORD | Address, | ||
INTRO_ACTION * | Action | ||
) |
Used to notify the introspection engine when a write took place on a protected driver.
[in] | Context | The driver for which the violation took place (KERNEL_DRIVER structure). |
[in] | Hook | The GPA hook associated to this callback. |
[in] | Address | GPA address that was accessed. |
[out] | Action | Desired action (allow, block). |
INT_STATUS_SUCCESS | On success. |
Definition at line 1315 of file windriver.c.
Referenced by IntWinDrvHeadersInMemory().
|
static |
This callback is called as soon as all the driver headers have been read using IntSwapMemReadData.
[in] | Context | The KERNEL_DRIVER structure. |
[in] | Cr3 | The virtual address space. |
[in] | VirtualAddress | The base virtual address read. |
[in] | PhysicalAddress | The physical address of the first page (VirtualAddress) read. |
[in] | Data | Buffer containing the read data. This will be freed once the callback returns! |
[in] | DataSize | Size of the Data buffer. Will normally be equal to the Length passed to read function. |
[in] | Flags | Swap flags. Check out SWAPMEM_FLG* for more info. |
INT_STATUS_SUCCESS | On success. |
Definition at line 724 of file windriver.c.
Referenced by IntWinDrvProtect().
INTSTATUS IntWinDrvIsListHead | ( | QWORD | PsLoadedModuleListGva, |
void * | PsLoadedModuleList, | ||
QWORD | KernelLdr | ||
) |
Used to identify WINDOWS_GUEST::PsLoadedModuleList.
[in] | PsLoadedModuleListGva | The PsLoadedModuleList GVA. |
[in] | PsLoadedModuleList | The PsLoadedModuleList (mapped). |
[in] | KernelLdr | GVA pointer to a LDR_DATA_TABLE_ENTRY32 or LDR_DATA_TABLE_ENTRY64 structure. |
INT_STATUS_SUCCESS | If the PsLoadedModuleListGva is the actual list head. |
Definition at line 67 of file windriver.c.
Referenced by IntWinGuestFindKernelObjectsInternal().
INTSTATUS IntWinDrvIterateLoadedModules | ( | PFUNC_IterateListCallback | Callback, |
QWORD | Aux | ||
) |
Used to iterate trough the WINDOWS_GUEST::PsLoadedModuleList.
[in] | Callback | The PFUNC_IterateListCallback callback invoked for every module. |
[in] | Aux | The auxiliary value passed to the callback. |
INT_STATUS_SUCCESS | On success. |
Definition at line 227 of file windriver.c.
Referenced by IntWinGuestFinishInit().
INTSTATUS IntWinDrvProtect | ( | KERNEL_DRIVER * | Driver, |
QWORD | ProtectionFlag | ||
) |
Used to enable protection for the given driver.
[in] | Driver | The driver to be protected. |
[in] | ProtectionFlag | The protection flag. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_ALREADY_INITIALIZED_HINT | If the driver is already protected. |
INT_STATUS_INVALID_PARAMETER_1 | If the driver is NULL. |
Definition at line 1069 of file windriver.c.
Referenced by IntWinDrvCreateFromAddress(), and IntWinDrvUpdateProtection().
INTSTATUS IntWinDrvRemoveEntry | ( | KERNEL_DRIVER * | Driver | ) |
Removes the KERNEL_DRIVER from the internal structures.
[in] | Driver | The driver to be removed. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1696 of file windriver.c.
Referenced by IntDriverUninit(), IntWinDrvCreateFromAddress(), and IntWinDrvRemoveFromAddress().
Removes a driver from the introspection's loaded modules list (gKernelDrivers).
[in] | ModuleInfo | The LDR_DATA_TABLE_ENTRY32 or LDR_DATA_TABLE_ENTRY64 corresponding to the module. |
INT_STATUS_SUCCESS | On success. |
Definition at line 522 of file windriver.c.
Referenced by IntDriverUnloadHandler().
|
static |
Sends a driver related EPT violation alert.
[in] | Driver | The driver for which the violation took place. |
[in] | Victim | The victim. |
[in] | Originator | The originator. |
[in] | Action | Taken action. |
[in] | Reason | Reason for the taken reason. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1250 of file windriver.c.
Referenced by IntWinDrvHandleRead(), and IntWinDrvHandleWrite().
|
static |
Send a driver loaded/unloaded event.
If INTRO_OPT_EVENT_MODULES is set, the integrator will be notified when a driver has been loaded or unloaded.
[in] | Driver | The driver that was loaded/unloaded. |
[in] | Loaded | True if the driver has been loaded, FALSE otherwise. |
Definition at line 30 of file windriver.c.
Referenced by IntWinDrvCreateFromAddress(), and IntWinDrvRemoveFromAddress().
INTSTATUS IntWinDrvUnprotect | ( | KERNEL_DRIVER * | Driver | ) |
Used to disable protection for the given driver.
[in] | Driver | The driver to be removed from protection. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER_1 | If the driver is NULL. |
Definition at line 1103 of file windriver.c.
Referenced by IntWinDrvRemoveEntry(), and IntWinDrvUpdateProtection().
INTSTATUS IntWinDrvUpdateProtection | ( | void | ) |
Used to update the protection for all the loaded modules (gKernelDrivers).
INT_STATUS_SUCCESS | On success. |
Definition at line 1751 of file windriver.c.
Referenced by IntGuestUpdateCoreOptions().
|
static |
Iterates all the loaded drivers to see if the Rip points inside any of them.
[in] | Rip | The RIP to be checked. |
The | KERNEL_DRIVER structure of the originating driver. |
NULL | if the Rip does NOT points inside a known driver. |
Definition at line 1411 of file windriver.c.
Referenced by IntWinDrvHandleRead().
INTSTATUS IntWinProtectReadNtEat | ( | void | ) |
Used to place a read hook on the ntoskrnl.exe EAT.
INT_STATUS_SUCCESS | On success. |
Definition at line 622 of file windriver.c.
Referenced by IntGuestUpdateCoreOptions(), and IntWinDrvHeadersInMemory().
INTSTATUS IntWinUnprotectReadNtEat | ( | void | ) |
Used to remove the EAT read hook from ntoskrnl.exe.
INT_STATUS_SUCCESS | On success. |
Definition at line 690 of file windriver.c.
Referenced by IntGuestUpdateCoreOptions(), and IntWinDrvForceDisableReadNtEat().