|
Bitdefender Hypervisor Memory Introspection
|
#include "hook.h"#include "hook_pts.h"#include "alerts.h"#include "gpacache.h"#include "kernvm.h"Go to the source code of this file.
Data Structures | |
| struct | _INVOCATION_CONTEXT |
Macros | |
| #define | INVK_CTX_CACHE_SIZE 8 |
| #define | PTS_LEVEL_ROOT 6 |
| #define | PTS_LEVEL_PML5 5 |
| #define | PTS_LEVEL_PML4 4 |
| #define | PTS_LEVEL_PDP 3 |
| #define | PTS_LEVEL_PD 2 |
| #define | PTS_LEVEL_PT 1 |
Typedefs | |
| typedef struct _INVOCATION_CONTEXT | INVOCATION_CONTEXT |
| typedef struct _INVOCATION_CONTEXT * | PINVOCATION_CONTEXT |
Functions | |
| static PHOOK_PTS_ENTRY | IntHookPtsFindEntry (LIST_HEAD *ListHead, QWORD PhysicalAddress) |
| Finds an already existing page-table entry hook on a given physical address. More... | |
| static INTSTATUS | IntHookPtsCreateEntry (QWORD PtPaAddress, WORD EntrySizeAndLevel, PHOOK_PTS_ENTRY Parent, PHOOK_PTS_ENTRY *Entry) |
| Creates a new page-table entry hook structure. More... | |
| static INTSTATUS | IntHookPtsHandleModification (PHOOK_PTS_ENTRY Entry, QWORD OldValue, QWORD NewValue) |
| Handle a modification inside a page-table entry. More... | |
| static QWORD | IntHookPtsGetPageSize (PHOOK_PTS_ENTRY Entry) |
| Computes the page size of a PTS entry. More... | |
| static void | IntHookAddCallbackToList (PLIST_HEAD List, PHOOK_PTS Context) |
| Adds a callback to the provided list. More... | |
| static void | IntHookPtsCloneCallbacks (PHOOK_PTS_ENTRY Entry) |
| Clone a list of callbacks locally, so they can be safely invoked. More... | |
| static INTSTATUS | IntHookPtsInvokeCallbacks (LIST_HEAD *Callbacks) |
| Invoke all the callbacks from a given list. More... | |
| static INTSTATUS | IntHookPtsWriteCallback (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action) |
| Page-table modification handler. More... | |
| static INTSTATUS | IntHookPtsRemovePteHook (PHOOK_PTS_ENTRY Entry, DWORD Flags) |
| Remove a page table entry hook. More... | |
| static INTSTATUS | IntHookPtsRemoveHookInternal (PHOOK_PTS Hook, DWORD Flags) |
| Remove a PTS hook. More... | |
| static INTSTATUS | IntHookPtsDeletePdHook (PHOOK_PTS_ENTRY Hook, DWORD Flags) |
| Permanently deletes a page-table entry hook. More... | |
| static INTSTATUS | IntHookPtsDeleteParents (PHOOK_PTS_ENTRY Hook, DWORD Flags) |
| Permanently deletes all PTM hooks of a page-table entry hook. More... | |
| static INTSTATUS | IntHookPtsDeleteHookInternal (PHOOK_PTS Hook, DWORD Flags) |
| Permanently deletes a PTS hook. More... | |
| static INTSTATUS | IntHookPtsDisableEntry (PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress, QWORD NewPteValue) |
| Disable a page-table entry hook. More... | |
| static INTSTATUS | IntHookPtsEnableEntry (PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress) |
| Enable a page-table entry hook. More... | |
| static INTSTATUS | IntHookPtsRemapEntry (PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress) |
| Remap a page-table entry to a new value. More... | |
| static INTSTATUS | IntHookPtsMergeEntry (PHOOK_PTS_ENTRY MergeRoot, PHOOK_PTS_ENTRY Entry) |
| Merge multiple entries into a single one. More... | |
| static INTSTATUS | IntHookPtsControlEntry (PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress, QWORD NewPteValue) |
| Handle control bits modifications inside a page-table entry. More... | |
| INTSTATUS | IntHookPtsSetHook (QWORD Cr3, QWORD VirtualAddress, PFUNC_SwapCallback Callback, void *Context, void *Parent, DWORD Flags, PHOOK_PTS *Hook) |
| Start monitoring translation modifications for the given VirtualAddress. More... | |
| INTSTATUS | IntHookPtsRemoveHook (HOOK_PTS **Hook, DWORD Flags) |
| Remove a PTS hook. More... | |
| INTSTATUS | IntHookPtsDeleteHook (HOOK_PTS **Hook, DWORD Flags) |
| Permanently delete the PTS hook. More... | |
| static __inline INTSTATUS | IntHookPtsCleanupList (LIST_HEAD *ListHead) |
| Commits a list of page-table entry hooks. More... | |
| INTSTATUS | IntHookPtsCommitHooks (void) |
| Commit all PTS hook modifications. More... | |
| INTSTATUS | IntHookPtsInit (void) |
| Initializes the PTS hooks system. More... | |
| INTSTATUS | IntHookPtsWriteEntry (PHOOK_PTS_ENTRY Entry, QWORD OldValue, QWORD NewValue) |
| Tests the translation modification handler. More... | |
| INTSTATUS | IntHookPtsCheckIntegrity (void) |
| Checks the integrity of the existing page-table hooks. Used for debugging the PT filter. More... | |
| static INTSTATUS | IntHookPtsDumpPtsEntry (HOOK_PTS_ENTRY const *Entry) |
| Prints a HOOK_PTS_ENTRY structure. More... | |
| void | IntHookPtsDump (void) |
| Prints all the page table hooks. More... | |
Variables | |
| static INVOCATION_CONTEXT | gInvkCtxStatic [INVK_CTX_CACHE_SIZE] |
| static DWORD | gInvkCtxIndex |
| #define INVK_CTX_CACHE_SIZE 8 |
We keep up to 8 entries statically allocated, in order to avoid the cost of dynamically allocating memory each time we have a translation modification.
Definition at line 107 of file hook_pts.c.
Referenced by IntHookPtsCloneCallbacks().
| #define PTS_LEVEL_PD 2 |
Definition at line 116 of file hook_pts.c.
Referenced by IntHookPtsSetHook().
| #define PTS_LEVEL_PDP 3 |
Definition at line 115 of file hook_pts.c.
Referenced by IntHookPtsSetHook().
| #define PTS_LEVEL_PML4 4 |
Definition at line 114 of file hook_pts.c.
Referenced by IntHookPtsSetHook().
| #define PTS_LEVEL_PML5 5 |
Definition at line 113 of file hook_pts.c.
Referenced by IntHookPtsSetHook().
| #define PTS_LEVEL_PT 1 |
Definition at line 117 of file hook_pts.c.
Referenced by IntHookPtsSetHook().
| #define PTS_LEVEL_ROOT 6 |
Definition at line 112 of file hook_pts.c.
Referenced by IntHookPtsCreateEntry(), and IntHookPtsSetHook().
| typedef struct _INVOCATION_CONTEXT INVOCATION_CONTEXT |
Some important notes regarding the PTS hooks:
It is important to understand the different types of hooks which exist for page-tables:
| typedef struct _INVOCATION_CONTEXT * PINVOCATION_CONTEXT |
|
static |
Adds a callback to the provided list.
Adds the provided PTS context to the provided list, maintaining the priority order. Some contexts/hook entries may have a higher priority than others.
| [in] | List | The list where the context must be inserted. |
| [in] | Context | The context/hook entry to be inserted. |
Definition at line 164 of file hook_pts.c.
Referenced by IntHookPtsHandleModification(), IntHookPtsMergeEntry(), and IntHookPtsSetHook().
| INTSTATUS IntHookPtsCheckIntegrity | ( | void | ) |
Checks the integrity of the existing page-table hooks. Used for debugging the PT filter.
This function will iterate through all the monitored virtual addresses and check if the actual translation present inside the guest is the same as the last value saved by Introcore. Basically, this function ensures that these hook structures are up to date with the actual memory contents. Used for debugging the PT filter.
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_NOT_NEEDED_HINT | If PT filtering is not enabled. |
| INT_STATUS_NOT_INITIALIZED_HINT | If the hooks system is not initialized. |
Definition at line 2236 of file hook_pts.c.
Referenced by IntHandleTimer().
Commits a list of page-table entry hooks.
| [in] | ListHead | The list of page-table entry hooks to be committed. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 2037 of file hook_pts.c.
Referenced by IntHookPtsCommitHooks().
|
static |
Clone a list of callbacks locally, so they can be safely invoked.
This function will simply alloc the callbacks invocation list. The callbacks will be called when we're done processing everything and any locks are released. This also allows each callback to safely remove its own hook, if it desires so.
| [in] | Entry | The entry whose callbacks are to be invoked. |
Definition at line 207 of file hook_pts.c.
Referenced by IntHookPtsHandleModification().
| INTSTATUS IntHookPtsCommitHooks | ( | void | ) |
Commit all PTS hook modifications.
This function will effectively delete all the removed PTS hooks. Hooks which are flagged with the HOOK_FLG_CHAIN_DELETE delete will be spared, as it is expected that they will be deleted by a higher-level hook manager.
| INT_STATUS_SUCCESS | On success. |
Definition at line 2084 of file hook_pts.c.
Referenced by IntHookCommitAllHooks().
|
static |
Handle control bits modifications inside a page-table entry.
| [in] | Entry | The entry being modified. |
| [in] | NewPtPaAddress | The page-table physical address. |
| [in] | NewPteValue | The page-table entry value. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 1074 of file hook_pts.c.
|
static |
Creates a new page-table entry hook structure.
This function will allocate a new HOOK_PTS_ENTRY structure for a page-table entry that is not monitored yet.
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_INSUFFICIENT_RESOURCES | If a memory allocation fails. |
Definition at line 1395 of file hook_pts.c.
Referenced by IntHookPtsHandleModification(), and IntHookPtsSetHook().
Permanently delete the PTS hook.
This function will permanently delete an existing PTS hook. This function must be called only if the hook has already been removed.
| [in,out] | Hook | The hook to be deleted. |
| [in] | Flags | Hook flags. Check out HOOK_FLG* for more info. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 1993 of file hook_pts.c.
Referenced by IntHookGvaDeleteHookInternal().
Permanently deletes a PTS hook.
This function will delete a PTS hook, together with all of its page-table entry and PTM hooks, if required.
| [in] | Hook | The hook to be removed. |
| [in] | Flags | Removal flags. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 756 of file hook_pts.c.
Referenced by IntHookPtsCommitHooks(), and IntHookPtsDeleteHook().
|
static |
Permanently deletes all PTM hooks of a page-table entry hook.
This function will delete all the PTM hook of a given page table entry hook.
| [in] | Hook | The hook to be removed. |
| [in] | Flags | Removal flags. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 709 of file hook_pts.c.
Referenced by IntHookPtsDeleteHookInternal().
|
static |
Permanently deletes a page-table entry hook.
This function will delete the PTM hook of a given page table entry hook.
| [in] | Hook | The hook to be removed. |
| [in] | Flags | Removal flags. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 673 of file hook_pts.c.
Referenced by IntHookPtsCleanupList(), and IntHookPtsDeleteParents().
|
static |
Disable a page-table entry hook.
This function handles PTEs that have just become absent. Basically, the PTE that points to this entry has become invalid, and therefore we have to disable this entry.
| [in] | Entry | The PTS entry which is to be disabled. |
| [in] | NewPtPaAddress | Reserved for future use. |
| [in] | NewPteValue | Reserved for future use. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 831 of file hook_pts.c.
Referenced by IntHookPtsHandleModification(), and IntHookPtsRemapEntry().
| void IntHookPtsDump | ( | void | ) |
Prints all the page table hooks.
This prints all the page table hooks from gHooks.
Definition at line 2452 of file hook_pts.c.
Referenced by IntHandleMemAccess(), and IntHookPtwEmulateWrite().
|
static |
Prints a HOOK_PTS_ENTRY structure.
| [in] | Entry | Structure to print. |
| INT_STATUS_SUCCESS | in case of success. |
| INT_STATUS_INVALID_PARAMETER_1 | if Entry is NULL. |
Definition at line 2388 of file hook_pts.c.
Referenced by IntHookPtsDump().
|
static |
Enable a page-table entry hook.
The PT entry that points to this entry has just become valid. We can re-enable this entry and place a new hook on the PTE of this entry, since the upper level PTE just become valid.
| [in] | Entry | The page-table entry hook that will be enabled. |
| [in] | NewPtPaAddress | The new page-table physical address. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 873 of file hook_pts.c.
Referenced by IntHookPtsHandleModification(), and IntHookPtsRemapEntry().
|
static |
Finds an already existing page-table entry hook on a given physical address.
| [in] | ListHead | The list to search for a matching PTS entry hook. |
| [in] | PhysicalAddress | The address for which we are searching an already existing PTS entry hook. |
| The | found PTS entry hook or NULL if none is found. |
Definition at line 796 of file hook_pts.c.
Referenced by IntHookPtsHandleModification(), and IntHookPtsSetHook().
|
static |
Computes the page size of a PTS entry.
Using the entry size and the level of a given translation, compute the page size associated to it.
| [in] | Entry | The entry whose size is to be computed. |
| The | page size associated with this entry. |
Definition at line 143 of file hook_pts.c.
Referenced by IntHookPtsCloneCallbacks(), and IntHookPtsSetHook().
|
static |
Handle a modification inside a page-table entry.
This function handles all types of modifications inside page-table entries, at any level. The cases it needs to handle are:
| [in] | Entry | The page-table entry that is being modified. |
| [in] | OldValue | Old page-table entry value. |
| [in] | NewValue | New page-table entry value. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_NOT_NEEDED_HINT | If both the old and the new values are invalid. |
Definition at line 1100 of file hook_pts.c.
Referenced by IntHookPtsWriteCallback(), and IntHookPtsWriteEntry().
| INTSTATUS IntHookPtsInit | ( | void | ) |
Initializes the PTS hooks system.
| INT_STATUS_SUCCESS | On success. |
Definition at line 2183 of file hook_pts.c.
Referenced by IntHookInit().
Invoke all the callbacks from a given list.
This function calls all the PTS (swap) callbacks for a given virtual address that has just had its translation modified. The provided argument is a list of INVOCATION_CONTEXT structures.
| [in] | Callbacks | List of INVOCATION_CONTEXT structures, one for each distinct callback. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_ACCESS_DENIED | If the PT modification seems malicious. Note that even if access denied is returned, the PT entry write may have already been emulated. |
Definition at line 272 of file hook_pts.c.
Referenced by IntHookPtsWriteCallback().
|
static |
Merge multiple entries into a single one.
The PTE that points to this entry has just become PSE - Page Size Extended. This means that now it points to a single 2M/4M/1G page instead of another PT. We have to iterate the lower levels and "Adopt" all the contexts from the lower level entries, which will be destroyed.
| [in] | MergeRoot | The new root page-table entry hook. |
| [in] | Entry | The page-table entry hook that is being migrated to the larger page. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_INVALID_INTERNAL_STATE | If an invalid internal state is encountered. |
InsertTailList(&MergeRoot->ContextEntries, &pPts->Link);
Definition at line 968 of file hook_pts.c.
Referenced by IntHookPtsHandleModification().
|
static |
Remap a page-table entry to a new value.
The PT entry that points to this entry has just been remapped. It remained valid, but the physical address of the pointed table modified.
| [in] | Entry | The page-table entry that has just changed translations. |
| [in] | NewPtPaAddress | The new page-table physical address. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 931 of file hook_pts.c.
Referenced by IntHookPtsHandleModification().
Remove a PTS hook.
Remove a PTS hook. Modifications to the subsequent virtual address translations will not be reported anymore. The hook is not deleted until either the commit phase, or when a higher level hook manager decides so.
| [in,out] | Hook | The hook to be removed. |
| [in] | Flags | Hook flags. Check out HOOK_FLG* for more info. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 1944 of file hook_pts.c.
Referenced by DbgPtsUnhook(), IntHookGvaRemoveHookInternal(), IntHookPtsInvokeCallbacks(), IntHookRemoveChain(), IntIcFreeInvdEntry(), IntSwapMemCancelTransaction(), IntSwapMemPageSwappedIn(), IntWinPfnHandleTranslationChange(), IntWinPfnRemoveLock(), and IntWinPfnUnlockAddress().
Remove a PTS hook.
This function will remove a PTS hook. This means that the callback will not be called anymore on translation modifications. HOOK_PTS_ENTRY and HOOK_PTM entries may still remain valid, if there are other HOOK_PTS entries pointing to them (they are reference counted).
| [in] | Hook | The PTS hook to be removed. |
| [in] | Flags | The removal flags. Check out HOOK_FLG* for more info. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 585 of file hook_pts.c.
Referenced by IntHookPtsRemoveHook(), and IntHookPtsSetHook().
|
static |
Remove a page table entry hook.
| [in] | Entry | The page table entry hook to be removed. |
| [in] | Flags | Removal flags. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 509 of file hook_pts.c.
Referenced by IntHookPtsMergeEntry(), and IntHookPtsRemoveHookInternal().
| INTSTATUS IntHookPtsSetHook | ( | QWORD | Cr3, |
| QWORD | VirtualAddress, | ||
| PFUNC_SwapCallback | Callback, | ||
| void * | Context, | ||
| void * | Parent, | ||
| DWORD | Flags, | ||
| PHOOK_PTS * | Hook | ||
| ) |
Start monitoring translation modifications for the given VirtualAddress.
Establishes a hook inside the page-tables of the given VirtualAddress inside the Cr3 virtual address space. Whenever there is a translation modification for the given VirtualAddress, the Callback will be invoked. The Context can be a user-supplied value which is passed to the invoked callback. This function will either add a new page-table entry hook (PTS entry hook) on each page-table entry used to translate the provided virtualAddress, or it will simply increment the reference count of an existing such entry.
| [in] | Cr3 | The monitored virtual address space. |
| [in] | VirtualAddress | The virtual address to be monitored. |
| [in] | Callback | The PFUNC_SwapCallback to be called when the translation is modified. |
| [in] | Context | Optional context that will be passed to the Callback. |
| [in] | Parent | Optional parent hook. |
| [in] | Flags | Hook flags. Check HOOK_FLG* for more info. |
| [out] | Hook | The hook handle which can later be used to remove this hook. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
| INT_STATUS_NOT_SUPPORTED | If a kernel-mode address is to be monitored outside the kernel Cr3. |
| INT_STATUS_INSUFFICIENT_RESOURCES | If a memory allocation fails. |
Definition at line 1535 of file hook_pts.c.
Referenced by DbgPtsHook(), IntHookGvaSetHook(), IntIcAddInvdForInstruction(), IntSwapMemReadData(), and IntWinPfnLockAddress().
|
static |
Page-table modification handler.
This function is called by the PTM hook manager, whenever a page-table entry is written. This is called for each written entry, and for each effective write. This function will call the PT write handler, IntHookPtwProcessWrite, and if we are dealing with a partial write, it will bail out. In essence, it just processes the page-table entry write, and calls the main IntHookPtsHandleModification handler.
| [in] | Context | The written PTS entry (PHOOK_PTS_ENTRY). |
| [in] | Hook | The GPA hook handle. |
| [in] | Address | Written guest physical address. |
| [out] | Action | Desired action for the memory write. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 374 of file hook_pts.c.
Referenced by IntHookPtsCreateEntry(), and IntHookPtsEnableEntry().
| INTSTATUS IntHookPtsWriteEntry | ( | PHOOK_PTS_ENTRY | Entry, |
| QWORD | OldValue, | ||
| QWORD | NewValue | ||
| ) |
Tests the translation modification handler.
| [in] | Entry | The entry to be "modified". |
| [in] | OldValue | Old page-table entry value. |
| [in] | NewValue | New page-table entry value. |
Definition at line 2216 of file hook_pts.c.
Referenced by DbgPtsWrite().
|
static |
Definition at line 109 of file hook_pts.c.
Referenced by IntHookPtsCloneCallbacks(), and IntHookPtsWriteCallback().
|
static |
Definition at line 108 of file hook_pts.c.