Bitdefender Hypervisor Memory Introspection
|
Handles in-guest memory allocations. More...
Go to the source code of this file.
Data Structures | |
struct | _SLACK_SPACE |
Macros | |
#define | for_each_slack(_var_name) list_for_each(gSlackAllocations, SLACK_SPACE, _var_name) |
Typedefs | |
typedef struct _SLACK_SPACE | SLACK_SPACE |
typedef struct _SLACK_SPACE * | PSLACK_SPACE |
Functions | |
static INTSTATUS | IntSlackSendIntegrityAlert (QWORD VirtualAddress, DWORD Size, BYTE Value) |
Sends an integrity alert if the slack buffer not 0-filled/NOP-filled. More... | |
static INTSTATUS | IntSlackAllocWindows (BOOLEAN Pageable, QWORD ModuleBase, DWORD Size, QWORD *Buffer, QWORD SecHint) |
Allocate memory inside the guest. More... | |
static INTSTATUS | IntSlackAllocLinux (DWORD Size, QWORD *Buffer) |
Allocate slack space on Linux. More... | |
INTSTATUS | IntSlackAlloc (QWORD ModuleBase, BOOLEAN Pageable, DWORD Size, QWORD *Buffer, QWORD SecHint) |
Allocate slack inside the guest. More... | |
INTSTATUS | IntSlackFree (QWORD Buffer) |
Free slack space. More... | |
void | IntSlackUninit (void) |
Uninit the slack system. Must be called only during uninit. More... | |
Variables | |
static LIST_HEAD | gSlackAllocations = LIST_HEAD_INIT(gSlackAllocations) |
Handles in-guest memory allocations.
This module deals with in-guest memory allocations. However, it can only allocate guest memory inside the padding area located at the end of MZ/PE sections (Windows) or inside the first 2 pages of the kernel image (Linux). We call this unused space "slack". Generally, this is available because sections rarely use the entire last page, but, because section alignment is usually equal to the size of a page (4K), this leaves some unused space we can claim. For example, if the .text section of the NT image has a virtual size of 0x329838 bytes, this leaves 0x1000 - 0x838 = 0x7C8 (1992) bytes unused inside the last page of the section. (assuming regular 0x1000 section alignment). This is more than enough for our current use-cases. NOTE: Patch-guard protects the sections slack space (it should be filled with zeros). Because of this, when allocating slack space and writing data inside it, make sure you use memcloak in order to hide the written contents, so as to when PatchGuard reads that area, zeros are returned instead.
Definition in file slack.c.
#define for_each_slack | ( | _var_name | ) | list_for_each(gSlackAllocations, SLACK_SPACE, _var_name) |
Definition at line 56 of file slack.c.
Referenced by IntSlackAllocWindows(), IntSlackFree(), and IntSlackUninit().
typedef struct _SLACK_SPACE * PSLACK_SPACE |
typedef struct _SLACK_SPACE SLACK_SPACE |
One slack allocation.
INTSTATUS IntSlackAlloc | ( | QWORD | ModuleBase, |
BOOLEAN | Pageable, | ||
DWORD | Size, | ||
QWORD * | Buffer, | ||
QWORD | SecHint | ||
) |
Allocate slack inside the guest.
Please see the description of the IntSlackAllocWindows function for Windows, and IntSlackAllocLinux for Linux. This function is just a wrapper for them.
[in] | Pageable | If true, the slack space can be allocated inside a pageable section. |
[in] | ModuleBase | The kernel module in which we wish to allocate slack space. |
[in] | Size | Size to be allocated. |
[out] | Buffer | Will contain, upon successful return, the guest virtual address of the allocated slack buffer inside the given module. |
[in] | SecHint | Optional section hint - if provided (non-zero), slack will be allocated inside the given section (note that this is a section name, not index). |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails or if enough slack space was not found inside the given module. |
Definition at line 437 of file slack.c.
Referenced by IntDetSetHook(), IntLixAgentAllocate(), IntMtblPatchInstruction(), IntSwapgsInstallHandler(), IntWinAgentInjectTrampoline(), and IntWinAgentSelectBootstrapAddress().
Allocate slack space on Linux.
On Linux we don't have space between sections since they aren't aligned. But we do have the first two pages where there should be hypercall_page and theoretically there should be enough space.
[in] | Size | Size of the buffer to be allocated. |
[out] | Buffer | Guest virtual address of the allocated buffer. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails or if enough slack space was not found inside the given module. |
Definition at line 328 of file slack.c.
Referenced by IntSlackAlloc().
|
static |
Allocate memory inside the guest.
This function will iterate through all the non-discardable, non-writable, executable sections of module pointed by ModuleBase, and it will search padding areas, between sections, after the virtual size of the given section. Inside this padding area, we can store Introcore specific data. NOTE: This function takes into considerations other code injections that may have been previously done. It will iterate through the list of currently allocated slacks, in order to ensure that it will never return an address that would lead to the corruption of already injected code/data chunks. NOTE: Slack space is a very limited resource (expect roughly a few kilobytes of it to be available inside the NT image, for example), so use it wisely. The main use-cases for the slack space are:
[in] | Pageable | If true, the slack space can be allocated inside a pageable section. |
[in] | ModuleBase | The kernel module in which we wish to allocate slack space. |
[in] | Size | Size to be allocated. |
[out] | Buffer | Will contain, upon successful return, the guest virtual address of the allocated slack buffer inside the given module. |
[in] | SecHint | Optional section hint - if provided (non-zero), slack will be allocated inside the given section (note that this is a section name, not index). |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails or if enough slack space was not found inside the given module. |
Definition at line 124 of file slack.c.
Referenced by IntSlackAlloc().
Free slack space.
Will free the given buffer allocated inside a loaded modules' slack space.
[in] | Buffer | The allocate slack address. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_FOUND | If the given slack was not found among the valid allocations. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is used. |
Definition at line 499 of file slack.c.
Referenced by IntDetRemoveHandler(), IntLixAgentFree(), IntWinAgentInjectTrampoline(), and IntWinAgentReleaseBootstrapAddress().
Sends an integrity alert if the slack buffer not 0-filled/NOP-filled.
[in] | VirtualAddress | The beginning guest virtual address of the slack memory region. |
[in] | Size | The size of the slack memory region. |
[in] | Value | The first value that is not equal to zero. |
INT_STATUS_SUCCESS | On success. |
Definition at line 60 of file slack.c.
Referenced by IntSlackAllocLinux(), and IntSlackAllocWindows().
void IntSlackUninit | ( | void | ) |
Uninit the slack system. Must be called only during uninit.
Definition at line 536 of file slack.c.
Referenced by IntGuestUninit().
|
static |