107 #define INVK_CTX_CACHE_SIZE 8 112 #define PTS_LEVEL_ROOT 6 113 #define PTS_LEVEL_PML5 5 114 #define PTS_LEVEL_PML4 4 115 #define PTS_LEVEL_PDP 3 116 #define PTS_LEVEL_PD 2 117 #define PTS_LEVEL_PT 1 159 return (4 == Entry->EntrySize) ? pageSizeS[Entry->Level - 1] : pageSizeL[Entry->Level - 1];
188 while (pivot != List)
194 pivot = pivot->
Blink;
198 pivot = pivot->
Flink;
221 while (list != &Entry->ContextEntries)
293 PINVOCATION_CONTEXT pInvk;
295 deny = pause =
FALSE;
304 list = Callbacks->
Flink;
305 while (list != Callbacks)
322 LOG(
"[PTS] Skipping calling the PTS callback for VA 0x%016llx\n", pInvk->
VirtualAddress);
334 ERROR(
"[ERROR] Callback failed: 0x%08x\n", status);
346 ERROR(
"[ERROR] IntHookPtsRemoveHook failed: 0x%08x\n", status);
399 QWORD newValue, oldValue;
416 newValue = oldValue = 0;
430 goto cleanup_and_exit;
439 goto cleanup_and_exit;
443 ERROR(
"[ERROR] IntHookPtwProcessWrite failed at %llx: 0x%08x\n", Address, status);
445 goto cleanup_and_exit;
450 goto cleanup_and_exit;
455 (0 == ((oldValue &
PT_P) + (newValue & PT_P))))
458 goto cleanup_and_exit;
466 ERROR(
"[ERROR] IntHookPtsHandleModification failed: 0x%08x\n", status);
483 ERROR(
"[ERROR] IntHookPtsInvokeCallbacks failed: 0x%08x\n", status);
489 TRACE(
"[PTS] Callback returned INT_STATUS_ACCESS_DENIED, will block the PT write.\n");
527 if ((NULL != Entry->PtPaHook) && Entry->PtPaHookSet)
533 ERROR(
"[ERROR] IntHookPtmRemoveHook failed: 0x%08x\n", status);
537 Entry->PtPaHookSet =
FALSE;
545 switch (Entry->Level)
617 pChild = &Hook->Header;
620 while ((NULL != pPt) && (decRefCount))
630 ERROR(
"[ERROR] IntHookPtsRemovePteHook failed: 0x%08x\n", status);
695 ERROR(
"[ERROR] IntHookPtmDeleteHook failed: 0x%08x\n", status);
738 ERROR(
"[ERROR] IntHookPtDeleteParents failed for level %d: 0x%08x\n", Hook->Level + 1, status);
741 Hook->Header.ParentHook = NULL;
748 ERROR(
"[ERROR] IntHookPtDeletePdHook failed: 0x%08x\n", status);
781 ERROR(
"[ERROR] IntHookPtsDeleteParents failed: 0x%08x\n", status);
814 list = listHead->
Flink;
815 while (list != listHead)
856 if (Entry->PtPaHookSet && (NULL != Entry->PtPaHook))
861 ERROR(
"[ERROR] IntHookPtmRemoveHook failed: 0x%08x\n", status);
865 Entry->PtPaHookSet =
FALSE;
866 Entry->PtPaAddress = 0;
892 if (Entry->PtPaHookSet && (NULL != Entry->PtPaHook))
894 if (Entry->PtPaAddress != NewPtPaAddress)
899 ERROR(
"[ERROR] IntHookPtmRemoveHook failed: 0x%08x\n", status);
917 ERROR(
"[ERROR] IntHookPtmSetHook failed: 0x%08x\n", status);
922 Entry->PtPaHookSet =
TRUE;
924 Entry->PtPaAddress = NewPtPaAddress;
952 ERROR(
"[ERROR] IntHookPtDisableEntry failed: 0x%08x\n", status);
959 ERROR(
"[ERROR] IntHookPtsEnableEntry failed: 0x%08x\n", status);
990 list = Entry->ChildrenEntries.
Flink;
991 while (list != &Entry->ChildrenEntries)
1003 ERROR(
"[ERROR] IntHookPtsMergeEntry failed: 0x%08x\n", status);
1008 if (Entry->RefCount > 0)
1014 ERROR(
"[ERROR] Entry %p has refcount 0!\n", Entry);
1021 if (MergeRoot == Entry)
1026 list = Entry->ContextEntries.
Flink;
1027 while (list != &Entry->ContextEntries)
1044 MergeRoot->RefCount++;
1047 pPts->
Parent = MergeRoot;
1051 if (0 != Entry->RefCount)
1053 ERROR(
"[ERROR] Entry %p refCount is %d after entry merging!\n", Entry, Entry->RefCount);
1062 ERROR(
"[ERROR] IntHookPtRemovePteHook failed: 0x%08x\n", status);
1127 QWORD curValue, newValue;
1128 BOOLEAN curValid, newValid, curPse, newPse, pseChanged;
1132 curValue = OldValue;
1133 newValue = NewValue;
1135 curValid = (0 != (curValue & 1));
1136 newValid = (0 != (newValue & 1));
1139 if (!curValid && !newValid)
1148 if (Entry->Level != 1)
1150 curPse = (0 != (Entry->IsPs));
1151 newPse = (0 != (newValue &
PD_PS));
1155 curPse = newPse =
FALSE;
1161 curPse = newPse =
FALSE;
1164 pseChanged = (newValid && (curPse != newPse));
1167 if (newValid && ((!Entry->IsLeaf && !pseChanged) || (Entry->IsLeaf && curPse && !newPse)))
1179 DWORD offsetsCount, index;
1180 QWORD offsets[8] = { 0 };
1185 memzero(cache,
sizeof(cache));
1193 list = Entry->ContextEntries.
Flink;
1194 while (list != &Entry->ContextEntries)
1197 QWORD childPtPaAddress, offset;
1206 level = (
BYTE)(offsetsCount - Entry->Level + 1);
1208 offset = offsets[level];
1209 index = (
DWORD)(offset / Entry->EntrySize);
1226 Entry->EntrySize | ((Entry->Level - 1) << 8), Entry, &pPt);
1229 ERROR(
"[ERROR] IntHookPtCreateEntry failed for %llx: 0x%08x\n", childPtPaAddress, status);
1237 if (Entry->RefCount > 0)
1243 ERROR(
"[ERROR] Entry %p refCount is zero!\n", Entry);
1259 else if (newValid && !curPse && newPse)
1271 ERROR(
"[ERROR] IntHookPtMergeEntry failed: 0x%08x\n", status);
1277 ERROR(
"[ERROR] Just merged entry %108p, but the ChildrenList is not empty!\n", Entry);
1283 list = Entry->ChildrenEntries.
Flink;
1284 while (list != &Entry->ChildrenEntries)
1287 QWORD oldChildValue, newChildValue, newPtPaAddress;
1301 ERROR(
"[ERROR] IntHookPtsDisableEntry failed: 0x%08x\n", status);
1325 ERROR(
"[ERROR] IntHookPtsEnableEntry failed: 0x%08x\n", status);
1334 ERROR(
"[ERROR] IntHookPtsRemapEntry failed: 0x%08x\n", status);
1345 if (newValid && !newPse)
1350 ERROR(
"[ERROR] IntGpaCacheFetchAndAdd failed: 0x%08x\n", status);
1364 ERROR(
"[ERROR] IntHookPtsHandleModification failed: 0x%08x\n", status);
1371 Entry->IsValid = newValid;
1375 Entry->IsPs = newPse;
1377 Entry->IsLeaf = (Entry->IsPs) || (1 == Entry->Level);
1433 pPt->
EntrySize = EntrySizeAndLevel & 0xFF;
1434 pPt->
Level = EntrySizeAndLevel >> 8;
1477 ERROR(
"[ERROR] IntHookPtmSetHook failed: 0x%08x\n", status);
1480 goto cleanup_and_exit;
1494 ERROR(
"[ERROR] IntGpaCacheFetchAndAdd failed for 0x%016llx: 0x%08x\n", pPt->
PtPaAddress, status);
1497 goto cleanup_and_exit;
1570 QWORD pml5eAddress, pml4eAddress, pdpeAddress, pdeAddress, pteAddress;
1578 if (NULL == Callback)
1589 pml5eAddress = pml4eAddress = pdpeAddress = pdeAddress = pteAddress = 0;
1590 root = pml4 = pdp = pd = pt = pf = NULL;
1604 ERROR(
"[ERROR] Kernel mapping 0x%016llx hook set inside non-system CR3 0x%016llx!\n", VirtualAddress, Cr3);
1664 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1666 goto cleanup_and_exit;
1682 if (0 != pml5eAddress)
1691 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1693 goto cleanup_and_exit;
1718 if (0 != pml4eAddress)
1727 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1729 goto cleanup_and_exit;
1755 if (0 != pdpeAddress)
1766 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1768 goto cleanup_and_exit;
1777 if ((0 != (pdpeValue &
PDP_PS)) && (0 != (pdpeValue &
PDP_P)))
1804 if (0 != pdeAddress)
1815 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1817 goto cleanup_and_exit;
1826 if ((0 != (pdeValue &
PDP_PS)) && (0 != (pdeValue &
PDP_P)))
1856 if (0 != pteAddress)
1865 ERROR(
"[ERROR] IntHookPtsCreateEntry failed: 0x%08x\n", status);
1867 goto cleanup_and_exit;
1914 ERROR(
"[ERROR] IntHookPtsRemoveHookInternal failed: 0x%08x\n", status2);
1925 else if (NULL != pf)
1978 ERROR(
"[ERROR] IntHookPtsRemoveHookInternal failed: 0x%08x\n", status);
2027 ERROR(
"[ERROR] IntHookPtsDeleteHookInternal failed: 0x%08x\n", status);
2052 list = ListHead->
Flink;
2053 while (list != ListHead)
2069 ERROR(
"[ERROR] IntHookPtsDeletePdHook failed: 0x%08x\n", status);
2074 WARNING(
"[WARNING] Unknown state for the hook at %p, flags %08x!\n", pPt, pPt->
Header.
Flags);
2124 ERROR(
"[ERROR] IntHookPtsDeleteHookInternal failed: 0x%08x\n", status);
2129 ERROR(
"[ERROR] Unknown hook state for hook %p, flags %08x\n", pPts, pPts->
Header.
Flags);
2138 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2145 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2152 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2159 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2166 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2173 ERROR(
"[ERROR] IntHookPtCleanupList failed: 0x%08x\n", status);
2229 Entry->WriteState.CurEntry = OldValue;
2293 TRACE(
"[ERROR] IntTranslateVirtualAddressEx failed for 0x%016llx with Cr3 0x%016llx: 0x%08x\n",
2330 LOG(
"[PTS INTEGRITY] Translation modification for VA 0x%016llx in CR3 0x%016llx: old = 0x%016llx " 2331 "new = 0x%016llx old size = 0x%016llx new size = 0x%016llx\n",
2360 WARNING(
"[WARNING] Failed to get originator on translation violation, RIP: %llx\n",
2373 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
2409 for (i = 0; i < (
DWORD)(5 - Entry->Level); i++)
2416 NLOG(
"Level %d, Entry %p, PTE at 0x%016llx, refcount %d, Cur 0x%016llx, Int 0x%016llx, " 2417 "Real 0x%016llx, IsValid %d, IsPs %d, IsLeaf %d\n",
2418 Entry->Level, Entry, Entry->PtPaAddress, Entry->RefCount, Entry->WriteState.CurEntry,
2419 Entry->WriteState.IntEntry, x, Entry->IsValid, Entry->IsPs, Entry->IsLeaf);
2421 list = Entry->ContextEntries.
Flink;
2422 while (list != &Entry->ContextEntries)
2428 for (i = 0; i < (
DWORD)(5 - Entry->Level); i++)
2433 NLOG(
" -> Context %p, Flags 0x%08x, Context callback %p, callback context %p, VA 0x%016llx\n",
2437 list = Entry->ChildrenEntries.
Flink;
2438 while (list != &Entry->ChildrenEntries)
2473 NLOG(
"-------------------------------------------------------------\n");
#define INT_STATUS_ACCESS_DENIED
#define INT_STATUS_PAGE_NOT_PRESENT
Indicates that a virtual address is not present.
INTSTATUS IntHookPtmRemoveHook(HOOK_PTM **Hook, DWORD Flags)
Remove a page-table hook handle.
static void IntHookPtsCloneCallbacks(PHOOK_PTS_ENTRY Entry)
Clone a list of callbacks locally, so they can be safely invoked.
#define CONTAINING_RECORD(List, Type, Member)
LIST_HEAD RemovedHooksPdpList
List of removed page-directory pointer entry hooks.
void * Context
User-defined data that will be supplied to the callback.
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
DWORD Size
The size of the access.
INTSTATUS IntHookPtsWriteEntry(PHOOK_PTS_ENTRY Entry, QWORD OldValue, QWORD NewValue)
Tests the translation modification handler.
BYTE EntrySize
4 (32 bit paging) or 8 (PAE or 64 bit paging)
#define HOOK_PTS_FLG_DELETE_PT_HOOK
INTSTATUS IntPhysicalMemRead(QWORD PhysicalAddress, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest physical memory range, but only for a single page.
#define THS_CHECK_PTFILTER
Will check if any RIP is inside the PT filter agent.
static DWORD gInvkCtxIndex
LIST_ENTRY Link
List element.
QWORD OldEntry
Previous page-table entry.
LIST_HEAD HooksRootList[HOOK_PT_HASH_SIZE]
Hash of monitored virtual address spaces.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
#define CLEAN_PHYS_ADDRESS64(x)
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
struct _INVOCATION_CONTEXT * PINVOCATION_CONTEXT
static INTSTATUS IntHookPtsRemoveHookInternal(PHOOK_PTS Hook, DWORD Flags)
Remove a PTS hook.
QWORD NewValue[8]
The written value. Only the first Size bytes are valid.
LIST_ENTRY PtsLink
Link inside the HooksPtsList.
Measures page tables integrity checks.
#define IntEnterDebugger()
LIST_HEAD ChildrenEntries
Children entries. Will be empty for leafs. Each entry is a HOOK_PTS_ENTRY.
struct _LIST_ENTRY * Flink
struct _HOOK_PTS_ENTRY * PHOOK_PTS_ENTRY
#define INT_SUCCESS(Status)
static INTSTATUS IntHookPtsDeleteParents(PHOOK_PTS_ENTRY Hook, DWORD Flags)
Permanently deletes all PTM hooks of a page-table entry hook.
#define HOOK_FLG_DISABLED
If flag is set, the hook is disabled, therefore ignored on EPT violations.
static BOOLEAN IsListEmpty(const LIST_ENTRY *ListHead)
static INTSTATUS IntHookPtsInvokeCallbacks(LIST_HEAD *Callbacks)
Invoke all the callbacks from a given list.
PHOOK_PTS Hook
The PTS hook associated with the modified address.
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
QWORD OldPageSize
Previous page size.
The action was not allowed because there was no reason to allow it.
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
DWORD WrittenMask
Bit mask indicating which bytes inside the page-table entry have been written.
INTRO_VIOLATION_HEADER Header
The alert header.
QWORD NewPageSize
New page size.
QWORD Cr3
Virtual address space where the address is monitored.
#define HOOK_PT_HASH_ID(x)
struct _EVENT_TRANSLATION_VIOLATION::@301 Victim
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.
#define INT_STATUS_NOT_NEEDED_HINT
LIST_HEAD RemovedHooksPml4List
List of removed PML4 entry hooks.
static INTSTATUS IntHookPtsEnableEntry(PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress)
Enable a page-table entry hook.
KERNEL_DRIVER * Driver
The driver that's modifying the memory.
#define HpAllocWithTag(Len, Tag)
BOOLEAN IsPs
True if this entry is a page size extension, and points to a 2M/4M/1G page.
int INTSTATUS
The status data type.
QWORD VirtualAddress
The Virtual Address whose translation is being modified.
HOOK_STATE * gHooks
Global hooks state.
static INVOCATION_CONTEXT gInvkCtxStatic[INVK_CTX_CACHE_SIZE]
Event structure for illegal paging-structures modifications.
QWORD Rip
The value of the guest RIP register when the event was generated.
Describes a kernel-mode originator.
#define HOOK_PT_PAE_ROOT_HASH_ID(x)
static INTSTATUS IntHookPtsCreateEntry(QWORD PtPaAddress, WORD EntrySizeAndLevel, PHOOK_PTS_ENTRY Parent, PHOOK_PTS_ENTRY *Entry)
Creates a new page-table entry hook structure.
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
EVENT_TRANSLATION_VIOLATION Translation
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
static INTSTATUS IntHookPtsRemapEntry(PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress)
Remap a page-table entry to a new value.
Measures page table entries writes.
INTSTATUS IntThrSafeCheckThreads(QWORD Options)
Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of c...
LIST_HEAD HooksPtsList
List of swap hooks.
static QWORD IntHookPtsGetPageSize(PHOOK_PTS_ENTRY Entry)
Computes the page size of a PTS entry.
QWORD CurPageSize
Current page size.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
#define HOOK_FLG_HIGH_PRIORITY
If flag is set, the callback associated to this hook will have a higher priority than the others...
#define HOOK_FLG_PT_UM_ROOT
If flag is set, the hook is set on the root paging structure, and only the low, user-mode entires are...
static void IntHookAddCallbackToList(PLIST_HEAD List, PHOOK_PTS Context)
Adds a callback to the provided list.
static __inline INTSTATUS IntHookPtsCleanupList(LIST_HEAD *ListHead)
Commits a list of page-table entry hooks.
TRANS_VIOLATION_TYPE ViolationType
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
#define HOOK_FLG_PAGING_STRUCTURE
If flag is set, the hook is set on paging structures.
BOOLEAN IntegrityCheckFailed
True if integrity checks failed on this translation.
BYTE HookType
The type of the hook structure (see _HOOK_TYPE)
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
#define ALERT_FLAG_BETA
If set, the alert is a BETA alert. No action was taken.
GENERIC_ALERT gAlert
Global alert buffer.
INTSTATUS IntSplitVirtualAddress(QWORD VirtualAddress, DWORD *OffsetsCount, QWORD *OffsetsTrace)
Split a linear address into page-table indexes.
BOOLEAN Static
True if this entry was not dynamically allocated (it doesn't have to be freed).
#define INT_STATUS_CANNOT_UNLOAD
Indicates that Introcore can not unload in a safely manner.
#define HOOK_FLG_GLOBAL_MASK
Global flags must be defined here and must be handled by each hooks layer (even if it ignores them...
BOOLEAN PtFilterEnabled
If True, the in-guest PT filter is enabled and deployed.
#define CLEAN_PHYS_ADDRESS32PAE_ROOT(x)
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
QWORD MappingsEntries[MAX_TRANSLATION_DEPTH]
Contains the entry in which paging table.
WORD EntryOffset
Entry offset inside the monitored page-table.
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
QWORD NewEntry
New PT entry.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
INTSTATUS IntGpaCacheFetchAndAdd(PGPA_CACHE Cache, QWORD Gpa, DWORD Size, PBYTE Buffer)
Fetch data from a cached entry, or add it to the cache, of not already present.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
LIST_HEAD RemovedHooksPtList
List of removed page-table entry hooks.
QWORD CurEntry
Current page-table entry.
void * ParentHook
The parent hook. For a GPA hook, for example, a GVA hook or a PagedHook will be the parent hook...
#define HOOK_FLG_CHAIN_DELETE
If flag is set, then we won't remove the hook on commit phase; we'll let the parent hook handle the d...
void * GpaCache
The currently used GPA cache.
#define INT_STATUS_INVALID_PARAMETER_4
INTSTATUS IntHookPtmDeleteHook(HOOK_PTM **Hook, DWORD Flags)
Permanently delete a page-table hook handle.
INTRO_WRITE_INFO WriteInfo
The original and new address to which VirtualAddress translates.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
#define HOOK_PTS_FLG_DELETE_PD_HOOK
HOOK_HEADER Header
Hook header - must be present for every hook.
#define HpFreeAndNullWithTag(Add, Tag)
HOOK_HEADER Header
Hook header - must be present for every hook.
#define INT_STATUS_INVALID_INTERNAL_STATE
Sent for virtual address translation alerts. See EVENT_TRANSLATION_VIOLATION.
INTSTATUS(* PFUNC_SwapCallback)(void *Context, QWORD VirtualAddress, QWORD OldEntry, QWORD NewEntry, QWORD OldPageSize, QWORD NewPageSize)
Callback invoked on translation modifications.
static void InsertAfterList(LIST_ENTRY *Pivot, LIST_ENTRY *Item)
void IntAlertFillWinProcessCurrent(INTRO_PROCESS *EventProcess)
Saves information about the current Windows process inside an alert.
Measures page table writes that are actually relevant for Introcore.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
DWORD RefCount
Number of references.
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
QWORD PtPaAddress
Physical address of the PT/PD/PDP/PML4/PML5 entry associated to this particular page.
INTSTATUS IntHookPtsRemoveHook(HOOK_PTS **Hook, DWORD Flags)
Remove a PTS hook.
BOOLEAN HooksRemoved
True if any hook has been removed.
static INTSTATUS IntHookPtsWriteCallback(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Page-table modification handler.
LIST_HEAD ContextEntries
The actual contexts. Each context will be a HOOK_PTS structure.
static INTSTATUS IntHookPtsDisableEntry(PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress, QWORD NewPteValue)
Disable a page-table entry hook.
static void InitializeListHead(LIST_ENTRY *ListHead)
INTSTATUS IntHookPtsDeleteHook(HOOK_PTS **Hook, DWORD Flags)
Permanently delete the PTS hook.
LIST_HEAD RemovedHooksPtsList
List of removed PTS entries.
#define UNREFERENCED_PARAMETER(P)
QWORD OldEntry
Old PT entry.
INTSTATUS IntHookPtsCheckIntegrity(void)
Checks the integrity of the existing page-table hooks. Used for debugging the PT filter.
#define CLEAN_PHYS_ADDRESS32(x)
enum _INTRO_ACTION INTRO_ACTION
Event actions.
QWORD CurEntry
Current page-table entry value.
INTSTATUS IntHookPtsCommitHooks(void)
Commit all PTS hook modifications.
PHOOK_PTS_ENTRY Parent
The leaf page-table entry hook associated with this address.
QWORD OldValue[8]
The original value. Only the first Size bytes are valid.
BOOLEAN PtPaHookSet
True if a hook is placed on the PT entry.
#define IntDbgEnterDebugger()
static INTSTATUS IntHookPtsDumpPtsEntry(HOOK_PTS_ENTRY const *Entry)
Prints a HOOK_PTS_ENTRY structure.
PFUNC_SwapCallback Callback
Swap callback.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
INTRO_MODULE Module
The module that modified the translation.
GUEST_STATE gGuest
The current guest state.
void IntHookPtsDump(void)
Prints all the page table hooks.
BOOLEAN IsValid
This referrers to the entry contained by this PTE. If true, it points to a valid table.
PFUNC_EptViolationCallback Callback
Write callback to be called for the modification.
LIST_HEAD RemovedHooksPdList
List of removed page-directory entry hooks.
#define ALERT_FLAG_FEEDBACK_ONLY
If set, the alert is a feedback only alert.
INTSTATUS IntHookPtsInit(void)
Initializes the PTS hooks system.
BYTE Level
Page table level (1 - PT, 5 - PML5)
struct _INVOCATION_CONTEXT INVOCATION_CONTEXT
QWORD PageSize
The page size used for this translation.
#define INT_STATUS_PARTIAL_WRITE
LIST_HEAD RemovedHooksPml5List
List of removed PML5 entry hooks.
#define THS_CHECK_ONLY
Will check for safeness, without moving any RIP or stack value.
struct _EXCEPTION_KM_ORIGINATOR::@64 Original
INTRO_ACTION Action
The action that was taken as the result of this alert.
#define INT_STATUS_NO_MAPPING_STRUCTURES
Indicates that not all mapping structures of a virtual address are present.
HOOK_PTEWS WriteState
Write state.
LIST_ENTRY Link
List element entry.
PAGING_MODE Mode
The paging mode used by the guest.
LIST_HEAD * CallbacksList
List of callbacks.
#define HOOK_PTS_MONITORED_BITS
HOOK_PTS_STATE PtsHooks
PTS hooks state (public page-table monitoring).
static INTSTATUS IntHookPtsDeleteHookInternal(PHOOK_PTS Hook, DWORD Flags)
Permanently deletes a PTS hook.
#define INT_STATUS_NOT_INITIALIZED_HINT
Encapsulates information about a virtual to physical memory translation.
static INTSTATUS IntHookPtsRemovePteHook(PHOOK_PTS_ENTRY Entry, DWORD Flags)
Remove a page table entry hook.
struct _EVENT_TRANSLATION_VIOLATION::@300 Originator
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
INTRO_PROCESS CurrentProcess
The current process.
struct _LIST_ENTRY * Blink
QWORD OldPageSize
Old page size.
LIST_ENTRY Link
Link inside the containing list.
INTSTATUS IntHookPtmSetHook(QWORD Address, PFUNC_EptViolationCallback Callback, void *Context, void *ParentHook, DWORD Flags, PHOOK_PTM *Hook)
Set a hook on a page-table.
PFUNC_SwapCallback Callback
The swap callback.
Used by page-table hooks.
void * Context
Context to be passed to the Callback.
QWORD VirtualAddress
Virtual address whose translation is being modified.
DWORD Flags
Generic flags. Check out EPT Hook flags.
static INTSTATUS IntHookPtsHandleModification(PHOOK_PTS_ENTRY Entry, QWORD OldValue, QWORD NewValue)
Handle a modification inside a page-table entry.
#define INVK_CTX_CACHE_SIZE
LIST_HEAD RemovedHooksRootList
List of removed root entries.
static INTSTATUS IntHookPtsMergeEntry(PHOOK_PTS_ENTRY MergeRoot, PHOOK_PTS_ENTRY Entry)
Merge multiple entries into a single one.
void IntAlertFillWinKmModule(const KERNEL_DRIVER *Driver, INTRO_MODULE *EventModule)
Saves kernel module information inside an alert.
#define INT_STATUS_REMOVE_HOOK_ON_RET
Can be used by hook callbacks in order to signal that the hook should be removed. ...
static INTSTATUS IntHookPtsControlEntry(PHOOK_PTS_ENTRY Entry, QWORD NewPtPaAddress, QWORD NewPteValue)
Handle control bits modifications inside a page-table entry.
QWORD VirtualAddress
The monitored virtual address.
static PHOOK_PTS_ENTRY IntHookPtsFindEntry(LIST_HEAD *ListHead, QWORD PhysicalAddress)
Finds an already existing page-table entry hook on a given physical address.
INTSTATUS IntExceptKernelGetOriginator(EXCEPTION_KM_ORIGINATOR *Originator, DWORD Options)
This function is used to get the information about the kernel-mode originator.
#define HOOK_PT_HASH_SIZE
static INTSTATUS IntHookPtsDeletePdHook(PHOOK_PTS_ENTRY Hook, DWORD Flags)
Permanently deletes a page-table entry hook.
Used by an internal page monitored using PTS.
#define HOOK_FLG_REMOVE
If flag is set, the hook has been removed, and waits the next commit to be actually deleted...
#define HOOK_FLG_PAE_ROOT
INTSTATUS IntHookPtwProcessWrite(PHOOK_PTEWS WriteState, QWORD Address, BYTE EntrySize, QWORD *OldValue, QWORD *NewValue)
Processes a page-table write, returning the old and the new page-table entry value.
#define INT_STATUS_INVALID_PARAMETER_7
A translation was modified without us intercepting it. This points to a bug in Introcore.
#define INT_STATUS_INSUFFICIENT_RESOURCES
#define INT_STATUS_INVALID_PARAMETER_3