14 #include "winagent_ve_x64.h" 93 #define VE_DRV_NAME u"#VE Agent" 94 #define VE_DRV_PATH VE_DRV_NAME 141 #define VE_TRAMPO_SIZE 24 160 CHAR text[ND_MIN_BUF_SIZE];
164 LOG(
"NO #VE info page on CPU %d!\n", CpuNumber);
168 LOG(
"**** #VE info page on CPU %d\n", vcpu->
Index);
169 LOG(
" Reason = 0x%08x, Reserved = 0x%08x, Qualification = 0x%016llx\n",
171 LOG(
" GLA = 0x%016llx, GPA = 0x%016llx, EPT = 0x%016llx, Reserved = 0x%016llx\n",
174 LOG(
" RAX = 0x%016llx RCX = 0x%016llx RDX = 0x%016llx RBX = 0x%016llx\n",
177 LOG(
" RSP = 0x%016llx RBP = 0x%016llx RSI = 0x%016llx RDI = 0x%016llx\n",
180 LOG(
" R8 = 0x%016llx R9 = 0x%016llx R10 = 0x%016llx R11 = 0x%016llx\n",
183 LOG(
" R12 = 0x%016llx R13 = 0x%016llx R14 = 0x%016llx R15 = 0x%016llx\n",
186 LOG(
" RIP = 0x%016llx FLG = 0x%016llx CS = 0x%016llx SS = 0x%016llx\n",
189 LOG(
" CR0 = 0x%016llx CR3 = 0x%016llx CR4 = 0x%016llx DR7 = 0x%016llx\n",
192 LOG(
" OLD = 0x%016llx NEW = 0x%016llx RSPN = %p RSPO = %p\n",
198 LOG(
"**** Instruction stream:\n");
201 LOG(
"**** Instruction in cache:\n");
205 LOG(
"**** VE core state:\n");
217 LOG(
"Self at 0x%016llx, phys at 0x%016llx, CPU %lld, current %d\n", vcpu->
VeInfoPage->
Self, veInfoGpa,
222 c ?
"convertible" :
"NOT CONVERTIBLE");
229 LOG(
"==============================================================================================\n");
262 BYTE r1, w1, x1, r2, w2, x2;
266 memzero(&victim,
sizeof(victim));
267 memzero(&originator,
sizeof(originator));
268 memzero(pEptViol,
sizeof(*pEptViol));
270 LOG(
"[VECORE] %s took place inside the #VE agent in protected view at GLA 0x%llx, from RIP 0x%llx!\n",
291 LOG(
"[VECORE] RIP GLA 0X%016llx, GPA 0x%016llx, EPT untrusted %c%c%c/%c, EPT protected %c%c%c/%c\n",
293 r2 ?
'R' :
'-', w2 ?
'W' :
'-', x2 ?
'X' :
'-', c2 ?
'C' :
'-');
300 LOG(
"[VECORE] GVA GLA 0X%016llx, GPA 0x%016llx, EPT untrusted %c%c%c/%c, EPT protected %c%c%c/%c\n",
302 r2 ?
'R' :
'-', w2 ?
'W' :
'-', x2 ?
'X' :
'-', c2 ?
'C' :
'-');
325 ERROR(
"[ERROR] Invalid access type!");
338 ERROR(
"[ERROR] IntExceptGetVictimEpt failed: 0x%08x\n", status);
350 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed: 0x%08x\n", status);
390 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
429 accessType = ((
PHOOK_GPA)Hook)->Header.EptHookType;
454 ERROR(
"[ERROR] Invalid access type!");
458 LOG(
"[VECORE] %s took place inside the #VE agent at GLA 0x%llx, from RIP 0x%llx!\n",
466 memzero(&victim,
sizeof(victim));
467 memzero(&originator,
sizeof(originator));
468 memzero(pEptViol,
sizeof(*pEptViol));
484 ERROR(
"[ERROR] IntExceptGetVictimEpt failed: 0x%08x\n", status);
496 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed: 0x%08x\n", status);
538 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
576 PBYTE oldPage, newPage;
577 QWORD oldAddr, newAddr;
580 oldPage = newPage = NULL;
586 LOG(
"[VECORE] Modified #VE agent page 0x%016llx from 0x%016llx to 0x%016llx!\n",
592 if ((OldPageSize == NewPageSize) && !!(OldEntry &
PT_P) && !!(NewEntry & PT_P) &&
598 if (!(OldEntry & PT_P) || !(NewEntry & PT_P))
600 ERROR(
"[ERROR] Old or new PT entry is not valid!\n");
606 oldAddr = (
CLEAN_PHYS_ADDRESS64(OldEntry) & ~(OldPageSize - 1)) + (VirtualAddress & (OldPageSize - 1));
607 newAddr = (
CLEAN_PHYS_ADDRESS64(NewEntry) & ~(NewPageSize - 1)) + (VirtualAddress & (NewPageSize - 1));
616 ERROR(
"[ERROR] Failed mapping the old address: 0x%08x\n", status);
619 goto cleanup_and_exit;
626 ERROR(
"[ERROR] Failed mapping the old address: 0x%08x\n", status);
629 goto cleanup_and_exit;
642 ERROR(
"[ERROR] IntGetEPTPageProtection failed: 0x%08x\n", status);
651 ERROR(
"[ERROR] IntSetEPTPageProtection failed: 0x%08x\n", status);
660 ERROR(
"[ERROR] IntSetEPTPageProtection failed: 0x%08x\n", status);
674 LOG(
"[VECORE] Remapping the #VE cache page at index %llu\n", i);
692 LOG(
"[VECORE] Remapping the #VE info page for VCPU %d\n", i);
698 ERROR(
"[ERROR] IntVeSetVeInfoPage failed: 0x%08x\n", status);
742 DWORD sectionRva = 0;
743 DWORD sectionCount = 0;
753 ERROR(
"[ERROR] IntPeIterateSections failed with status: 0x%08x\n", status);
757 LOG(
"[VECORE] Hooking headers against any access...\n");
768 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
780 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
792 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
796 for (i = 0; i < sectionCount; i++, pSec++)
798 LOG(
"[VECORE] Hooking section %d (%s) with characteristics 0x%08x against writes\n",
810 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
813 LOG(
"[VECORE] Hooking section %d (%s) with characteristics 0x%08x against reads\n",
825 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
828 if (0 != memcmp(pSec->
Name,
"VESTUB",
sizeof(
"VESTUB")))
830 LOG(
"[VECORE] Hooking section %d (%s) with characteristics 0x%08x against executes\n",
842 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
871 DWORD sectionRva = 0;
872 DWORD sectionCount = 0;
882 ERROR(
"[ERROR] IntPeIterateSections failed with status: 0x%08x\n", status);
887 for (
DWORD i = 0; i < sectionCount; i++, pSec++)
911 ERROR(
"[ERROR] IntTranslateVirtualAddress failed for GVA %llx: 0x%08x\n", gva, status);
918 ERROR(
"[ERROR] IntSetEPTPageProtectionEx failed for GPA %llx: 0x%08x\n", gpa, status);
952 LOG(
"Hooking PTs...\n");
962 ERROR(
"[ERROR] IntHookGvaSetHook failed: 0x%08x\n", status);
994 WARNING(
"[WARNING] IntHookGvaRemoveHook failed: 0x%08x\n", status);
1036 LOG(
"[VECORE] Setting the #VE info page on CPU %d at %llx/%llx\n", CpuNumber, VeInfoPageGva, veinfoGpa);
1041 ERROR(
"[ERROR] IntSetVEInfoPage failed: 0x%08x\n", status);
1045 if (0 != VeInfoPageGva)
1050 ERROR(
"[ERROR] IntTranslateVirtualAddress failed: 0x%08x\n", status);
1057 ERROR(
"[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
1061 LOG(
"[VECORE] Setting the #VE info page on CPU %d at %llx/%llx\n", CpuNumber, VeInfoPageGva, veinfoGpa);
1066 ERROR(
"[ERROR] IntSetVEInfoPage failed: 0x%08x\n", status);
1095 LOG(
"[VECORE] #VE loader deployed!\n");
1132 ERROR(
"[ERROR] #VE driver injection failed with error 0x%08x, load failed: %s, will bail out.\n", ErrorCode,
1139 LOG(
"[INFO] Will activate INTRO_OPT_IN_GUEST_PT_FILTER because the flag has been removed " 1140 "due to INTRO_OPT_VE\n");
1161 ERROR(
"[ERROR] IntHookGpaEnableVe failed: 0x%08x\n", status);
1167 LOG(
"[VECORE] #VE driver loaded successfully!\n");
1196 LOG(
"[VECORE] #VE unloader deployed!\n");
1229 buff[iidx++] = 0xE8;
1230 buff[iidx++] = 0x03;
1231 buff[iidx++] = 0x00;
1232 buff[iidx++] = 0x00;
1233 buff[iidx++] = 0x00;
1236 buff[iidx++] = 0x0F;
1237 buff[iidx++] = 0xAE;
1238 buff[iidx++] = 0xE8;
1241 buff[iidx++] = 0xC7;
1242 buff[iidx++] = 0x04;
1243 buff[iidx++] = 0x24;
1244 buff[iidx++] = (Target >> 0) & 0xFF;
1245 buff[iidx++] = (Target >> 8) & 0xFF;
1246 buff[iidx++] = (Target >> 16) & 0xFF;
1247 buff[iidx++] = (Target >> 24) & 0xFF;
1250 buff[iidx++] = 0xC7;
1251 buff[iidx++] = 0x44;
1252 buff[iidx++] = 0x24;
1253 buff[iidx++] = 0x04;
1254 buff[iidx++] = (Target >> 32) & 0xFF;
1255 buff[iidx++] = (Target >> 40) & 0xFF;
1256 buff[iidx++] = (Target >> 48) & 0xFF;
1257 buff[iidx++] = (Target >> 56) & 0xFF;
1259 buff[iidx++] = 0xC3;
1264 ERROR(
"[ERROR] IntVirtMemSafeWrite failed for GVA %llx: 0x%08x\n", Address, status);
1293 QWORD kiKernelExit = 0;
1300 0x90, 0x90, 0x90, 0x90,
1301 0x90, 0x90, 0x90, 0x90,
1302 0x90, 0x90, 0x90, 0x90,
1303 0x90, 0x90, 0x90, 0x90,
1304 0x90, 0x90, 0x90, 0x90,
1305 0x90, 0x90, 0x90, 0x90,
1312 ERROR(
"[ERROR] IntVirtMemSafeWrite failed for GVA %llx: 0x%08x\n", VeCoreJmpKiKernelExitAddress, status);
1321 ERROR(
"[ERROR] IntVeFindKernelKvaShadowAndKernelExit failed: 0x%08x\n", status);
1329 LOG(
"[INFO] Found KiKernelExit @ %llx\n", kiKernelExit);
1377 DWORD rva = 0, codelen = 0;
1392 LOG(
"[VECORE] Delivering the #VE agent at GVA %llx...\n", GuestVirtualAddress);
1402 status =
IntLdrLoadPEImage(gVeDriverx64,
sizeof(gVeDriverx64), GuestVirtualAddress,
1406 ERROR(
"[ERROR] IntLdrLoadPEImage failed: 0x%08x\n", status);
1407 goto cleanup_and_exit;
1415 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1416 goto cleanup_and_exit;
1419 LOG(
"[VECORE] The #VE agent was written at GVA %llx!\n", GuestVirtualAddress);
1427 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1428 goto cleanup_and_exit;
1437 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1438 goto cleanup_and_exit;
1451 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1452 goto cleanup_and_exit;
1461 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1462 goto cleanup_and_exit;
1473 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1474 goto cleanup_and_exit;
1482 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1483 goto cleanup_and_exit;
1494 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1495 goto cleanup_and_exit;
1502 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1503 goto cleanup_and_exit;
1506 LOG(
"[VECORE] Patched relevant-bits value 0x%016llx at %llx!\n", relevantbits, GuestVirtualAddress + rva);
1514 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1515 goto cleanup_and_exit;
1522 ERROR(
"[ERROR] IntVePatchVeCoreJumpBack failed: 0x%08x\n", status);
1523 goto cleanup_and_exit;
1526 LOG(
"[VECORE] Patched VeCoreJumpToKiKernelExit code at %llx\n", GuestVirtualAddress + rva);
1533 ERROR(
"[ERROR] IntPeFindExportByName failed for VeCoreVePages: 0x%08x\n", status);
1534 goto cleanup_and_exit;
1542 ERROR(
"[ERROR] IntPeFindExportByName failed VeCoreVeStacks: 0x%08x\n", status);
1543 goto cleanup_and_exit;
1546 vestacks = GuestVirtualAddress + rva;
1551 ERROR(
"[ERROR] IntPeFindExportByName failed VeCoreCache: 0x%08x\n", status);
1552 goto cleanup_and_exit;
1555 gVeCache = GuestVirtualAddress + rva;
1557 LOG(
"[VECORE] #VE info pages at 0x%016llx\n", vepages);
1558 LOG(
"[VECORE] #VE stacks at 0x%016llx\n", vestacks);
1559 LOG(
"[VECORE] #VE page cache 0x%016llx\n",
gVeCache);
1567 "VeCoreVirtualizationExceptionHandlerKPTI", &rva);
1574 "VeCoreVirtualizationExceptionHandlerNoKPTI", &rva);
1580 "VeCoreVirtualizationExceptionHandler", &rva);
1585 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1586 goto cleanup_and_exit;
1595 ERROR(
"[ERROR] IntWinApiHookVeHandler failed: 0x%08x\n", status);
1596 goto cleanup_and_exit;
1599 LOG(
"[VECORE] Hooked the #VE handler, old handler at %llx, new handler at %llx!\n", oldvehnd, newvehnd);
1608 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1609 goto cleanup_and_exit;
1616 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1617 goto cleanup_and_exit;
1625 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1626 goto cleanup_and_exit;
1632 ERROR(
"[ERROR] IntVePatchVeCoreJmpTrampoline failed: 0x%08x\n", status);
1633 goto cleanup_and_exit;
1640 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1641 goto cleanup_and_exit;
1648 QWORD gdtbase, desc;
1656 TRACE(
"[VECORE] VCPU %u is not used by the guest, will skip it\n", i);
1664 ERROR(
"[ERROR] IntGdtFindBase failed: 0x%08x\n", status);
1665 goto cleanup_and_exit;
1669 if (gdtlimit < 0x57)
1671 ERROR(
"[ERROR] GDT 0x%016llx on CPU %u has limit %u, which is too small!\n", gdtbase, i, gdtlimit);
1673 goto cleanup_and_exit;
1680 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1681 goto cleanup_and_exit;
1685 limit = ((desc & 0xFFFF) | ((desc & 0x000F000000000000) >> 32)) << ((desc & 0x80000000000000) ? 12 : 0);
1687 cpuid = ((limit & 0x3FF) << 6) | (limit >> 14);
1689 LOG(
"[VECORE] VCPU %d maps on guest CPU %d, GDT entry is 0x%016llx\n", i, cpuid, desc);
1696 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1697 goto cleanup_and_exit;
1708 ERROR(
"[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
1709 goto cleanup_and_exit;
1716 ERROR(
"[ERROR] IntVeHookVeDriver failed: 0x%08x\n", status);
1717 goto cleanup_and_exit;
1720 LOG(
"[VECORE] #VE driver hooked in guest view!\n");
1727 ERROR(
"[ERROR] IntVeEnableDisableDriverAccessInProtectedView failed: 0x%08x\n", status);
1728 goto cleanup_and_exit;
1731 LOG(
"[VECORE] #VE driver hooked in protected view!\n");
1738 ERROR(
"[ERROR] IntVeLockDriver failed: 0x%08x\n", status);
1739 goto cleanup_and_exit;
1742 LOG(
"[VECORE] #VE driver locked in memory!\n");
1751 ERROR(
"[ERROR] IntVeSetVeInfoPage failed: 0x%08x\n", status);
1752 goto cleanup_and_exit;
1761 LOG(
"[VECORE] Initialized the #VE info paged at 0x%016llx, stacks at 0x%016llx!\n", vepages, vestacks);
1767 gVeModule.
BaseVa = GuestVirtualAddress;
1777 ERROR(
"[ERROR] Something failed during #VE load, will unload it!\n");
1814 ERROR(
"[ERROR] IntVeSetVeInfoPage failed: 0x%08x\n", status);
1824 ERROR(
"[ERROR] IntMemClkUncloakRegion failed: 0x%08x\n", status);
1836 ERROR(
"[ERROR] IntHookObjectDestroyFastSafe failed: 0x%08x\n", status);
1840 LOG(
"[VECORE] Successfully removed agent protection in default view!\n");
1846 ERROR(
"[ERROR] IntVeUnlockDriver failed: 0x%08x\n", status);
1853 ERROR(
"[ERROR] IntVeEnableDisableDriverAccessInProtectedView failed: 0x%08x\n", status);
1858 LOG(
"[VECORE] Successfully removed agent protection in protected view!\n");
1902 LOG(
"[WARNING] Cannot unload yet, RIPs still point inside the filter!\n");
1910 ERROR(
"[ERROR] IntVeUnhookVeAgent failed: 0x%08x\n", status);
1924 LOG(
"[VECORE] #VE driver unloaded successfully!\n");
1972 LOG(
"[VECORE] #VE driver unloaded successfully!\n");
1977 ERROR(
"[ERROR] IntWinPowDisableSpinWait failed: 0x%08x\n", status);
2020 LOG(
"Breaking in debugger due to #VE request, reason 0x%016llx, argument 0x%016llx.\n",
2023 LOG(
"==============================================================================================\n");
2024 LOG(
"==============================================================================================\n");
2025 LOG(
"==============================================================================================\n");
2026 LOG(
"==============================================================================================\n");
2028 LOG(
"==============================================================================================\n");
2033 LOG(
"$$$$ #VE on CPU %d/%lld/%lld, #VE info page at 0x%016llx, self at 0x%016llx, " 2034 "GLA 0x%016llx, GPA 0x%016llx, QUAL 0x%016llx\n",
2046 ERROR(
"[ERROR] Trying to raise EPT violation with NULL #VE info page!\n");
2054 ERROR(
"[ERROR] Unknown #VE hypercall number %lld!\n", regs->
Rdx);
2080 WARNING(
"[WARNING] Cannot inject the #VE agent, because #VE is not supported!\n");
2086 WARNING(
"[WARNING] Cannot inject the #VE agent, because uninit is being prepared!\n");
2092 WARNING(
"[WARNING] Cannot inject the #VE agent, because an agent is already %s!\n",
2100 WARNING(
"[WARNING] Cannot inject the #VE agent, because it is only supported on x64 Windows!\n");
2111 NULL, 0, NULL, 0, NULL);
2150 ERROR(
"[ERROR] IntHookGpaDisableVe failed: 0x%08x\n", status);
2156 ERROR(
"[ERROR] IntVeUnhookVeAgent failed: 0x%08x\n", status);
2185 LOG(
"[VECORE] #VE driver unloaded successfully!\n");
2193 NULL, gVeDriverx64,
sizeof(gVeDriverx64),
TRUE,
2195 NULL, AgOpts, NULL, 0, NULL);
2240 (Ptr >= vehnd && Ptr < vehnd + 0x80) ||
2288 #define MAX_INSTRUX_VE_KERNEL_OBJECTS_COUNT 1024 2290 DWORD instruxCount = 0;
2295 PBYTE instruxBuffer = NULL;
2296 DWORD currentPosInBuff = 0;
2299 QWORD kernelExit = 0, kvaShadow = 0;
2300 DWORD maxInstruxCount;
2310 if (NULL == instruxBuffer)
2313 goto cleanup_and_exit;
2320 ERROR(
"[ERROR] IntIdtGetEntry failed for IDT base 0x%016llx: 0x%08x\n",
2322 goto cleanup_and_exit;
2328 ERROR(
"[ERROR] Failed to read the PF Shadow buffer: 0x%08x\n", status);
2329 goto cleanup_and_exit;
2342 ERROR(
"[ERROR] IntDecDecodeInstructionFromBuffer failed: 0x%08x\n", status);
2343 goto cleanup_and_exit;
2346 if ((instrux.Instruction == ND_INS_MOV_CR) && ND_IS_OP_REG(&instrux.Operands[0], ND_REG_CR, 8, NDR_CR3))
2353 if (instrux.Instruction == ND_INS_JMPNR && bMovCr3)
2355 currentRip = currentRip +
SIGN_EX(instrux.RelOffsLength, instrux.RelativeOffset) + instrux.Length;
2361 currentPosInBuff += instrux.Length;
2362 currentRip += instrux.Length;
2367 ERROR(
"[ERROR] Failed to find JMP after MOV CR3 instruction, bailing out!\n");
2370 goto cleanup_and_exit;
2377 ERROR(
"[ERROR] Failed to read the PF buffer: 0x%08x\n", status);
2378 goto cleanup_and_exit;
2382 currentPosInBuff = 0;
2392 ERROR(
"[ERROR] IntDecDecodeInstructionFromBuffer failed: 0x%08x\n", status);
2393 goto cleanup_and_exit;
2396 if (instrux.Instruction == ND_INS_IRET)
2403 instruxSizes[instruxCount] = instrux.Length;
2405 currentPosInBuff += instrux.Length;
2406 currentRip += instrux.Length;
2412 goto cleanup_and_exit;
2415 if (instruxCount == 0)
2417 ERROR(
"[ERROR] We found an IRET as the first instruction in nt!KiPageFault, will bail out!\n");
2420 goto cleanup_and_exit;
2423 maxInstruxCount = instruxCount >= 5 ? instruxCount - 5 : 0;
2427 for (
DWORD i = instruxCount - 1; i >= maxInstruxCount; i--)
2432 currentPosInBuff -= instruxSizes[i];
2433 currentRip -= instruxSizes[i];
2439 ERROR(
"[ERROR] IntDecDecodeInstructionFromBuffer failed: 0x%08x\n", status);
2440 goto cleanup_and_exit;
2450 if (instrux.Instruction == ND_INS_JMPNR &&
2451 instrux.Operands[0].Type == ND_OP_OFFS)
2453 kernelExit = currentRip +
SIGN_EX(instrux.RelOffsLength, instrux.RelativeOffset) + instrux.Length;
2455 else if (instrux.Instruction == ND_INS_TEST &&
2456 instrux.Operands[0].Type == ND_OP_MEM &&
2457 instrux.Operands[0].Info.Memory.IsRipRel &&
2458 instrux.Operands[1].Type == ND_OP_IMM &&
2459 instrux.Operands[1].Info.Immediate.Imm == 1)
2463 kvaShadow = currentRip + instrux.Operands[0].Info.Memory.Disp + instrux.Length;
2466 if (kernelExit != 0 && kvaShadow != 0)
2472 if (kernelExit == 0 || kvaShadow == 0)
2480 *KiKernelExit = kernelExit;
2483 if (NULL != instruxBuffer)
2524 LOG(
"[INFO] No #VE support is present for guest, will not enable the #VE system!\n");
2530 LOG(
"[INFO] No VMFUNC support is present for guest, will not enable the #VE system!\n");
2554 TRACE(
"[VECORE] Required APIs not found, will not use #VE.\n");
2558 LOG(
"[INFO] #VE and VMFUNC support detected, will use the #VE filtering optimization!\n");
2564 ERROR(
"[ERROR] IntCreateEPT failed: 0x%08x\n", status);
2565 goto cleanup_and_exit;
2568 LOG(
"[INFO] Untrusted EPT index is: %d, Protected EPT index is: %d\n",
2574 ERROR(
"[ERROR] IntGuestGetLastGpa failed: 0x%08x\n", status);
2575 goto cleanup_and_exit;
2578 TRACE(
"[VECORE] Max physical address for guest: 0x%016llx\n",
gVeMaxGpa);
2609 ERROR(
"[ERROR] IntLdrGetImageSizeAndEntryPoint failed: 0x%08x\n", status);
2610 goto cleanup_and_exit;
2614 memset(&gVeModule, 0,
sizeof(gVeModule));
2631 LOG(
"[VECORE] Successfully added all the relevant info in gVeModule!\n");
2678 ERROR(
"[ERROR] IntDestroyEPT failed: 0x%08x\n", status);
2728 QWORD totalVE = 0, mmFaults = 0, ignoredFaults = 0, igpw = 0, igpt = 0, igir = 0;
2737 LOG(
"[VECORE] No #VE stats to dump!\n");
2745 LOG(
"[VECORE] [CPU %d] We've got %llu #VE events, %llu ignored " 2746 "(%llu page-walk, %llu irrelevant, %llu cache), %f ticks/#VE\n",
2764 LOG(
"[VECORE] Total EPT = %llu, non-#VE = %llu, #VE/PT = %llu, by MM = %llu, " 2765 "ignored = %llu - %f%% (page-walk = %llu, cache = %llu, irrel = %llu)\n",
2766 gEptEvents + totalVE, gEptEvents, totalVE, mmFaults, ignoredFaults,
2767 ignoredFaults * 100.0 / (
double)totalVE, igpw, igpt, igir);
2821 DWORD line, bucket, entry;
2844 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
2845 goto cleanup_and_exit;
2854 if (
gVeCachePages[line].Page->Entries[bucket][entry] == Address)
2868 if (
gVeCachePages[line].Page->Entries[bucket][entry] == Address)
2914 QWORD mapBase, mapSize;
2915 QWORD pml4i, pdpi, pdi, pti, pfi;
2922 pfi = (Gla >> 3) & 0x1ff;
2937 mapBase = (pml4i << 39) | (pdpi << 30) | (pdi << 21) | (pti << 12);
2938 mapBase |= pml4i >= 0x100 ? 0xFFFF000000000000 : 0;
Measures kernel mode exceptions checks.
#define IMAGE_SCN_MEM_EXECUTE
static INTSTATUS IntVeUnlockDriver(void)
Removes the translation hook from the VE agent.
TIMER_FRIENDLY void IntDumpArchRegs(IG_ARCH_REGS const *Registers)
This function dumps the register values in a user friendly format.
INTSTATUS IntPtiInjectPtFilter(void)
Inject the PT filter inside the guest.
QWORD PhysicalAddress
The physical address to which VirtualAddress translates to.
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
QWORD Reserved2
Reserved by Intel.
INTRO_CODEBLOCKS CodeBlocks
Code blocks extracted for the alert.
QWORD VeMm
Number of VEs generated by the OS.
#define VE_CACHE_BUCKETS
64 buckets/line, indexed by bits [3, 8] inside the page-table entry address.
#define ROUND_UP(what, to)
QWORD OldValue
Old page-table entry.
INTSTATUS IntVeHandleHypercall(DWORD CpuNumber)
Handles hyper calls initiated by the VE agent.
DWORD gVeDriverSize
The driver virtual size.
#define GPA_HOOK_TABLE_SIZE
Size of the GPA hook hash.
#define INTRO_OPT_VE
Enable the Virtualization exception page table access pre-filtering agent (64-bit Windows only)...
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
DWORD Indexes[VE_CACHE_BUCKETS]
Array of used indexes inside the cache page.
QWORD IntVeGetDriverAddress(void)
Gets the guest virtual address of the VE agent.
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
INTSTATUS IntGetEPTPageConvertible(DWORD EptIndex, QWORD Address, BOOLEAN *Convertible)
LIST_HEAD GpaHooksWrite[GPA_HOOK_TABLE_SIZE]
Hash table of write hooks.
void ** gVeDriverPages
Swap hook handle for each VE driver page.
An internal error occurred (no memory, pages not present, etc.).
BYTE Instruction[16]
Current instruction bytes.
static INTSTATUS IntVeHandleAccess(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Handle accesses inside the VE agent (outside the protected view).
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.
INTSTATUS IntIdtGetEntry(DWORD CpuNumber, DWORD Entry, QWORD *Handler)
Get the handler of an interrupt from the IDT.
DWORD Index
The VCPU number.
INTSTATUS IntHookGpaDisableVe(void)
Disable VE filtering.
DWORD Crc32Compute(const void *Buffer, size_t Size, DWORD InitialCrc)
Computes the CRC for a byte array.
BOOLEAN Initialized
True if the VCPU is initialized and used by the guest, False if it is not.
QWORD GuestPhysicalAddress
Same as the GPA field provided on EPT Violations.
QWORD TscTotal
Total number of CPU ticks spent inside the agent.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
#define LDR_FLAG_FIX_RELOCATIONS
If flag is set, the relocations will be applied.
#define CLEAN_PHYS_ADDRESS64(x)
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
EXCEPTION_VICTIM_EPT Ept
Valid if the modified zone is EPT.
QWORD VeIgnoredIrrelevant
WIN_KERNEL_DRIVER Win
Valid only for Windows guests.
BOOLEAN IntVeIsCurrentRipInAgent(void)
Check if the current RIP points inside the VE agent.
INTSTATUS IntGetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Get the current guest GPR state.
#define VE_CACHE_LINES
64 cache lines (pages), indexed by bits [12, 17] inside the page-table address.
#define IntEnterDebugger()
INTSTATUS IntPeFindExportByName(QWORD ImageBase, BYTE *ImageBaseBuffer, CHAR *Name, DWORD *ExportRva)
Find the export name a Rva lies in.
#define VE_STACK_SIZE
Total size of the stack used by the VE agent.
QWORD Qualification
Same as the exit qualification provided on VM Exits.
QWORD gVeInfoPages
Guest virtual address where the VE info pages are located.
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
#define VE_CACHE_ENTRIES
8 entries/bucket.
#define IMAGE_SCN_MEM_WRITE
#define INT_SUCCESS(Status)
QWORD NewValue
New page-table entry.
static BOOLEAN IsListEmpty(const LIST_ENTRY *ListHead)
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
DWORD PathLength
The driver`s path length (number of WCHARS).
QWORD IntHookGetGlaFromGpaHook(HOOK_GPA const *Hook, QWORD Address)
Gets the GLA from a GPA hook.
BOOLEAN IntMemClkIsPtrInCloak(const void *Cloak, QWORD Ptr)
Checks if a guest virtual address is located inside a cloak region.
PBYTE MzPeHeaders
The driver`s MZ/PE headers (cached internally).
#define INT_STATUS_NOT_NEEDED_HINT
static INTSTATUS IntVeDeployUnloader(QWORD GuestVirtualAddress, DWORD AgentTag, void *Context)
Called after the boot driver (VE unloader) has been successfully injected.
REGISTERS Registers
Offset 0x30 - 0x200, general purpose registers.
INTSTATUS IntVeUpdateCacheEntry(QWORD Address, BOOLEAN Monitored)
Update an address inside the VE cache.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
QWORD Size
The size of the kernel module that owns this driver object.
static INTSTATUS IntVeHookVeDriver(void)
Protect the VE driver inside the untrusted EPT view.
BOOLEAN Protected
True if the driver is protected, False if it is not.
DWORD OSVersion
Os version.
static void IntVeDumpVeInfoPage(DWORD CpuNumber)
Dump the VE info page on the provided VCPU.
#define INT_STATUS_NOT_FOUND
BOOLEAN SupportVMFUNC
Set to True if support for VMFUNC was detected.
HOOK_STATE * gHooks
Global hooks state.
Describes a kernel-mode originator.
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
INTRO_GUEST_TYPE OSType
The type of the guest.
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
BOOLEAN VeAgentWaiting
True if the #VE agent was not yet injected, but it should be.
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.
#define VE_MAX_CPUS
Currently, VE supports only 64 VCPUs max.
PVECPU VeInfoPage
Pointer to the VEINFO page used for this VCPU.
static INTSTATUS IntVeUnhookVeAgent(void)
Removes the hooks placed on the VE agent.
static INTSTATUS IntVeDeployLoader(QWORD GuestVirtualAddress, DWORD AgentTag, void *Context)
Called once the VE loaded has been injected.
#define VE_HCALL_RAISE_EPT
Describes a kernel driver.
INTSTATUS IntHookGvaSetHook(QWORD Cr3, QWORD Gva, DWORD Length, BYTE Type, void *Callback, void *Context, void *ParentHook, DWORD Flags, HOOK_GVA **GvaHook)
Set a read, write, execute or swap hook on a guest virtual address.
static INTSTATUS IntVeHandleSwap(void *Context, QWORD VirtualAddress, QWORD OldEntry, QWORD NewEntry, QWORD OldPageSize, QWORD NewPageSize)
Handle VE agent page remapping.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
QWORD VeTotal
Total number of VEs.
INTSTATUS IntVeInit(void)
Initialize the VE system.
INTRO_VIOLATION_HEADER Header
The alert header.
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
#define HOOK_FLG_HIGH_PRIORITY
If flag is set, the callback associated to this hook will have a higher priority than the others...
INTSTATUS IntSetEPTPageProtection(DWORD EptIndex, QWORD Gpa, BYTE Read, BYTE Write, BYTE Execute)
DWORD NameHash
The hash of the name.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
INTSTATUS IntAlertFillCodeBlocks(QWORD Rip, QWORD Cr3, BOOLEAN Execute, INTRO_CODEBLOCKS *CodeBlocks)
Fills the code blocks pattern for an alert.
struct _HOOK_GPA * PHOOK_GPA
#define ALERT_FLAG_BETA
If set, the alert is a BETA alert. No action was taken.
void IntAlertEptFillFromKmOriginator(const EXCEPTION_KM_ORIGINATOR *Originator, EVENT_EPT_VIOLATION *EptViolation)
Fills kernel mode originator information inside an EPT alert.
LIST_HEAD GpaHooksRead[GPA_HOOK_TABLE_SIZE]
Hash table of read hooks.
GENERIC_ALERT gAlert
Global alert buffer.
#define INT_STATUS_CANNOT_UNLOAD
Indicates that Introcore can not unload in a safely manner.
INTSTATUS IntGuestGetLastGpa(QWORD *MaxGpa)
Get the upper limit of the guest physical memory range.
#define VE_CACHE_GET_LINE(x)
#define INITIAL_CRC_VALUE
void IntVeDumpStats(void)
Dump VE statistics.
#define INT_STATUS_EXCEPTION_BLOCK
static void IntVeResetState(void)
Reset the VE state.
#define INT_STATUS_ALREADY_INITIALIZED
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
PBYTE ProtectedStack
Offset 0x200, the protected stack.
#define INT_STATUS_NOT_INITIALIZED
#define IG_CURRENT_VCPU
For APIs that take a VCPU number as a parameter, this can be used to specify that the current VCPU sh...
SIZE_T NameLength
The length of the Name. This is the number of characters in the Name buffer.
static QWORD IntVeDeliverDriverForUnload(QWORD GuestVirtualAddress, DWORD MaxSize, void *Context)
Handles the unloading of the VE agent.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
QWORD MappingsEntries[MAX_TRANSLATION_DEPTH]
Contains the entry in which paging table.
QWORD TscCount
Total number of times the agent has been invoked.
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
#define ZONE_EXECUTE
Used for execute violation.
QWORD EptpIndex
The index of the EPT in which the fault took place.
#define VE_CACHE_GET_BUCKET(x)
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
INTSTATUS IntExceptGetVictimEpt(void *Context, QWORD Gpa, QWORD Gva, INTRO_OBJECT_TYPE Type, DWORD ZoneFlags, EXCEPTION_VICTIM_ZONE *Victim)
Fills an EXCEPTION_VICTIM_ZONE with relevant information from an EPT violation.
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...
QWORD IdtBase
Original IDT base.
Structure encapsulating VCPU-specific information.
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
DWORD gVeDriverEntryPoint
The driver entry point (RVA).
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
#define INVALID_EPTP_INDEX
QWORD Gpa
The accessed guest physical address. Valid only for EPT exits.
INTSTATUS IntHookGpaEnableVe(void)
Enable VE filtering.
#define HpFreeAndNullWithTag(Add, Tag)
#define INT_STATUS_INVALID_INTERNAL_STATE
void * Name
The name of the driver.
PBYTE gVeLoadedImageBuffer
Contains the loaded #VE module, relocated and such.
void IntExceptKernelLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a kernel-mode violation and dumps the code-blocks.
static INTSTATUS IntVeLockDriver(void)
Monitors all the VE agent pages against translation modifications.
union _IMAGE_SECTION_HEADER::@214 Misc
static INTSTATUS IntVeEnableDisableDriverAccessInProtectedView(BOOLEAN Enable)
Protect the VE driver inside the protected EPT view.
QWORD GuestLinearAddress
Same as the GLA field provided on EPT Violations.
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
QWORD Self
Pointer to self.
#define INT_STATUS_ALREADY_INITIALIZED_HINT
DWORD SelfMapIndex
The self map index.
INTSTATUS IntHookGvaRemoveHook(HOOK_GVA **Hook, DWORD Flags)
Remove a GVA hook.
Sent when an EPT violation triggers an alert. See EVENT_EPT_VIOLATION.
HOOK_GPA_STATE GpaHooks
GPA hooks state.
PWCHAR Path
The driver`s path.
#define IDT_DESC_SIZE64
The size of a 64-bit interrupt descriptor.
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.
static INTSTATUS IntVePatchVeCoreJmpTrampoline(QWORD Address, QWORD Target)
Patches the VE trampoline inside the guest VE handler.
DWORD CpuCount
The number of logical CPUs.
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
INTSTATUS IntVeUnInit(void)
Uninit the VE system.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
The Virtualization exception agent injected inside the guest.
INTSTATUS IntSetVEInfoPage(DWORD CpuNumber, QWORD VeInfoGpa)
QWORD ProtectionFlag
The introcore option that decided that this driver must be protected.
DWORD ProtectedEptIndex
The EPTP index of the trusted EPT.
void * gVeHandlerCloak
Cloak handle used to hide the guest VE handler.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
static INTSTATUS IntVePatchVeCoreJmpKiKernelExit(QWORD VeCoreJmpKiKernelExitAddress)
This function patches the VE code responsible of jumping to the KiKernelExit routine.
static uint64_t __rdtsc(void)
BOOLEAN VeInitialized
Set to True if #VE initialization was done.
#define THS_CHECK_VEFILTER
Will check if any RIP is inside the VE filter agent.
QWORD Rip
The RIP from where the call to the exported function came.
QWORD gVeMaxGpa
Maximum GPA accessible to the guest.
QWORD Gva
The modified guest virtual address.
QWORD gVeDriverAddress
The guest virtual address where the driver was deployed.
No access type. This can be used for swap hooks.
INTSTATUS IntGetEPTPageProtection(DWORD EptIndex, QWORD Gpa, BYTE *Read, BYTE *Write, BYTE *Execute)
INTSTATUS IntDestroyEPT(DWORD EptIndex)
struct @259 gVeCachePages[VE_CACHE_LINES]
static INTSTATUS IntVeFindKernelKvaShadowAndKernelExit(QWORD *KiKernelExit)
Searches for the KvaShadow and KiKernelExit.
__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...
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.
void IntAlertFillWinProcessByCr3(QWORD ProcessCr3, INTRO_PROCESS *EventProcess)
Saves information about a Windows process inside an alert. The process is searched by its kernel CR3...
THS_PTR_TYPE
The type of pointer to be checked.
BOOLEAN IntVeIsPtrInAgent(QWORD Ptr, THS_PTR_TYPE Type)
Check if an address points inside the VE agent.
INTSTATUS IntWinPowDisableSpinWait(void)
This function is called in order to disable spin waiting after everything we needed to be unloaded wa...
LIST_HEAD GpaHooksExecute[GPA_HOOK_TABLE_SIZE]
Hash table of execute hooks.
BOOLEAN IntVeIsAgentRemapped(QWORD Gla)
Checks if a given guest linear address belongs to the VE agent.
#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.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
#define INT_STATUS_RAISE_EPT
Raises an EPT event. Can be used to treat another event as an EPT violation.
#define ZONE_READ
Used for read violation.
PBYTE OriginalStack
Offset 0x208, the original stack.
BOOLEAN SupportVE
Set to True if support for #VE was detected.
#define HOOK_PTS_MONITORED_BITS
static INTSTATUS IntVeSetVeInfoPage(DWORD CpuNumber, QWORD VeInfoPageGva)
Sets the VE info page on the provided VCPU.
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.
QWORD VePageWalk
Number of VEs generated by the CPU page-walker.
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
static KERNEL_DRIVER gVeModule
Indicate the #VE agent state.
#define INT_STATUS_NOT_INITIALIZED_HINT
Encapsulates information about a virtual to physical memory translation.
INTSTATUS IntCreateEPT(DWORD *EptIndex)
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
BOOLEAN GlueIsVeApiAvailable(void)
Checks if the virtualization exception API is implemented.
INTRO_PROCESS CurrentProcess
The current process.
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.
VE_CACHE_LINE * Page
Mapped page inside Introspection virtual address space.
The action was blocked because there was no exception for it.
The Virtualization exception driver.
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
static QWORD IntVeDeliverDriverForLoad(QWORD GuestVirtualAddress, DWORD MaxSize, void *Context)
Initializes the VE driver agent inside the guest.
void IntVeHandleGuestResumeFromSleep(void)
Simply set the VeAgentWaiting variable to true if VE is enabled.
INTSTATUS IntVeRemoveAgent(DWORD AgOpts)
Removes the VE agent from guest memory.
INTSTATUS IntGdtFindBase(DWORD CpuNumber, QWORD *GdtBase, WORD *GdtLimit)
Returns the GDT base and limit for a guest CPU.
INTSTATUS IntVeDeployAgent(void)
Inject the VE agent inside the guest.
Event structure for EPT violations.
INTSTATUS IntGetCurrentEptIndex(DWORD CpuNumber, DWORD *EptpIndex)
Get the EPTP index of the currently loaded EPT.
BOOLEAN BugCheckInProgress
static INTSTATUS IntVeCompleteUnloader(QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context)
Finishes the unload procedure, by resetting the state and the power-state spin wait.
void IntDisasmGva(QWORD Gva, DWORD Length)
This function disassembles a code buffer (given its GVA) and then dumps the instructions (textual dis...
static INTSTATUS IntVeCompleteLoader(QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context)
Called once the VE loader has finished execution.
#define ALERT_FLAG_PROTECTED_VIEW
BOOLEAN PtFilterFlagRemoved
Set to True if the INTRO_OPT_IN_GUEST_PT_FILTER was given, but it was removed.
INTSTATUS IntWinApiHookVeHandler(QWORD NewHandler, void **Cloak, QWORD *OldHandler, DWORD *ReplacedCodeLen, BYTE *ReplacedCode)
Hooks the #VE handler.
#define INTRO_OPT_IN_GUEST_PT_FILTER
Enable in-guest page-table filtering (64-bit Windows only).
void * gVeHookObject
Hook object containing VE agent protection in the untrusted EPT.
DWORD PathHash
CRC32 hash value for the driver`s path.
QWORD gVeCache
The VE page-table cache.
#define MAX_INSTRUX_VE_KERNEL_OBJECTS_COUNT
The name is the #VE Agent.
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
INTSTATUS IntVeHandleEPTViolationInProtectedView(IG_EPT_ACCESS AccessType, INTRO_ACTION *Action)
Handle an EPT violation inside the protected EPT view.
DWORD UntrustedEptIndex
The EPTP index of the untrusted EPT.
INTSTATUS IntExceptKernelGetOriginator(EXCEPTION_KM_ORIGINATOR *Originator, DWORD Options)
This function is used to get the information about the kernel-mode originator.
INTSTATUS IntAlertFillExecContext(QWORD Cr3, INTRO_EXEC_CONTEXT *ExecContext)
Fills the current execution context.
#define ZONE_WRITE
Used for write violation.
#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.
DWORD Reason
Same as the basic VM Exit reason.
#define INT_STATUS_INSUFFICIENT_RESOURCES
void IntVeDumpVeInfoPages(void)
Dumps the VE info pages on all VCPUs.