15 #include "winagent_ptdriver_x64.h" 56 #define MAX_ENTRIES_PER_BUCKET 256 57 #define MAX_LUT_PAGES 64 58 #define MAX_HANDLER_SIZE 48ull 59 #define TABLE_BUCKET_MASK 0x3F 141 else if (p1->
Gla > p2->
Gla)
187 _Inout_ PPTI_CANDIDATE Candidate
195 if (NULL != Candidate->CloakHandle)
202 Candidate->CloakHandle = NULL;
238 DWORD i, vi, count, seci, pagei;
239 BYTE int3[16] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
242 PBYTE pPage1, pPage2;
245 pPage1 = pPage2 = NULL;
249 for (seci = 0; ; seci++)
268 if (0 != memcmp(sec.
Name,
".text", 5))
274 memcpy(secname, sec.
Name, 8);
277 TRACE(
"[PTCORE] Parsing section '%s'...\n", secname);
286 for (pagei = 0; pagei < pageCount; ++pagei)
298 ERROR(
"ERROR] Failed mapping page %d of section %d: 0x%08x\n", pagei, seci, status);
299 goto cleanup_and_exit;
305 while (i < sizeToParse)
308 NDSTATUS ndstatus = NdDecodeEx(&instrux,
313 if (ND_STATUS_BUFFER_TOO_SMALL == ndstatus)
315 BYTE buffer[16] = { 0 };
322 ERROR(
"ERROR] Failed mapping page %d of section %d: 0x%08x\n", pagei, seci, status);
323 goto cleanup_and_exit;
326 memcpy(buffer, pPage1 + i, sizeToParse - i);
327 memcpy(buffer + sizeToParse - i, pPage2, 16 - (sizeToParse - i));
355 if (instrux.Instruction == ND_INS_MOV ||
356 instrux.Instruction == ND_INS_XCHG ||
357 (instrux.Instruction == ND_INS_CMPXCHG && instrux.HasLock))
359 if (instrux.Operands[0].Type == ND_OP_MEM && instrux.Operands[0].Size == 8 &&
360 instrux.Operands[0].Info.Memory.HasBase && !instrux.Operands[0].Info.Memory.HasIndex &&
361 instrux.Operands[0].Info.Memory.Base != NDR_RSP &&
362 (!instrux.HasDisp || ((instrux.Displacement < 0x20) && (instrux.Displacement % 8 == 0))) &&
363 ((instrux.Operands[1].Type == ND_OP_REG) || ((instrux.Operands[1].Type == ND_OP_IMM) &&
364 (instrux.Operands[1].Info.Immediate.Imm == 0))) &&
371 goto cleanup_and_exit;
374 pPtc->
Gla = target + i;
376 memcpy(&pPtc->
Instruction, &instrux,
sizeof(instrux));
389 ERROR(
"[ERROR] IntMemClkCloakRegion failed: 0x%08x\n", status);
391 goto cleanup_and_exit;
396 memcpy(pPage1 + i, int3, instrux.Length);
400 memcpy(pPage1 + i, int3, sizeToParse - i);
401 memcpy(pPage2, int3, instrux.Length - (sizeToParse - i));
407 ERROR(
"[ERROR] RbInsertNode failed: 0x%08x\n", status);
409 goto cleanup_and_exit;
435 TRACE(
"[PTCORE] Patched %d instructions in section '%s'!\n", count, secname);
471 for (
LIST_ENTRY *list = gPtiCandidatesList.
Flink; list != &gPtiCandidatesList; )
488 PPTI_CANDIDATE Candidate
524 Candidate->
Instruction.Operands[0].Info.Memory.Disp;
525 BYTE int20[16] = { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCD, 0x14 };
531 enum { ptNone, ptSelfMap, ptTranslatesToPt, ptWritesPte } criteria = ptNone;
542 criteria = ptSelfMap;
545 #define REG(r) (*(&gVcpu->Regs.Rax + (r))) 554 gla =
REG(Candidate->Instruction.Operands[0].Info.Memory.Base) +
555 Candidate->Instruction.Operands[0].Info.Memory.Disp;
562 if (NULL != pageEntry)
565 relevant = pageEntry->
PtCount != 0;
566 criteria = ptTranslatesToPt;
577 if (ND_OP_REG == Candidate->Instruction.Operands[1].Type)
579 newval =
REG(Candidate->Instruction.Operands[1].Info.Register.Reg);
581 else if (ND_OP_IMM == Candidate->Instruction.Operands[1].Type)
583 newval = Candidate->Instruction.Operands[1].Info.Immediate.Imm;
594 if (((newval & 0xFFF) == 0x863 || (newval & 0xFFF) == 0x063 ||
595 (newval & 0xFFF) == 0x8E3 || (newval & 0xFFF) == 0x021) &&
596 ((newval & 0xFFF0000000000000) == 0x0000000000000000 ||
597 (newval & 0xFFF0000000000000) == 0x0A00000000000000 ||
598 (newval & 0xFFF0000000000000) == 0x8A00000000000000) &&
599 ((newval & 0x000FFFFFFFFFF000) != 0))
602 criteria = ptWritesPte;
610 rip = Candidate->Gla + Candidate->Instruction.Length;
615 ERROR(
"[ERROR] Maximum handler index reached!\n");
617 goto release_and_exit;
626 goto release_and_exit;
632 handler[len++] = 0x6A;
636 handler[len++] = 0x6A;
637 if (Candidate->Instruction.HasDisp)
640 handler[len++] = (
BYTE)Candidate->Instruction.Displacement;
648 handler[len++] = 0x48 | Candidate->Instruction.Rex.b;
649 handler[len++] = 0x50 | Candidate->Instruction.ModRm.rm;
656 handler[len++] = 0xE8;
657 handler[len++] = (dest >> 0x00) & 0xFF;
658 handler[len++] = (dest >> 0x08) & 0xFF;
659 handler[len++] = (dest >> 0x10) & 0xFF;
660 handler[len++] = (dest >> 0x18) & 0xFF;
665 handler[len++] = 0x48 | Candidate->Instruction.Rex.b;
666 handler[len++] = 0xFF;
667 handler[len++] = 0x30 | Candidate->Instruction.ModRm.rm | (Candidate->Instruction.ModRm.mod << 6);
669 if (Candidate->Instruction.HasSib)
671 handler[len++] = Candidate->Instruction.Sib.Sib;
674 if (Candidate->Instruction.HasDisp)
676 for (
QWORD k = 0; k < Candidate->Instruction.DispLength; k++)
678 handler[len++] = (Candidate->Instruction.Displacement >> (k * 8)) & 0xFF;
683 for (i = 0; i < Candidate->Instruction.Length; i++)
685 handler[len++] = Candidate->Instruction.InstructionBytes[i];
689 handler[len++] = 0x48 | Candidate->Instruction.Rex.b;
690 handler[len++] = 0xFF;
691 handler[len++] = 0x30 | Candidate->Instruction.ModRm.rm | (Candidate->Instruction.ModRm.mod << 6);
693 if (Candidate->Instruction.HasSib)
695 handler[len++] = Candidate->Instruction.Sib.Sib;
698 if (Candidate->Instruction.HasDisp)
700 for (
QWORD k = 0; k < Candidate->Instruction.DispLength; k++)
702 handler[len++] = (Candidate->Instruction.Displacement >> (k * 8)) & 0xFF;
718 handler[len++] = 0xE9;
719 handler[len++] = (dest >> 0x00) & 0xFF;
720 handler[len++] = (dest >> 0x08) & 0xFF;
721 handler[len++] = (dest >> 0x10) & 0xFF;
722 handler[len++] = (dest >> 0x18) & 0xFF;
734 ERROR(
"[ERROR] IntKernVirtMemWrite failed: 0x%08x\n", status);
736 goto release_and_exit;
742 ERROR(
"[ERROR] IntKernVirtMemWrite failed: 0x%08x\n", status);
744 goto release_and_exit;
751 ERROR(
"[ERROR] IntKernVirtMemWrite failed: 0x%08x\n", status);
753 goto release_and_exit;
758 &int20[16 - Candidate->Instruction.Length]);
761 ERROR(
"[ERROR] IntMemClkModifyPatchedData failed: 0x%08x\n", status);
763 goto release_and_exit;
769 Candidate->PtInstruction =
TRUE;
770 Candidate->Monitored =
FALSE;
775 TRACE(
"[PTCORE] Successfully patched instruction at RIP 0x%016llx, HND 0x%016llx, index %d, criteria %d!\n",
811 list = gPtiCandidatesList.
Flink;
812 while (list != &gPtiCandidatesList)
823 LOG(
"[PTCORE] Found instruction to remove, RIP 0x%016llx\n", pPtc->
Gla);
831 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
844 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
914 DWORD total, monitored, inpt, relevant;
916 total = monitored = inpt = relevant = 0;
924 for (
LIST_ENTRY *list = gPtiCandidatesList.
Flink; list != &gPtiCandidatesList; )
927 CHAR text[ND_MIN_BUF_SIZE];
940 LOG(
"%04d ---- RIP 0x%016llx, instruction %s\n", total, pPtc->
Gla, text);
943 LOG(
"We have %d total instructions modified, %d remaining to inspect, %d in page-tables, %d relevant\n",
944 total, monitored, inpt, relevant);
970 LOG(
"[PTCORE] Write took place inside the PT agent at GLA %llx, from RIP %llx!\n",
1005 LOG(
"[PTCORE] Exec took place inside the PT agent at GLA %llx, from RIP %llx!\n",
1034 DWORD sectionRva = 0;
1035 DWORD sectionCount = 0;
1045 ERROR(
"[ERROR] IntPeIterateSections failed with status: 0x%08x\n", status);
1050 for (i = 0; i < sectionCount; i++, pSec++)
1052 TRACE(
"[PTCORE] Hooking section %d (%s) with characteristics 0x%08x against writes\n",
1066 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
1072 TRACE(
"[PTCORE] Hooking section %d (%s) with characteristics 0x%08x against execute\n",
1084 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
1113 ERROR(
"[ERROR] IntPtiMonitorAllPtWriteCandidates failed: 0x%08x\n", status);
1114 goto cleanup_and_exit;
1121 ERROR(
"[ERROR] IntHookGpaEnablePtCache failed: 0x%08x\n", status);
1122 goto cleanup_and_exit;
1125 LOG(
"[PTCORE] PT filtering enabled!\n");
1168 ERROR(
"[ERROR] IntPtiRestoreAllPtWriteCandidates failed: 0x%08x\n", status);
1175 ERROR(
"[ERROR] IntHookGpaDisablePtCache failed: 0x%08x\n", status);
1182 ERROR(
"[ERROR] IntMtblRemoveAgentEntries failed: 0x%08x\n", status);
1185 LOG(
"[PTCORE] PT filtering disabled!\n");
1215 LOG(
"[PTCORE] PT filter loader deployed!\n");
1284 ERROR(
"[ERROR] IntLdrLoadPEImage failed: 0x%08x\n", status);
1285 goto cleanup_and_exit;
1292 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1293 goto cleanup_and_exit;
1300 ERROR(
"[ERROR] .cache section not found: 0x%08x!\n", status);
1301 goto cleanup_and_exit;
1312 ERROR(
"[ERROR] .table section not found: 0x%08x!\n", status);
1313 goto cleanup_and_exit;
1324 ERROR(
"[ERROR] .handler section not found: 0x%08x!\n", status);
1325 goto cleanup_and_exit;
1337 ERROR(
"[ERROR] .main section not found: 0x%08x!\n", status);
1338 goto cleanup_and_exit;
1350 ERROR(
"[ERROR] .main section not found: 0x%08x!\n", status);
1351 goto cleanup_and_exit;
1363 ERROR(
"[ERROR] .memtbl section not found: 0x%08x!\n", status);
1364 goto cleanup_and_exit;
1377 ERROR(
"[ERROR] .lock section not found: 0x%08x!\n", status);
1378 goto cleanup_and_exit;
1405 ERROR(
"[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
1406 goto cleanup_and_exit;
1414 ERROR(
"[ERROR] IntPtiHookPtDriver failed: 0x%08x\n", status);
1415 goto cleanup_and_exit;
1422 ERROR(
"[ERROR] IntVeHookVirtualizationExceptionHandler failed: 0x%08x\n", status);
1423 goto cleanup_and_exit;
1464 ERROR(
"[ERROR] PT filter injection failed with error 0x%08x, will bail out.\n", ErrorCode);
1477 ERROR(
"[ERROR] IntPtiEnableFiltering failed: 0x%08x\n", status);
1481 LOG(
"[PTCORE] PT filter loaded successfully!\n");
1488 ERROR(
"[ERROR] PT filter deliver failed, cannot enable monitoring!\n");
1492 WARNING(
"[WARNING] PT filter deliver failed, cannot enable monitoring!\n");
1523 LOG(
"[PTCORE] PT filter unloader deployed!\n");
1551 ERROR(
"[ERROR] IntMemClkUncloakRegion failed: 0x%08x\n", status);
1563 ERROR(
"[ERROR] IntHookObjectDestroy failed: 0x%08x\n", status);
1613 LOG(
"[WARNING] Cannot unload yet, RIPs still point inside the filter!\n");
1627 ERROR(
"[ERROR] IntPtiUnhookPtFilter failed: 0x%08x\n", status);
1631 LOG(
"[PTCORE] PT filter unhooked successfully!\n");
1663 LOG(
"[PTCORE] PT filter unloaded successfully!\n");
1668 ERROR(
"[ERROR] IntWinPowDisableSpinWait failed: 0x%08x\n", status);
1696 ERROR(
"[ERROR] Uninit in progress, cannot deploy the PT filtering agent now!\n");
1716 ERROR(
"[ERROR] IntLdrGetImageSizeAndEntryPoint failed: 0x%08x\n", status);
1724 NULL, 0, NULL, 0, NULL);
1727 ERROR(
"[ERROR] IntAgentInject failed: 0x%08x\n", status);
1766 ERROR(
"[ERROR] IntPtiDisableFiltering failed: 0x%08x\n", status);
1772 ERROR(
"[ERROR] IntPtiUnhookPtFilter failed: 0x%08x\n", status);
1798 LOG(
"[PTCORE] PT filter unhooked successfully!\n");
1806 NULL, gPtDriverx64,
sizeof(gPtDriverx64),
TRUE,
1808 NULL, AgOpts, NULL, 0, NULL);
1845 ERROR(
"[ERROR] IntPeGetSectionHeaderByRva failed for address %llx, agent at 0x%016llx, size %d\n",
1879 QWORD cacheIndex = Gpa & 0x1FF000;
1893 ERROR(
"[ERROR] IntVirtMemMap failed for 0x%016llx: 0x%08x\n", cacheGva, status);
1897 for (
DWORD i = 0; i < 512; i++)
1899 if (pEntries[i] == Gpa)
1930 QWORD cacheIndex = Gpa & 0x1FF000;
1944 ERROR(
"[ERROR] IntVirtMemMap failed for 0x%016llx: 0x%08x\n", cacheGva, status);
1948 for (i = 0; i < 512; i++)
1950 if (pEntries[i] == Gpa)
1955 if (pEntries[i] == 0)
1964 pEntries[
__rdtsc() % 512] = Gpa;
2019 ERROR(
"[ERROR] Could not allocate space in agent: requested %d bytes, used %d bytes, total %d bytes\n",
2039 ERROR(
"[ERROR] IntKernVirtMemWrite failed: 0x%08x\n", status);
2048 ERROR(
"[ERROR] IntKernVirtMemWrite failed: 0x%08x\n", status);
2053 TRACE(
"[PTFILTER] Allocated memtable space for RIP 0x%016llx at 0x%016llx, size %d bytes\n", Rip, ptr, Size);
2057 gPtMemtableSize += Size;
#define IMAGE_SCN_MEM_EXECUTE
static INTSTATUS IntPtiCompleteLoader(QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context)
Called once the PT loader finished execution.
BOOLEAN Monitored
TRUE if the instruction is being monitored. FALSE if it has been restored.
INTSTATUS IntPeGetSectionHeaderByRva(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD GuestRva, IMAGE_SECTION_HEADER *SectionHeader)
Given a relative virtual address, return the section header which describes the section the RVA lies ...
#define CONTAINING_RECORD(List, Type, Member)
#define ROUND_UP(what, to)
static INTSTATUS IntPtiDisableFiltering(void)
Disable PT candidate instructions monitoring.
INTSTATUS IntPtiCacheAdd(QWORD Gpa)
Add a guest-physical address to the PT filter cache of entries for which an exit is not required...
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
LIST_HEAD gPtiCandidatesList
We store each candidate in a RB tree, ordered by the location. We also store them in a linked-list...
QWORD gPtDriverMainAddress
Main function inside the PT filter.
INTSTATUS IntPtiRemovePtFilter(DWORD AgOpts)
Removes the PT filter.
#define THS_CHECK_PTFILTER
Will check if any RIP is inside the PT filter agent.
DWORD gPtTableIndexes[MAX_LUT_PAGES]
Lookup table of indexes.
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
static INTSTATUS IntPtCompleteUnloader(QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context)
Called once the agent unloader has finished executing.
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
INTSTATUS IntHookObjectDestroy(HOOK_OBJECT_DESCRIPTOR **Object, DWORD Flags)
Destroy an entire hook object. All regions belonging to this object will be removed.
IG_ARCH_REGS Regs
The current state of the guest registers.
QWORD gPtDriverHandlersAddress
Main handler inside the PT filter.
INTSTATUS IntKernVirtMemPatchDword(QWORD GuestVirtualAddress, DWORD Data)
Writes 4 bytes in the guest kernel memory.
#define LDR_FLAG_FIX_RELOCATIONS
If flag is set, the relocations will be applied.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
#define INT_STATUS_DISASM_ERROR
Indicates a decoder error.
INTSTATUS IntMemClkModifyPatchedData(void *CloakHandle, DWORD Offset, DWORD Size, const void *Data)
Modifies the patched data inside the guest memory.
#define IntEnterDebugger()
INTSTATUS IntHookGpaDisablePtCache(void)
Disable PT filtering.
struct _LIST_ENTRY * Flink
Measures the instruction search done for the page table filtering agent.
QWORD Gla
Linear address where the candidate was found.
QWORD gPtDriverAddress
Guest virtual address where the PT filter was injected.
void FUNC_RbTreeNodeFree(RBNODE *Node)
INTSTATUS IntPeGetSectionHeaderByIndex(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD Index, IMAGE_SECTION_HEADER *SectionHeader)
Return the section header located on position Index (0 based).
#define IMAGE_SCN_MEM_WRITE
#define INT_SUCCESS(Status)
QWORD gPtDriverCheckFunction
The check function inside the PT filter.
BOOLEAN gPtMonitored
Indicate the PT filter state.
QWORD gPtDriverMemtableAddress
Section used to store mem-tables (checkout memtables.c).
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
RBTREE gPtiCandidatesTree
PT candidate instruction RB tree root.
INTSTATUS RbLookupNode(RBTREE *Tree, RBNODE *NodeToSearch, RBNODE **NodeFound)
#define INT_STATUS_NOT_NEEDED_HINT
void * CloakHandle
Cloak handle used to hide the INT3/INT 20.
struct _PTI_CANDIDATE * PPTI_CANDIDATE
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
static void IntPtiRbTreeNodeFree(RBNODE *Node)
Called on RB tree node free.
DWORD OSVersion
Os version.
void IntPtiDumpStats(void)
Dump PT filtering statistics.
int FUNC_RbTreeNodeCompare(RBNODE *Left, RBNODE *Right)
#define INT_STATUS_NOT_FOUND
INSTRUX Instruction
The decoded instruction.
struct _PTI_CANDIDATE PTI_CANDIDATE
static INTSTATUS IntPtiMonitorAllPtWriteCandidates(void)
Scan the .text section of the NT image for PT candidates.
static INTSTATUS IntPtiHandleWrite(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
This callback handles writes that take place inside the in-guest PT filter. All attempts will be bloc...
INTSTATUS IntPtiHandleInt3(void)
This function is the main INT3 handler.
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
static void IntPtiDeleteInstruction(PPTI_CANDIDATE Candidate)
Delete a PT candidate instruction.
INTRO_GUEST_TYPE OSType
The type of the guest.
RBNODE Node
RB node for this entry.
INTSTATUS IntThrSafeCheckThreads(QWORD Options)
Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of c...
Will write the contents of the patched data inside the guest.
void IntPtiHandleGuestResumeFromSleep(void)
Sets PtFilterWaiting to true if PT filtering was enabled, or to false otherwise.
static int IntPtiRbTreeNodeCompareRip(RBNODE *Left, RBNODE *Right)
RB tree node compare function.
QWORD IntPtiAllocMemtableSpace(QWORD Rip, DWORD Size)
Allocate space for a mem-table.
#define TABLE_BUCKET_MASK
BOOLEAN PtFilterWaiting
True if the in-guest PT filter was not yet injected, but it should be.
static INTSTATUS IntPtiHookPtDriver(void)
Protect the in-guest PT filter against unauthorized access.
BOOLEAN IntPtiIsPtrInAgent(QWORD Ptr, THS_PTR_TYPE Type)
Check if an address points inside the PT filter. Ignore non-executable sections when doing so...
Measures the INT3 exits generated by the page table filtering mechanism.
#define INT_STATUS_CANNOT_UNLOAD
Indicates that Introcore can not unload in a safely manner.
INTSTATUS IntPtiInjectPtFilter(void)
Inject the PT filter inside the guest.
BOOLEAN PtFilterEnabled
If True, the in-guest PT filter is enabled and deployed.
PHOOK_EPT_ENTRY IntHookGpaGetExistingEptEntry(QWORD GpaPage)
Get the EPT entry associated with the provided guest physical page.
static INTSTATUS IntPtiUnhookPtFilter(void)
Remove protection from the PT filter.
#define INT_STATUS_NOT_INITIALIZED
INTSTATUS IntHookGpaEnablePtCache(void)
Enable PT filtering.
DWORD gPtMemtableSize
This indicates how much mem-table space we have allocated.
INTSTATUS IntPtiRemoveInstruction(QWORD Rip)
Remove the hook on a monitored instruction.
static INTSTATUS IntPtiHandleExecute(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
This callback handles instruction fetches that take place inside the in-guest PT filter. All attempts will be blocked.
#define MAX_ENTRIES_PER_BUCKET
DWORD gPtDriverSize
Size of the PT filter.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
static void IntPtiResetState(void)
Reset the PT filter state (used after removing it from guest memory).
static INTSTATUS IntPtiInspectInstruction(PPTI_CANDIDATE Candidate)
Inspect a candidate instruction for page-table modifications.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
QWORD Current
The currently used options.
INTSTATUS IntPeListSectionsHeaders(QWORD ImageBase, BYTE *ImageBuffer, DWORD ImageBufferSize, DWORD *FirstSectionOffset, DWORD *SectionCount)
Will get the offset to the first section header and the number of sections from the given module...
LIST_ENTRY Link
List entry element.
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
INTSTATUS IntMtblRemoveAgentEntries(void)
Removes only the mem-table entries that were relocated inside the PT filter.
static QWORD IntPtiDeliverDriverForLoad(QWORD GuestVirtualAddress, DWORD MaxSize, void *Context)
Called by the driver loader, in order to initialize the in-guest PT-filter.
#define HpFreeAndNullWithTag(Add, Tag)
INTSTATUS IntMemClkCloakRegion(QWORD VirtualAddress, QWORD Cr3, DWORD Size, DWORD Options, PBYTE OriginalData, PBYTE PatchedData, PFUNC_IntMemCloakWriteHandle WriteHandler, void **CloakHandle)
Hides a memory zone from the guest.
QWORD KernelVa
The guest virtual address at which the kernel image.
INTSTATUS IntIcFlushAddress(PINS_CACHE Cache, QWORD Gva, QWORD Cr3)
Flush entries cached from a given address.
union _IMAGE_SECTION_HEADER::@214 Misc
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
#define INT_STATUS_NO_DETOUR_EMU
Signals that no emulation is needed for this event.
#define IntPeGetSectionHeaderByName(Base, Buff, Name, Cr3, Sec)
#define INT_STATUS_ALREADY_INITIALIZED_HINT
DWORD SelfMapIndex
The self map index.
INTSTATUS IntWinAgentInject(PFUNC_AgentInjection InjectionCallback, PFUNC_AgentCompletion CompletionCallback, PFUNC_AgentDeliver DeliverCallback, void *Context, PBYTE AgentContent, DWORD AgentSize, BOOLEAN AgentInternal, DWORD AgentTag, AGENT_TYPE AgentType, const CHAR *Name, DWORD Options, const CHAR *Args, DWORD Pid, PWIN_AGENT *Agent)
Schedule an agent injection inside the guest.
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
#define UNREFERENCED_PARAMETER(P)
void * InstructionCache
The currently used instructions cache.
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
static QWORD IntPtiDeliverDriverForUnload(QWORD GuestVirtualAddress, DWORD MaxSize, void *Context)
This function is called when the boot driver is ready to unload & free the PT filter.
static INTSTATUS IntPtiEnableFiltering(void)
Enable PT candidate instruction monitoring.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
static uint64_t __rdtsc(void)
DWORD PtCount
Number of PT hooks.
INTSTATUS IntPtiCacheRemove(QWORD Gpa)
Remove a guest physical page from the PT filter cache.
static INTSTATUS IntPtiDeployUnloader(QWORD GuestVirtualAddress, DWORD AgentTag, void *Context)
Called as soon as the PT filter unloader has been successfully injected. Disables the PT filtering...
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
INTSTATUS IntLdrLoadPEImage(PBYTE RawPe, DWORD RawPeSize, QWORD GuestVirtualAddress, PBYTE LoadedPe, DWORD VirtualPeSize, DWORD Flags)
Load the provided PE image at the provided guest virtual address, and return it in LoadedPe...
DWORD gPtHandlersTotalSize
Total handlers size.
GUEST_STATE gGuest
The current guest state.
INTSTATUS IntLdrGetImageSizeAndEntryPoint(PBYTE RawPe, DWORD RawSize, DWORD *VirtualSize, DWORD *EntryPoint)
Returns the entry point and the virtual size for the provided module.
#define _Function_class_(expr)
THS_PTR_TYPE
The type of pointer to be checked.
PBYTE gPtDriverImage
Pointer to the PT filter image.
QWORD gPtDriverCacheAddress
GVA of the PT filter cache - entries we do not need to generate an exit for.
INTSTATUS IntWinPowDisableSpinWait(void)
This function is called in order to disable spin waiting after everything we needed to be unloaded wa...
#define IMAGE_SCN_MEM_DISCARDABLE
TIMER_FRIENDLY void IntDumpGva(QWORD Gva, DWORD Length, QWORD Cr3)
This function is a wrapper over IntDumpGvaEx (it uses RowLength = 16, ElementLength = 1...
void RbDeleteNode(RBTREE *Tree, RBNODE *Node)
void * gPtDriverCloak
PT filter cloak handle.
#define THS_CHECK_ONLY
Will check for safeness, without moving any RIP or stack value.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
static INTSTATUS IntPtiRestoreAllPtWriteCandidates(void)
Restore all PT candidates, by removing the INT3/INT 20 hook established on them.
#define HOOK_PTS_MONITORED_BITS
#define LIST_HEAD_INIT(Name)
INTSTATUS IntHookObjectHookRegion(void *Object, QWORD Cr3, QWORD Gla, SIZE_T Length, BYTE Type, void *Callback, void *Context, DWORD Flags, HOOK_REGION_DESCRIPTOR **Region)
Hook a contiguous region of virtual memory inside the provided virtual address space.
INTSTATUS IntKernVirtMemPatchQword(QWORD GuestVirtualAddress, QWORD Data)
Writes 8 bytes in the guest kernel memory.
INTSTATUS RbInsertNode(RBTREE *Tree, RBNODE *Node)
QWORD gPtDriverRdataAddress
Address of the rdata section inside the PT filter.
BYTE * KernelBuffer
A buffer containing the entire kernel image.
INTSTATUS IntMemClkUncloakRegion(void *CloakHandle, DWORD Options)
Removes a cloak region, making the original memory contents available again to the guest...
VCPU_STATE * gVcpu
The state of the current VCPU.
void * gPtDriverHook
PT filter hook handle.
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
static INTSTATUS IntPtiDeployLoader(QWORD GuestVirtualAddress, DWORD AgentTag, void *Context)
Called on initial loader deployment.
DWORD gPtMemtableTotalSize
Total mem-table size.
BOOLEAN BugCheckInProgress
#define RB_TREE_INIT(Name, Free, Compare)
Initializes a RBTREE structure.
INTSTATUS IntWinApiHookVeHandler(QWORD NewHandler, void **Cloak, QWORD *OldHandler, DWORD *ReplacedCodeLen, BYTE *ReplacedCode)
Hooks the #VE handler.
unsigned long long * PQWORD
#define INTRO_OPT_IN_GUEST_PT_FILTER
Enable in-guest page-table filtering (64-bit Windows only).
QWORD IntPtiGetAgentAddress(void)
Get the guest virtual address where the PT filter resides.
QWORD gPtDriverTableAddress
Table of handlers inside the PT filter.
#define IMAGE_SCN_MEM_NOT_PAGED
The page table filtering agent.
#define INT_STATUS_INVALID_PARAMETER_2
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
QWORD Gla
The accessed guest virtual address. Valid only for EPT exits.
INTSTATUS IntHookObjectCreate(DWORD ObjectType, QWORD Cr3, void **Object)
Create a new hook object.
BOOLEAN PtInstruction
TRUE if the instruction modified e PT entry.
DWORD gPtHandlerIndex
Current handler index.
DWORD gPtDriverEntryPoint
Entry point of the PT filter.
#define INT_STATUS_INSUFFICIENT_RESOURCES