|
Bitdefender Hypervisor Memory Introspection
|
Implements instrumentation for switch-case table access instructions. More...
#include "memtables.h"#include "guests.h"#include "icache.h"#include "memcloak.h"#include "ptfilter.h"#include "slack.h"Go to the source code of this file.
Functions | |
| static INTSTATUS | IntMtblRemoveEntry (PMEM_TABLE_RELOC Reloc) |
| Removes a mem-table entry. More... | |
| static INTSTATUS | IntMtblPatchInstruction (PMEM_TABLE_RELOC Reloc, PINSTRUX Instrux, PIG_ARCH_REGS Regs) |
| Relocate and instrument a switch-case load instruction. More... | |
| INTSTATUS | IntMtblCheckAccess (void) |
| Check if the current instruction is like a switch-case table access instruction. More... | |
| BOOLEAN | IntMtblIsPtrInReloc (QWORD Ptr, THS_PTR_TYPE Type, QWORD *Table) |
| Check if the given pointer is inside a mem-table relocation handler. More... | |
| void | IntMtblDisable (void) |
| Disables mem-table instructions instrumentation. More... | |
| BOOLEAN | IntMtblInsRelocated (QWORD Rip) |
| Check if the instruction at the provided RIP is instrumented. More... | |
| INTSTATUS | IntMtblRemoveAgentEntries (void) |
| Removes only the mem-table entries that were relocated inside the PT filter. More... | |
| INTSTATUS | IntMtblUninit (void) |
| Completely uninit the mem-tables, removing all the handlers from the NT slack space. More... | |
Variables | |
| static LIST_HEAD | gMemTables = LIST_HEAD_INIT(gMemTables) |
| List of memtables. More... | |
Implements instrumentation for switch-case table access instructions.
Mem-tables is a module used to instrument switch-case tables that are inserted by the compiler inside code pages. Sometimes, these switch-case tables end up being placed inside a page of memory which also contains a hooked API; pages which contain hooked APIs are monitored via EPT against reads, in order to hide the hooks from patch-guard, but if switch-case tables are also present inside those pages, a very high number of read EPT violations will be generated, leading to a very high performance impact. The way we mitigate this is by relocating all such instructions into the slack space of the NT image, and by replacing the memory access instruction with a sequence of instructions that load immediate values instead (the immediate values are the values that would normally be loaded from memory).
Definition in file memtables.c.
| INTSTATUS IntMtblCheckAccess | ( | void | ) |
Check if the current instruction is like a switch-case table access instruction.
This function checks if the current instruction (pointed by the RIP on the current VCPU) looks like an instruction which loads switch-case offset from a code-page. We look after the following features: 0. The instruction must be a MOV instruction;
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_NOT_NEEDED_HINT | If there's no need to instrument the instruction. |
| INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 401 of file memtables.c.
Referenced by IntHandleMemAccess().
| void IntMtblDisable | ( | void | ) |
Disables mem-table instructions instrumentation.
This function will remove all the hooks placed on mem-table like instructions, thus disabling the instrumentation. Note that the handlers will still remain, and if we have pointers still pointing there, nothing bad will happen. This function should be called only when preparing for uninit.
Definition at line 644 of file memtables.c.
Referenced by IntGuestPrepareUninit().
Check if the instruction at the provided RIP is instrumented.
| [in] | Rip | The RIP to be checked. |
| TRUE | if the RIP contains an instrumented instruction, FALSE otherwise. |
Definition at line 677 of file memtables.c.
Referenced by IntHandleEptViolation().
| BOOLEAN IntMtblIsPtrInReloc | ( | QWORD | Ptr, |
| THS_PTR_TYPE | Type, | ||
| QWORD * | Table | ||
| ) |
Check if the given pointer is inside a mem-table relocation handler.
| [in] | Ptr | The pointer to be checked. |
| [in] | Type | Pointer type - stack value or live RIP. |
| [out] | Table | Optional address to the relocation table, if any is found. |
| TRUE | If the pointer points within a relocation handler, FALSE otherwise. |
Definition at line 596 of file memtables.c.
Referenced by IntThrSafeIsLiveRIPInIntro(), and IntThrSafeIsStackPtrInIntro().
|
static |
Relocate and instrument a switch-case load instruction.
This function will re-write a switch-case load instruction using sequences of instruction which do not access memory (the page which is already read hooked, in particular). The rewriting algorithm relies on loading immediate values into the destination register instead of directly accessing the memory. Each instrumented instruction will contain a header, and a variable size region, with one entry for each value inside the switch-case table. Given a switch-case load instruction, say "MOV ecx, dword ptr [rdx+rax*4+0x4ea91c]", this is how we rewrite it:
For example, let's assume the following:
NOTE: the instruction has already been validated by the caller, so there's no need to do any check here. In order to see what validations/checks we do before we decide to relocate such an instruction, take a look at IntMtblCheckAccess. NOTE: this code will be written inside the guest while the VCPUs are paused. NOTE: after modifying the instruction, its entry inside the instruction-cache must be invalidated; if we don't do this, another VCPU that might have generated an exit from the same instruction might try to instrument it again, as decoding the current instruction would still see the old MOV cached, instead of seeing the newly patched JMP.
| [in,out] | Reloc | The mem-table relocation structure. |
| [in] | Instrux | Decoded instruction to be instrumented. |
| [in] | Regs | The general purpose registers. |
| INT_STATUS_SUCCESS | On success. |
| INT_STATUS_NOT_SUPPORTED | If the switch-case table has more than 16 entries. |
Definition at line 70 of file memtables.c.
Referenced by IntMtblCheckAccess().
| INTSTATUS IntMtblRemoveAgentEntries | ( | void | ) |
Removes only the mem-table entries that were relocated inside the PT filter.
When using the PT filter, many mem-table instructions may need to be instrumented. Since the NT sections slack space is very scarce, we will use, in that case, the PT filter itself in order to accommodate the relocated instructions. However, when the PT filter is unloaded, we also must stop instrumenting the instructions that were relocated inside of it.
| INT_STATUS_SUCCESS | On success. |
Definition at line 707 of file memtables.c.
Referenced by IntPtiDisableFiltering().
|
static |
Removes a mem-table entry.
This function completely removed a mem-table entry, by removing the hook established on the instrumented instruction, and by removing the handling code injected inside the NT slack space.
| [in] | Reloc | Mem-table relocation to be removed. |
| INT_STATUS_SUCCESS | On success. |
Definition at line 32 of file memtables.c.
Referenced by IntMtblPatchInstruction(), IntMtblRemoveAgentEntries(), and IntMtblUninit().
| INTSTATUS IntMtblUninit | ( | void | ) |
Completely uninit the mem-tables, removing all the handlers from the NT slack space.
This function must be called only during uninit, and only after thread-safeness was employed, in order to make sure no live RIPs or saved RIPs point inside a handler.
| INT_STATUS_SUCCESS | On success. |
Definition at line 745 of file memtables.c.
Referenced by IntGuestUninit().
|
static |
List of memtables.
Definition at line 12 of file memtables.c.