Bitdefender Hypervisor Memory Introspection
|
Go to the source code of this file.
Macros | |
#define | for_each_pfn_lock(_var_name) list_for_each (gWinPfns, WIN_PFN_LOCK, _var_name) |
Iterates the linked list in gWinPfns. More... | |
Functions | |
INTSTATUS | IntWinPfnIsMmPfnDatabase (QWORD MmPfnDatabase) |
Checks if a a guest virtual address points to MmPfnDatabase. More... | |
static INTSTATUS | IntWinPfnModifyRefCount (QWORD PhysicalAddress, BOOLEAN Increment) |
Modifies the in-guest reference count of a physical page. More... | |
static PWIN_PFN_LOCK | IntWinPfnFindByGpa (QWORD GpaPage) |
Finds a PFN lock by a guest physical address. More... | |
static PWIN_PFN_LOCK | IntWinPfnFindByGva (QWORD GvaPage) |
Finds a PFN lock by a guest virtual address. More... | |
static INTSTATUS | IntWinPfnMoveLock (WIN_PFN_LOCK *PfnLock, QWORD NewGpa) |
Moves a lock set for a guest virtual address when the page to which it translates to changes. More... | |
static INTSTATUS | IntWinPfnUnlockAddress (QWORD Address, BOOLEAN IsPhysical) |
Unlocks a guest page. More... | |
static INTSTATUS | IntWinPfnHandleTranslationChange (WIN_PFN_LOCK *Context, QWORD VirtualAddress, QWORD OldEntry, QWORD NewEntry, QWORD OldPageSize, QWORD NewPageSize) |
Handles translation changes for locked guest virtual pages. More... | |
static INTSTATUS | IntWinPfnLockAddress (QWORD Address, BOOLEAN IsPhysical, PWIN_PFN_LOCK *PfnLock) |
Locks a guest page. More... | |
INTSTATUS | IntWinPfnLockGva (QWORD Gva, WIN_PFN_LOCK **PfnLock) |
Locks a guest virtual address. More... | |
INTSTATUS | IntWinPfnLockGpa (QWORD Gpa, WIN_PFN_LOCK **PfnLock) |
Locks a guest physical address. More... | |
INTSTATUS | IntWinPfnRemoveLock (WIN_PFN_LOCK *PfnLock, BOOLEAN Force) |
Removes a PFN lock. More... | |
void | IntWinPfnDump (void) |
Prints all the PFN locks. More... | |
void | IntWinPfnUnInit (void) |
Uninits the PFN locks. More... | |
Variables | |
static LIST_HEAD | gWinPfns = LIST_HEAD_INIT(gWinPfns) |
The list of locked PFNs. More... | |
#define for_each_pfn_lock | ( | _var_name | ) | list_for_each (gWinPfns, WIN_PFN_LOCK, _var_name) |
Iterates the linked list in gWinPfns.
Can be used to safely iterate the PFN list. The current PFN pointed to by _var_name can safely be removed from the list, but note that removing other detours while iterating the list using this macro is not a valid operation and can corrupt the list.
[in] | _var_name | The name of the variable in which the WIN_PFN_LOCK pointer will be placed. This variable will be declared by the macro an available only in the context created by the macro. |
Definition at line 20 of file winpfn.c.
Referenced by IntWinPfnDump(), IntWinPfnFindByGpa(), IntWinPfnFindByGva(), and IntWinPfnUnInit().
|
static |
Finds a PFN lock by a guest physical address.
[in] | GpaPage | The page to search by. |
Definition at line 338 of file winpfn.c.
Referenced by IntWinPfnLockAddress(), and IntWinPfnUnlockAddress().
|
static |
Finds a PFN lock by a guest virtual address.
[in] | GvaPage | The page to search by. |
Definition at line 364 of file winpfn.c.
Referenced by IntWinPfnLockAddress(), and IntWinPfnUnlockAddress().
|
static |
Handles translation changes for locked guest virtual pages.
This is the EPT swap hook set by IntWinPfnLockAddress. Since locks on virtual pages are in fact locks on the physical pages to which they translate to, when the translation changes, we also have to move the lock to the new page. If the new page is a large page, or if the page is swapped out, the in-guest reference counter is decremented. For large pages the swap hook will also be removed, as large pages are not swappable. If the page size remains 4KB, the lock is moved using IntWinPfnMoveLock.
[in] | Context | The context set by IntWinPfnLockAddress. This will be the WIN_PFN_LOCK structure for which the hook was placed. |
[in] | VirtualAddress | The guest virtual address for which the translation changed. |
[in] | OldEntry | The old page table entry for VirtualAddress. |
[in] | NewEntry | The new page table entry for VirtualAddress. |
[in] | OldPageSize | The old page size. Ignored. |
[in] | NewPageSize | The new page size. |
Definition at line 531 of file winpfn.c.
Referenced by IntWinPfnLockAddress().
Checks if a a guest virtual address points to MmPfnDatabase.
[in] | MmPfnDatabase | Guest virtual address to check. |
INT_STATUS_SUCCESS | if the provided address is indeed the MmPfnDataBase. |
INT_STATUS_INVALID_OBJECT_TYPE | if it is not. |
Definition at line 24 of file winpfn.c.
Referenced by IntWinGuestFindKernelObjectsInternal().
|
static |
Locks a guest page.
Every IntWinPfnLockAddress call for an address must match a call to this function. If the Introcore reference counter reaches 0, it means that we also have to remove the lock from the guest, but only if it is a physical, not large, page. Also, any resources held by the lock are freed: the swap hook (if it exists) and the lock itself. It will also be removed from the gWinPfns list.
[in] | Address | Address to unlock. |
[in] | IsPhysical | True if Address is a guest physical address; False if it is a guest virtual address. |
[out] | PfnLock | On success, will contain a pointer to the lock. May be NULL. |
INT_STATUS_SUCCESS | in case of success. |
INT_STATUS_INVALID_PARAMETER_2 | if Address is a guest virtual address and it does not point inside the kernel. |
INT_STATUS_NOT_FOUND | if no lock is found for Address. |
Definition at line 636 of file winpfn.c.
Referenced by IntWinPfnLockGpa(), and IntWinPfnLockGva().
INTSTATUS IntWinPfnLockGpa | ( | QWORD | Gpa, |
WIN_PFN_LOCK ** | PfnLock | ||
) |
Locks a guest physical address.
[in] | Gpa | Guest physical address to lock. |
[out] | PfnLock | On success, will contain a pointer to the lock. May be NULL. |
Definition at line 820 of file winpfn.c.
Referenced by IntWinProcLockCr3().
INTSTATUS IntWinPfnLockGva | ( | QWORD | Gva, |
WIN_PFN_LOCK ** | PfnLock | ||
) |
Locks a guest virtual address.
This will actually lock the guest physical address to which Gva translates to, and place a swap hook on Gva page tables. If the page is not currently present, it will be locked when it will be made present.
[in] | Gva | Guest virtual address to lock. |
[out] | PfnLock | On success, will contain a pointer to the lock. May be NULL. |
Modifies the in-guest reference count of a physical page.
The counter is incremented or decremented with WIN_PFN_INC_VALUE.
When incrementing the counter, if the page is not in the WinPfnModifiedPage, WinPfnActivePage, WinPfnModifiedNowritePage, or WinPfnStandbyPage states the operation is refused.
We do not increment the counter if it the new value would be larger than WIN_PFN_REF_MAX.
When decrementing the counter, we do nothing if the value is already less than WIN_PFN_INC_VALUE.
[in] | PhysicalAddress | Physical address for which to modify the reference counter. |
[in] | Increment | True to increment the counter, False to decrement it. |
INT_STATUS_SUCCESS | in case of success. |
INT_STATUS_NOT_NEEDED_HINT | if the change is not needed. |
INT_STATUS_NOT_SUPPORTED | if the page is not in a state that supports the reference counter change. |
INT_STATUS_NOT_INITIALIZED | if the PFN entry for this page is not initialized. |
Definition at line 197 of file winpfn.c.
Referenced by IntWinPfnHandleTranslationChange(), IntWinPfnLockAddress(), IntWinPfnMoveLock(), IntWinPfnRemoveLock(), and IntWinPfnUnlockAddress().
|
static |
Moves a lock set for a guest virtual address when the page to which it translates to changes.
Since locks on virtual pages are in fact locks on the physical pages to which they translate to, when the translation changes we need to move the lock to the new page. This means that we must unlock the old page and lock the new one.
If the old physical address of the lock is 0 it means that the page is swapped in and we only have to set the lock on the new page.
If the new physical address is 0 it means that the page is swapped out and we only have to remove the lock from the old page.
[in,out] | PfnLock | The lock that must be moved. |
[in] | NewGpa | The new guest physical address that will receive the lock. |
Definition at line 390 of file winpfn.c.
Referenced by IntWinPfnHandleTranslationChange().
INTSTATUS IntWinPfnRemoveLock | ( | WIN_PFN_LOCK * | PfnLock, |
BOOLEAN | Force | ||
) |
Removes a PFN lock.
This will decrement the Introcore reference counter and only remove the lock when it reaches 0, unless a forced removal is requested.
[in,out] | PfnLock | Lock to remove. The pointer will no longer be valid after this function returns. |
[in] | Force | True to remove the lock even if the reference counter is not 0. |
INT_STATUS_SUCCESS | in case of success. |
INT_STATUS_NOT_NEEDED_HINT | if the reference counter has not reached 0 and Force is False. |
INT_STATUS_INVALID_PARAMETER_1 | if PfnLock is NULL. |
Definition at line 838 of file winpfn.c.
Referenced by IntWinPfnUnInit(), IntWinProcRemoveProcess(), and IntWinProcUnlockCr3().
void IntWinPfnUnInit | ( | void | ) |
Uninits the PFN locks.
If any locks are still active when this function is called, they will be forcibly removed using IntWinPfnRemoveLock.
Definition at line 922 of file winpfn.c.
Referenced by IntGuestUninit().
Unlocks a guest page.
Every IntWinPfnLockAddress call for an address must match a call to this function. If the Introcore reference counter reaches 0, it means that we also have to remove the lock from the guest, but only if it is a physical, not large, page. Also, any resources held by the lock are freed: the swap hook (if it exists) and the lock itself. It will also be removed from the gWinPfns list.
[in] | Address | Address to unlock. |
[in] | IsPhysical | True if Address is a guest physical address; False if it is a guest virtual address. |
INT_STATUS_SUCCESS | in case of success. |
INT_STATUS_INVALID_PARAMETER_2 | if Address is a guest virtual address and it does not point inside the kernel. |
INT_STATUS_NOT_FOUND | if no lock is found for Address. |
|
static |