41 #define KERNEL_SEARCH_LIMIT (16 * ONE_MEGABYTE) 53 #define IDLE_THREAD_OFFSET_PCR ((gGuest.Guest64) ? 0x198 : 0x12C) 56 #define PROCESS_SEARCH_LIMIT_THREAD_UPPER (DWORD)((gGuest.Guest64) ? 0x220 : 0x150) 59 #define PROCESS_SEARCH_LIMIT_THREAD_LOWER (DWORD)((gGuest.Guest64) ? 0x210 : 0x150) 67 #define CR3_OFFSET_IN_KPROCESS (DWORD)((gGuest.Guest64) ? 0x28 : 0x18) 70 #define WIN_SHARED_USER_DATA_PTR (gGuest.Guest64 ? 0xFFFFF78000000000 : 0xFFDF0000) 98 const DWORD maxSecCount = 10;
99 const DWORD objCount = 3;
101 DWORD objectsFound = 0;
107 if (NULL == pSections)
113 pSections, §ionCount);
116 ERROR(
"[ERROR] IntPeGetSectionHeadersByName failed for `ALMOSTRO`: 0x%08x\n", status);
117 goto cleanup_and_exit;
121 &pSections[sectionCount], NULL);
124 ERROR(
"[ERROR] IntPeGetSectionHeadersByName failed for `.data`: 0x%08x\n", status);
125 goto cleanup_and_exit;
131 for (
DWORD i = 0; i < sectionCount; i++)
136 for (
DWORD j = 0; j < pageCount; j++)
147 QWORD target = kernelBase + offset;
149 pPage.ptrValue = NULL;
156 ERROR(
"[ERROR] Failed mapping page %d of section %d: 0x%08x\n", j, i, status);
162 pPage.ptrValue = pKernel + offset;
166 if (j == pageCount - 1)
179 void *hostPtr =
gGuest.
Guest64 ? (
void *)&pPage.pPage64[parsed] : (
void *)&pPage.pPage32[parsed];
192 ((p & 0xFFFFFFFF00000000) == 0xFFFFFFFF00000000)))
197 if (pSec->
Name[0] !=
'.')
209 TRACE(
"[INTRO-INIT] Found loaded module list: 0x%llx\n", target);
225 TRACE(
"[INTRO-INIT] Found process list head: 0x%llx\n", target);
234 if (pSec->
Name[0] ==
'.')
247 TRACE(
"[INTRO-INIT] Found PFN database: 0x%llx\n", p);
261 if (objectsFound == objCount)
272 if (objectsFound == objCount)
279 if (objectsFound < objCount)
286 ERROR(
"[ERROR] MmPfnDatabase not found!\n");
291 ERROR(
"[ERROR] PsLoadedModuleList not found!\n");
296 ERROR(
"[ERROR] PsActiveProcessHead not found!\n");
305 if (NULL != pSections)
331 QWORD systemProcess = 0;
336 TRACE(
"[INTRO-INIT] IntWinGuestFindKernelObjects%d: 0x%08x\n",
gGuest.
Guest64 ? 64 : 32, status);
346 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
356 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed: 0x%08x\n", status);
410 for (
DWORD i = 256; i < 512; i++)
414 LOG(
"[SELFMAP] Found index = %d (0x%x)\n", i, i);
423 ERROR(
"[ERROR] Self map index not found!\n");
490 for (
DWORD i = 256; i < 512; i++)
502 goto _cleanup_and_leave;
508 for (
DWORD i = 4; i < 512; i++)
513 goto _cleanup_and_leave;
524 WARNING(
"[WARNING] We have a translation, but different physical addresses for 0x%016llx: " 525 "0x%016llx != 0x%016llx\n", KernelAddress, GvaTranslation->PhysicalAddress, nkt.
PhysicalAddress);
528 goto _cleanup_and_leave;
563 const QWORD startPhys = StartPhysical;
564 const QWORD endPhys = EndPhysical;
565 QWORD currentCr3 = 0;
568 if (NULL == SystemCr3)
576 ERROR(
"[ERROR] IntCr3Read failed: 0x%08x\n", status);
580 if (currentCr3 >= startPhys && currentCr3 < endPhys)
582 LOG(
"[WINGUEST STATIC] The current CR3 0x%016llx is already the system cr3!\n", currentCr3);
583 *SystemCr3 = currentCr3;
591 ERROR(
"[ERROR] IntTranslateVirtualAddressEx failed for 0x%016llx with cr3 0x%016llx: 0x%08x\n",
592 KernelAddress, currentCr3, status);
628 initEntry = initEntry->
Flink;
633 ERROR(
"[ERROR] IntSwapMemRemoveTransaction failed for %llx:%x: 0x%08x\n",
664 ERROR(
"[ERROR] IntRegisterBreakpointHandler failed: 0x%08x\n", status);
702 ERROR(
"[ERROR] IntWinDrvObjUninit failed: 0x%08x\n", status);
731 ERROR(
"[ERROR] IntCr4Unprotect failed: 0x%08x\n", status);
742 _In_ void *Originator,
802 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
837 exitAfterInformation =
TRUE;
841 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed: %08x\n", status);
843 exitAfterInformation =
TRUE;
854 ERROR(
"[ERROR] IntExceptGetVictimEpt failed: %08x\n", status);
856 exitAfterInformation =
TRUE;
859 if (exitAfterInformation)
872 LOG(
"[SUD-EXEC] An execution on shared user data occured in kernel-mode!\n");
914 ERROR(
"[ERROR] No process found with cr3: 0x%016llx, but ring is 3! Will inject #UD!",
924 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
925 exitAfterInformation =
TRUE;
936 ERROR(
"[ERROR] Failed getting modified zone: 0x%08x\n", status);
937 exitAfterInformation =
TRUE;
939 if (exitAfterInformation)
952 LOG(
"[SUD-EXEC] An execution on shared user data occured in user-mode!\n");
995 QWORD currentThread = 0;
1005 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1014 ERROR(
"[ERROR] IntWinGuestHandleKernelSudExec failed: 0x%08x\n", status);
1022 ERROR(
"[ERROR] IntWinThrGetCurrentThread failed: 0x%08x\n", status);
1027 if (NULL != pending)
1029 goto cleanup_and_take_action;
1035 ERROR(
"[ERROR] IntWinGuestHandleKernelSudExec failed: 0x%08x\n", status);
1039 cleanup_and_take_action:
1049 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
1067 ERROR(
"[ERROR] IntInjectExceptionInGuest failed: 0x%08x\n", status);
1071 if (NULL == pending)
1079 ERROR(
"[ERROR] IntUDAddToPendingList failed: 0x%08x\n", status);
1112 if (NULL != gSudExecHook)
1128 ERROR(
"[ERROR] IntHookGvaSetHook failed: 0x%08x\n", status);
1147 if (NULL == gSudExecHook)
1155 ERROR(
"[ERROR] IntHookGvaRemoveHook failed: 0x%08x\n", status);
1183 ERROR(
"[ERROR] IntWinIdtProtectAll failed: 0x%08x\n", status);
1193 ERROR(
"[ERROR] IntMsrSyscallProtect failed: 0x%08x\n", status);
1203 ERROR(
"[ERROR] IntCr4Protect failed: 0x%08x\n", status);
1213 ERROR(
"[ERROR] IntIdtrProtect failed: 0x%08x\n", status);
1223 ERROR(
"[ERROR] IntGdtrProtect failed: 0x%08x\n", status);
1233 ERROR(
"[ERROR] IntWinGuestProtectSudExec failed: 0x%08x\n", status);
1265 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"PsCreateSystemThread", status);
1274 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"ExAllocatePoolWithTag", status);
1283 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"ExFreePoolWithTag", status);
1287 TRACE(
"[INTRO-INIT] Found API function ExFreePoolWithTag @ 0x%016llx...\n", gWinGuest->
ExFreePoolWithTag);
1292 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"NtBuildNumber", status);
1299 ERROR(
"[ERROR] Failed getting NtBuildNumber value: %08x\n", status);
1303 TRACE(
"[INTRO-INIT] Found NtBuildNumber @ 0x%016llx with value 0x%08x...\n",
1309 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"NtBuildLab", status);
1316 ERROR(
"[ERROR] Failed getting NtBuildLab value for kernel base 0x%016llx:0x%08x\n",
gGuest.
KernelVa, status);
1320 TRACE(
"[INTRO-INIT] Found NtBuildLab @ 0x%016llx with value: `%s`\n",
1328 ERROR(
"[ERROR] %s not found: 0x%08x\n",
"KeServiceDescriptorTable RVA", status);
1335 ERROR(
"[ERROR] Failed getting KeServiceDescriptorTable value: %08x\n", status);
1344 ERROR(
"[ERROR] Failed getting KeServiceDescriptorTable number of services: %08x\n", status);
1350 ERROR(
"[ERROR] The number of services in the SSDT is higher than expected: %u\n",
1355 TRACE(
"[INTRO-INIT] Found KeServiceDescriptorTable @ 0x%016llx with table at 0x%016llx and %d functions...\n",
1382 #define WIN_SHARED_USER_DATA_OFFSET_PRODUCT 0x264 1383 #define WIN_SHARED_USER_DATA_OFFSET_PROD_VALID 0x268 1386 DWORD valid, productType;
1418 *ProductType = productType;
1422 #undef WIN_SHARED_USER_DATA_OFFSET_PRODUCT 1423 #undef WIN_SHARED_USER_DATA_OFFSET_PROD_VALID 1452 ERROR(
"[ERROR] IntWinGuestResolveImports failed: 0x%08x\n", status);
1456 goto leave_and_unload;
1467 goto leave_and_unload;
1477 WARNING(
"[WARNING] IntWinGuestFetchProductType failed: 0x%08x, will not be able to determine whether it is a " 1478 "server or not\n", status);
1491 goto leave_and_unload;
1510 ERROR(
"[ERROR] IntWinGuestFindKernelObjects failed: 0x%08x\n", status);
1516 WARNING(
"[WARNING] Introcore load was aborted!\n");
1519 goto leave_and_unload;
1522 TRACE(
"[INTRO-INIT] Kernel objects successfully identified!\n");
1527 ERROR(
"[ERROR] IntWinAgentInjectTrampoline failed: 0x%08x\n", status);
1528 goto leave_and_unload;
1534 ERROR(
"[ERROR] IntWinApiHookAll failed: 0x%08x\n", status);
1535 goto leave_and_unload;
1541 ERROR(
"[ERROR] IntSwapgsStartMitigation failed: 0x%08x\n", status);
1542 goto leave_and_unload;
1548 ERROR(
"[ERROR] IntWinDrvIterateLoadedModules failed: 0x%08x\n", status);
1549 goto leave_and_unload;
1555 ERROR(
"[ERROR] Failed finding kernel module!\n");
1556 goto leave_and_unload;
1559 LOG(
"[INTRO-INIT] Kernel loaded @ 0x%016llx size of image = 0x%llx timedate stamp = 0x%08x\n",
1565 ERROR(
"[ERROR] IntWinHalCreateHalData failed: 0x%08x\n", status);
1566 goto leave_and_unload;
1572 ERROR(
"[ERROR] IntWinProcIterateGuestProcesses failed: 0x%08x\n", status);
1573 goto leave_and_unload;
1579 ERROR(
"[ERROR] IntWinGuestActivateProtection failed: 0x%08x\n", status);
1580 goto leave_and_unload;
1588 ERROR(
"[ERROR] IntVeDeployAgent failed: 0x%08x\n", status);
1593 TRACE(
"[WINGUEST] Ensuring no thread will return into our hooks!\n");
1598 ERROR(
"[ERROR] IntThrSafeCheckThreads failed: 0x%08x\n", status);
1599 goto leave_and_unload;
1606 TRACE(
"[WINGUEST] Introspection successfully initialized!\n");
1675 ERROR(
"[ERROR] Callback came after we have no more sections to read...\n");
1677 goto resume_and_exit;
1686 TRACE(
"[WINGUEST STATIC] Since we are called asynchronously we will finish the initialization...\n");
1691 ERROR(
"[ERROR] IntWinGuestFinishInit failed: 0x%08x\n", status);
1696 if (Flags & SWAPMEM_FLAG_ASYNC_CALL)
1731 DWORD secStartOffset, secCount;
1736 unmapNtHeaders =
FALSE;
1743 ERROR(
"[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
1749 ERROR(
"[ERROR] Inconsistent MZPE image!\n");
1771 ERROR(
"[ERROR] Failed mapping VA 0x%016llx to host: 0x%08x\n",
1776 unmapNtHeaders =
TRUE;
1803 ERROR(
"[ERROR] Failed mapping VA 0x%016llx to host: 0x%08x\n",
1808 unmapNtHeaders =
TRUE;
1823 ERROR(
"[ERROR] Sections gets outside the first page. We don't support this yet!\n");
1845 for (
DWORD i = 0; i < secCount; i++)
1847 DWORD secActualSize;
1856 ERROR(
"[ERROR] We cannot have a section starting at 0!\n");
1863 ERROR(
"[ERROR] We cannot have a section starting at 0!\n");
1874 ERROR(
"[ERROR] Section %d seems corrupted: sizeOfImage = 0x%x, secstart = 0x%x, secsize = 0x%x\n",
1881 (0 == memcmp(pSec->
Name,
"INITKDBG",
sizeof(
"INITKDBG") - 1) ||
1882 (0 == memcmp(pSec->
Name,
"ERRATA",
sizeof(
"ERRATA") - 1))))
1897 ERROR(
"[ERROR] IntKernVirtMemRead failed for 0x%016llx -> 0x%016llx %s: 0x%08x\n",
1900 pSec->
Name, status);
1920 void *swapHandle = NULL;
1929 pSwp->
Size = secActualSize;
1933 WARNING(
"Section %d / %d is not in memory, will do a swap mem read\n", i, secCount);
1946 ERROR(
"[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
1951 if (NULL != swapHandle)
1958 if (retSize != secActualSize)
1960 ERROR(
"We requested %08x bytes, but got %08x!\n", secActualSize, retSize);
1972 TRACE(
"[WINGUEST STATIC] All sections were present in memory!\n");
1977 ERROR(
"[ERROR] IntWinGuestFinishInit failed: 0x%08x\n", status);
2032 ERROR(
"[ERROR] IntWinGuestReadKernel failed: 0x%08x\n", status);
2071 DWORD smallestBuild, biggestBuild;
2087 ERROR(
"[ERROR] IntCamiGetWinSupportedList failed: 0x%08x\n", status);
2091 TRACE(
"[INFO] %d supported os versions from cami\n", cb);
2094 if (NULL == pNtList)
2102 ERROR(
"[ERROR] IntCamiGetWinSupportedList failed: 0x%08x\n", status);
2103 goto cleanup_and_exit;
2107 smallestBuild = pNtList[0];
2108 biggestBuild = pNtList[cb - 1];
2124 DWORD val = pPage[i];
2126 if ((val & 0xf0000000) != 0xf0000000 ||
2127 (val & 0xf000ffff) != val ||
2128 (val & 0xffff) > biggestBuild ||
2129 (val & 0xffff) < smallestBuild)
2134 for (
DWORD j = 0; j < cb; j++)
2136 if (pNtList[j] == (val & 0xFFFF))
2138 TRACE(
"[WINGUEST STATIC] Found an NtBuildNumber 0x%08x (%d) @ 0x%016llx\n",
2139 val, val & 0xffff, gva + i *
sizeof(
DWORD));
2141 *NtBuildNumber = pNtList[j];
2143 goto cleanup_and_exit;
2169 if (NULL != pNtList)
2214 const DWORD maxSecCount = 10;
2215 DWORD sectionCount = 0;
2218 void *mappedSecPage = NULL;
2234 WARNING(
"[WARNING] Gva 0x%016llx is not in a good section of 0x%016llx, discardable: %d, " 2235 "execute: %d, writable: %d",
2236 KernelGva, KernelBase, !!(pSec[0].Characteristics & IMAGE_SCN_MEM_DISCARDABLE),
2237 !!(pSec[0].Characteristics & IMAGE_SCN_MEM_EXECUTE),
2238 !!(pSec[0].Characteristics & IMAGE_SCN_MEM_WRITE));
2240 goto cleanup_and_exit;
2246 pSec, §ionCount);
2249 WARNING(
"[WARNING] IntPeGetSectionHeadersByName failed for `ALMOSTRO`: 0x%08x, secCount = %d\n", status, sectionCount);
2252 goto cleanup_and_exit;
2258 WARNING(
"[WARNING] Presumed base 0x%016llx has no .data section!\n", KernelBase);
2260 goto cleanup_and_exit;
2265 for (
DWORD iSec = 0; iSec < sectionCount; iSec++)
2267 if ((pSec[iSec].VirtualAddress &
PAGE_OFFSET) != 0)
2269 WARNING(
"[WARNING] Base 0x%016llx has section start 0x%08x which is not page aligned!\n",
2270 KernelBase, pSec[iSec].VirtualAddress);
2272 goto cleanup_and_exit;
2277 WARNING(
"[WARNING] Section %d has size too big: 0x%08x\n", iSec, pSec[iSec].Misc.
VirtualSize);
2279 goto cleanup_and_exit;
2282 for (
QWORD page = KernelBase + pSec[iSec].VirtualAddress;
2288 if (page == ((KernelBase + pSec[iSec].VirtualAddress + pSec[iSec].Misc.
VirtualSize) &
PAGE_MASK))
2296 WARNING(
"[WARNING] IntVirtMemMap failed for 0x%016llx: 0x%08x. .data seems paged " 2297 "out for 0x%016llx!\n", page, status, KernelBase);
2298 goto cleanup_and_exit;
2304 *(
DWORD *)((size_t)mappedSecPage + current);
2306 if (currentptr == KernelBase)
2308 TRACE(
"[INFO] Found PsNtosImageBase = 0x%016llx at address 0x%016llx!\n",
2309 KernelBase, page + current);
2311 goto cleanup_and_exit;
2320 if (NULL != mappedSecPage)
2337 WARNING(
"[WARNING] PsNtosImageBase not found for 0x%016llx!\n", KernelBase);
2366 QWORD kernelBase, limit;
2385 if ((hostPage[0] ==
'M' && hostPage[1] ==
'Z'))
2390 WARNING(
"[WARNING] IntWinGuestValidateKernel failed: 0x%08x\n", status);
2406 if (NULL != hostPage)
2413 ERROR(
"[ERROR] Could not find the kernel headers in the first %lldMB!\n",
2418 *KernelBase = kernelBase;
2441 DWORD activeCount = CpuCount;
2444 for (
DWORD i = 0; i < CpuCount; i++)
2461 if (0 == cr3 || 0 == (cr0 &
CR0_PG))
2468 if (activeCount != CpuCount)
2470 WARNING(
"[WARNING] The active cpu count (%d) is different than the actual cpu count (%d)\n",
2471 activeCount, CpuCount);
2474 TRACE(
"[INTRO-INIT] Active CPU Count: %d\n", activeCount);
2505 QWORD kernelCr3OffsetPcr;
2509 DWORD csType, mapSize;
2510 INSTRUX offsetInstrux;
2515 kernelCr3OffsetPcr = kpcr = 0;
2531 ERROR(
"[ERROR] Failed to map Syscall page: 0x%08x\n", status);
2532 goto cleanup_and_exit;
2541 for (
DWORD i = 0; i < mapSize;)
2545 CHAR nd[ND_MIN_BUF_SIZE] = { 0 };
2555 NdToText(&instrux, 0,
sizeof(nd), nd);
2562 if (ND_INS_MOV == instrux.Instruction && 2 == instrux.ExpOperandsCount &&
2563 ND_OP_REG == instrux.Operands[0].Type &&
2564 ND_REG_GPR == instrux.Operands[0].Info.Register.Type)
2567 (instrux.Operands[0].Info.Register.Reg == offsetInstrux.Operands[0].Info.Register.Reg))
2572 if (ND_OP_MEM == instrux.Operands[1].Type && instrux.Operands[1].Info.Memory.HasSeg &&
2573 instrux.Operands[1].Info.Memory.HasDisp &&
2574 ((
gGuest.
Guest64 && NDR_GS == instrux.Operands[1].Info.Memory.Seg) ||
2575 (!
gGuest.
Guest64 && NDR_FS == instrux.Operands[1].Info.Memory.Seg)))
2577 memcpy(&offsetInstrux, &instrux,
sizeof(instrux));
2580 TRACE(
"[INFO] Found a possible offset instruction: %s\n", nd);
2588 memzero(&offsetInstrux,
sizeof(offsetInstrux));
2596 else if (bFound && ND_INS_MOV_CR == instrux.Instruction && 2 == instrux.ExpOperandsCount &&
2597 ND_OP_REG == instrux.Operands[0].Type && ND_OP_REG == instrux.Operands[1].Type &&
2598 ND_REG_CR == instrux.Operands[0].Info.Register.Type &&
2599 NDR_CR3 == instrux.Operands[0].Info.Register.Reg &&
2600 offsetInstrux.Operands[0].Info.Register.Reg == instrux.Operands[1].Info.Register.Reg)
2602 kernelCr3OffsetPcr = offsetInstrux.Operands[1].Info.Memory.Disp;
2604 TRACE(
"[INFO] Found a valid second instruction: %s\n", nd);
2605 TRACE(
"[INFO] We will use the last possible offset instruction!\n");
2610 i += instrux.Length;
2613 if (0 == kernelCr3OffsetPcr)
2615 ERROR(
"[ERROR] Could not find a valid instruction to get kernel cr3!");
2617 goto cleanup_and_exit;
2620 TRACE(
"[INTRO-INIT] Found KernelDirectoryTableBase offset in PCR at %llx\n", kernelCr3OffsetPcr);
2625 ERROR(
"[ERROR] IntFindKernelPcr failed: 0x%08x\n", status);
2626 goto cleanup_and_exit;
2629 TRACE(
"[INTRO-INIT] Found PCR at 0x%016llx\n", kpcr);
2634 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
2635 goto cleanup_and_exit;
2664 QWORD pcr, idleThread, idleProcess;
2669 pcr = idleThread = idleProcess = 0;
2677 ERROR(
"[ERROR] IntFindKernelPcr failed: 0x%08x\n", status);
2690 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
2694 TRACE(
"[INFO] Idle thread [%d] @ 0x%016llx\n",
gVcpu->
Index, idleThread);
2699 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
2701 goto cleanup_and_exit;
2709 QWORD supposedCr3 = 0;
2722 TRACE(
"[INFO] Found a potentially valid idle process at offset 0x%08x -> 0x%016llx\n",
2741 TRACE(
"[INFO] Found a valid idle process cr3 at offset 0x%08x @ 0x%016llx -> 0x%016llx\n",
2779 DWORD activeCpuCount;
2782 void *swapHandle = NULL;
2785 QWORD kernelBase = 0;
2786 QWORD kernelBaseIdt = 0;
2787 DWORD ntBuildNumber = 0;
2794 memzero(gWinGuest,
sizeof(*gWinGuest));
2807 ERROR(
"[ERROR] IntVeInit failed: 0x%08x; will continue, but will not use #VE.\n", status);
2811 TRACE(
"[INTRO-INIT] #VE initialized successfully!\n");
2821 ERROR(
"[ERROR] IntGsRead failed: 0x%08x\n", status);
2825 TRACE(
"[INTRO-INIT] IA32_GS_BASE_MSR = 0x%016llx \n", gsBase);
2834 ERROR(
"[ERROR] IntFsRead failed: 0x%08x\n", status);
2838 TRACE(
"[INTRO-INIT] IA32_FS_BASE_MSR = 0x%016llx \n", fsBase);
2854 ERROR(
"[ERROR] Failed reading the syscall msr: 0x%08x\n", status);
2859 ERROR(
"[ERROR] SYSCALL MSR 0x%016llx is not valid!\n", msrValue);
2865 TRACE(
"[INTRO-INIT] Found SYSCALL handler @ 0x%016llx\n", msrValue);
2870 ERROR(
"[ERROR] IntCr3Read failed: 0x%08x\n", status);
2880 ERROR(
"[ERROR] IntWinGuestFindKernelCr3 failed: 0x%08x\n", status);
2897 ERROR(
"[ERROR] IntIdtGetEntry failed: %08x\n", status);
2903 TRACE(
"[INTRO-INIT] Found first interrupt handler @ 0x%016llx\n", idtValue);
2907 WARNING(
"[WARNING] First interrupt handler @ 0x%016llx is not valid\n", idtValue);
2915 ERROR(
"[ERROR] IntWinGuestFindKernel failed: %08X\n", status);
2920 LOG(
"[INTRO-INIT] Found the base of the ntoskrnl.exe [SYSCALL] @ VA 0x%016llx\n", kernelBase);
2929 ERROR(
"[ERROR] IntWinGuestFindKernel failed: 0x%08X\n", status);
2938 LOG(
"[INTRO-INIT] Found the base of the ntoskrnl.exe [IDT] @ VA 0x%016llx\n", kernelBaseIdt);
2941 if (kernelBaseIdt && kernelBase != kernelBaseIdt)
2943 WARNING(
"[WARNING] SYSCALL & IDT handlers point in different drivers (0x%016llx vs 0x%016llx).\n",
2944 kernelBase, kernelBaseIdt);
2946 kernelBase = kernelBaseIdt;
2953 ERROR(
"[ERROR] IntWinGuestFindBuildNumber failed: 0x%08X\n", status);
2983 ERROR(
"[ERROR] IntWinGuestFindIdleCr3 failed: 0x%08x\n", status);
2999 ERROR(
"[ERROR] IntWinGuestFindSelfMapIndex failed: 0x%08x\n", status);
3022 ERROR(
"[ERROR] IntWinGuestInit failed: 0x%08x\n", status);
3049 ERROR(
"[ERROR] Failed reading the kernel headers: 0x%08x\n", status);
3054 if (NULL != swapHandle)
3114 count = snprintf(VersionString, VersionStringSize,
"%s %s", gWinGuest->
ServerVersionString,
3115 strcasestr(FullString,
"lts") ?
"ltsb" :
"");
3122 count = snprintf(VersionString, VersionStringSize,
"%s %s %s", gWinGuest->
VersionString,
3123 strcasestr(FullString,
"lts") ?
"ltsb" :
"", appendix);
3126 if (count >= VersionStringSize)
Measures kernel mode exceptions checks.
#define IMAGE_SCN_MEM_EXECUTE
static INTSTATUS IntWinGuestFetchProductType(WIN_PRODUCT_TYPE *ProductType)
Obtains the Windows product type.
static INTSTATUS IntWinGuestFindSelfMapIndex(void)
Finds the self map index.
#define INT_STATUS_GUEST_OS_NOT_SUPPORTED
Indicates that the guest operating system is not supported.
INTSTATUS IntWinAgentUnInit(void)
Uninit the agents state.
#define THS_CHECK_SWAPGS
Will check if any RIP is inside a mitigated SWAPGS gadget.
static INTSTATUS IntWinGuestFindKernel(QWORD KernelGva, QWORD *KernelBase)
Searches for the base of the Windows kernel image.
struct _IMAGE_NT_HEADERS64 * PIMAGE_NT_HEADERS64
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.
INTRO_CODEBLOCKS CodeBlocks
Code blocks extracted for the alert.
static INTSTATUS IntWinGuestHandleKernelSudExec(QWORD Address, INTRO_ACTION *Action)
Handles a kernel mode execution inside SharedUserData.
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 ...
INTSTATUS IntIdtFindBase(DWORD CpuNumber, QWORD *Base, WORD *Limit)
Returns the IDT base and limit for a guest CPU.
#define CONTAINING_RECORD(List, Type, Member)
#define ROUND_UP(what, to)
void IntGuestSetIntroErrorState(INTRO_ERROR_STATE State, INTRO_ERROR_CONTEXT *Context)
Updates the value of the gErrorState and the value of the gErrorStateContext.
#define INTRO_OPT_VE
Enable the Virtualization exception page table access pre-filtering agent (64-bit Windows only)...
struct _IMAGE_FILE_HEADER IMAGE_FILE_HEADER
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
QWORD MmPfnDatabase
Guest virtual address of the PFN data base.
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
#define WIN_SHARED_USER_DATA_PTR
The address where the SharedUserData is mapped in the Windows kernel.
An internal error occurred (no memory, pages not present, etc.).
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
INTSTATUS IntWinGuestActivateProtection(void)
Activates the protection for a Windows guest.
static INTSTATUS IntWinGuestFindKernelObjects(void)
Searches for kernel objects.
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 IntIdtrProtect(void)
Enable IDTR protection.
BOOLEAN Initialized
True if the VCPU is initialized and used by the guest, False if it is not.
QWORD SyscallAddress
Guest virtual address of the SYSCALL/SYSENTER handler.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
INTSTATUS IntPeFindKernelExport(const char *Name, QWORD *ExportGva)
Find an export inside the NT kernel image.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
BOOLEAN IntPolicyCoreTakeAction(QWORD Flag, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a core introspection option.
INTSTATUS IntFsRead(DWORD CpuNumber, QWORD *FsValue)
Reads the IA32_FS_BASE guest MSR.
Measures user mode exceptions checks.
#define PAGE_REMAINING(addr)
WIN_KERNEL_DRIVER Win
Valid only for Windows guests.
INTSTATUS IntReadString(QWORD StrGva, DWORD MinimumLength, BOOLEAN AnsiOnly, char **String, DWORD *StringLength)
Reads a string from the guest kernel memory.
INTSTATUS IntWinHalCreateHalData(void)
Initializes gHalData.
QWORD ReturnRip
The RIP at which the code that triggered the alert returns.
struct _EVENT_EPT_VIOLATION::@276 Originator
DWORD KernelSize
The size of the kernel.
#define KERNEL_SEARCH_LIMIT
The maximum size of the area of memory in which the kernel base is searched for.
INTSTATUS IntWinGuestNew(void)
Starts the initialization and protection process for a new Windows guest.
WORD IdtLimit
The current IDT limit.
INTSTATUS IntSwapMemReadData(QWORD Cr3, QWORD VirtualAddress, DWORD Length, DWORD Options, void *Context, DWORD ContextTag, PFUNC_PagesReadCallback Callback, PFUNC_PreInjectCallback PreInject, void **SwapHandle)
Reads a region of guest virtual memory, and calls the indicated callback when all the data is availab...
struct _LIST_ENTRY * Flink
Information not yet loaded.
The product type is unknown.
void IntWinHalUninit(void)
Frees any resources held by gHalData and removes all the HAL protections.
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
#define IMAGE_SCN_MEM_WRITE
#define PROCESS_SEARCH_LIMIT_THREAD_UPPER
The upper limit of the area in which the idle process is searched.
#define INT_SUCCESS(Status)
QWORD ExFreePoolWithTag
Guest virtual address of the ExFreePoolWithTag kernel function.
INTSTATUS IntWinThrGetCurrentThread(DWORD CpuNumber, QWORD *EthreadAddress)
Get the ETHREAD structure address of the thread currently running on the given CPU.
LIST_ENTRY Link
Link inside the WINDOWS_GUEST.InitSwapHandles list.
A critical structure was not found inside the guest kernel.
static INTSTATUS IntWinGuestFindBuildNumber(QWORD KernelGva, BOOLEAN Guest64, BOOLEAN IsKptiInstalled, DWORD *NtBuildNumber)
Finds the NtBuildNumber kernel variable.
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
void IntWinAgentInit(void)
Initialize the agents state.
BOOLEAN ProtectionActivated
IMAGE_FILE_HEADER FileHeader
WIN_PRODUCT_TYPE ProductType
The product type. Obtained directly from the guest during initialization.
INTSTATUS IntWinGuestProtectSudExec(void)
Protects SharedUserData against executions by establishing an EPT hook on it.
static INTSTATUS IntWinGuestFindKernelCr3(QWORD Syscall)
Searches for the kernel Cr3.
INFO_UD_PENDING * IntUDGetEntry(const QWORD Cr3, const QWORD Rip, const QWORD Thread)
Get a UD entry for the provided Cr3, Rip and Thread ID.
#define INT_STATUS_NOT_NEEDED_HINT
Describes a user-mode originator.
INTSTATUS IntPeGetSectionHeadersByName(QWORD ImageBase, BYTE *ImageBaseBuffer, PCHAR Name, DWORD NumberOfSectionHeadersAllocated, QWORD Cr3, IMAGE_SECTION_HEADER *SectionHeaders, DWORD *NumberOfSectionHeadersFilled)
Return all the section headers matching the indicated Name.
#define HpAllocWithTag(Len, Tag)
INTSTATUS IntWinDrvObjUninit(void)
Removes all the driver objects in the gWinDriverObjects.
int INTSTATUS
The status data type.
QWORD Size
The size of the kernel module that owns this driver object.
The operating system version is not supported.
INTSTATUS IntMsrSyscallProtect(void)
Enable protection for all SYSCALL and SYSENTER MSRs.
DWORD OSVersion
Os version.
QWORD gEventId
The ID of the current event.
#define INT_STATUS_NOT_FOUND
DWORD NumberOfServices
The number of entries in the SSDT.
#define WIN_SHARED_USER_DATA_OFFSET_PRODUCT
QWORD IntroActiveEventId
The event ID on which introcore became active.
QWORD ExAllocatePoolWithTag
Guest virtual address of the ExAllocatePoolWithTag kernel function.
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
#define TRFLG_NONE
No special options.
PCHAR ServerVersionString
A NULL terminated string containing Windows server version information.
void IntWinGuestUninit(void)
Uninits a Windows guest.
WINDOWS_GUEST _WindowsGuest
Linux specific information. Valid when OSType is introGuestWindows.
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...
BOOLEAN IntWinGuestIsIncreasedUserVa(void)
Check if the guest has an increased user address space.
INTSTATUS IntPhysicalMemWrite(QWORD PhysicalAddress, DWORD Length, void *Buffer)
Writes data to a guest physical memory range, but only for a single page.
static INTSTATUS IntWinGuestFindSystemCr3(QWORD KernelAddress, QWORD *SystemCr3, QWORD StartPhysical, QWORD EndPhysical)
Searches for the system Cr3 in a range of physical addresses.
#define INT_STATUS_LOAD_ABORTED
Indicates that Introcore loading was aborted.
static INTSTATUS IntWinGuestResolveImports(void)
Obtains the addresses of public variable and functions exposed by the Windows kernel.
INTSTATUS IntCr4Unprotect(void)
Disables the CR4 protection.
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
#define INTRO_OPT_PROT_KM_IDT
INTSTATUS IntDumpCodeAndRegs(QWORD Gva, QWORD Gpa, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes) as well as the values of the reg...
INTRO_GUEST_TYPE OSType
The type of the guest.
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
INSTRUX Instruction
The current instruction, pointed by the guest RIP.
INTSTATUS IntThrSafeCheckThreads(QWORD Options)
Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of c...
INTSTATUS IntNotifyIntroActive(void)
INTSTATUS IntWinDrvCreateFromAddress(QWORD ModuleInfo, QWORD Flags)
Adds a driver to introspection's LoadedModuleList (gKernelDrivers). This way we avoid lots of mapping...
static DWORD IntWinGetActiveCpuCount(DWORD CpuCount)
Gets the number of active CPUs used by the guest.
DWORD TimeDateStamp
The driver`s internal timestamp (from the _IMAGE_FILE_HEADER).
#define WIN_SHARED_USER_DATA_OFFSET_PROD_VALID
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.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
INTSTATUS IntGdtrProtect(void)
Enable GDTR protection.
INTRO_VIOLATION_HEADER Header
The alert header.
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
QWORD PsCreateSystemThread
Guest virtual address of the PsCreateSystemThread kernel function.
#define INTRO_OPT_PROT_KM_MSR_SYSCALL
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.
static INTSTATUS IntWinGuestHandleUserSudExec(QWORD Address, INTRO_ACTION *Action)
Handles an user-mode execution inside SharedUserData.
Exposes the functions used to provide Windows Threads related support.
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
void * Library
The library that's modifying the memory (if that's the case).
A kernel export was not found.
The object was detected after it was created.
void IntAlertEptFillFromKmOriginator(const EXCEPTION_KM_ORIGINATOR *Originator, EVENT_EPT_VIOLATION *EptViolation)
Fills kernel mode originator information inside an EPT alert.
GENERIC_ALERT gAlert
Global alert buffer.
#define INT_STATUS_ALIGNMENT_INCONSISTENCY
INTSTATUS IntSwapMemRemoveTransaction(void *Transaction)
Remove a transaction.
DWORD Size
The size of the read.
QWORD Flags
The entry that maps VirtualAddress to PhysicalAddress, together with all the control bits...
INTSTATUS IntKernVirtMemFetchDword(QWORD GuestVirtualAddress, DWORD *Data)
Reads 4 bytes from the guest kernel memory.
#define IDLE_THREAD_OFFSET_PCR
The offset of the IdleThread field inside the _KPCR.
static INTSTATUS IntWinGuestFinishInit(void)
Finalizes the Windows initialization once the entire kernel is read.
INTSTATUS IntFindKernelPcr(DWORD CpuNumber, QWORD *Pcr)
Finds the address of the Windows kernel _KPCR.
#define INT_STATUS_EXCEPTION_BLOCK
QWORD PsActiveProcessHead
Guest virtual address of the PsActiveProcessHead kernel variable.
#define INT_STATUS_ALREADY_INITIALIZED
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
QWORD PsLoadedModuleList
Guest virtual address of the PsLoadedModuleList kernel variable.
#define INT_STATUS_NOT_INITIALIZED
INTSTATUS IntSysenterRead(DWORD CpuNumber, QWORD *SysCs, QWORD *SysEip, QWORD *SysEsp)
Queries the IA32_SYSENTER_CS, IA32_SYSENTER_EIP, and IA32_SYSENTER_ESP guest MSRs.
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
The kernel image was not found.
#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...
#define CR3_OFFSET_IN_KPROCESS
The offset of the DirectoryTableBase field inside _KPROCESS.
WIN_PRODUCT_TYPE
The type of the Windows OS.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
__noreturn void IntBugCheck(void)
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
#define ZONE_EXECUTE
Used for execute violation.
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 IntCr0Read(DWORD CpuNumber, QWORD *Cr0Value)
Reads the value of the guest CR0.
INTSTATUS IntWinPfnIsMmPfnDatabase(QWORD MmPfnDatabase)
Checks if a a guest virtual address points to MmPfnDatabase.
static INTSTATUS IntWinGuestKernelHeadersInMemory(WIN_INIT_SWAP *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
Handles the swap in of the kernel MZPE headers.
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
INTSTATUS IntVeInit(void)
Initialize the VE system.
union _IMAGE_SECTION_HEADER::@209 Misc
#define INTRO_OPT_PROT_KM_IDTR
Enable interrupt descriptor-table registers protection.
QWORD IdtBase
Original IDT base.
void IntExceptUserLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_UM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a user-mode violation, dumps the code-blocks and the injection buffer...
QWORD Ssdt
Guest virtual address of the SSDT structure inside the kernel.
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
BOOLEAN GuestInitialized
True if the OS-specific portion has been initialized.
#define HpFreeAndNullWithTag(Add, Tag)
INFO_UD_PENDING * CurrentUD
The currently pending #UD injection on this CPU.
INTSTATUS IntGsRead(DWORD CpuNumber, QWORD *GsValue)
Reads the IA32_GS_BASE guest MSR.
static BOOLEAN IntWinGuestIsSystemCr3(QWORD KernelAddress, const VA_TRANSLATION *GvaTranslation, QWORD Cr3)
Checks if a Cr3 is the system Cr3.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3(QWORD Cr3)
Finds a process by its kernel CR3.
#define INT_STATUS_INVALID_DATA_STATE
Executions inside the SharedUserData region.
#define INT_STATUS_INVALID_INTERNAL_STATE
QWORD KernelVa
The guest virtual address at which the kernel image.
INTSTATUS IntWinProcIterateGuestProcesses(PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the in-guest process list and calls Callback for each entry.
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 IntWinGuestHandleSudExec(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Ept callback which handles executions inside SharedUserData.
struct _IMAGE_NT_HEADERS * PIMAGE_NT_HEADERS32
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
INTSTATUS IntWinDrvIsListHead(QWORD PsLoadedModuleListGva, void *PsLoadedModuleList, QWORD KernelLdr)
Used to identify WINDOWS_GUEST::PsLoadedModuleList.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
#define IntPeGetSectionHeaderByName(Base, Buff, Name, Cr3, Sec)
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
QWORD VirtualAddress
The guest virtual address that will be read.
#define SWAPMEM_FLAG_ASYNC_CALL
void IntWinGuestCancelKernelRead(void)
Cancels the kernel read.
static INTSTATUS IntWinGuestSectionInMemory(WIN_INIT_SWAP *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
Handles the swap in of a kernel section done while the WINDOWS_GUEST.KernelBuffer is read...
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.
static void InitializeListHead(LIST_ENTRY *ListHead)
DWORD CpuCount
The number of logical CPUs.
INTSTATUS IntWinApiHookAll(void)
Iterates through all hookable APIs and sets requested hooks.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
void IntDriverUninit(void)
Uninitializes the drivers submodule.
#define INT_STATUS_DATA_BUFFER_TOO_SMALL
INTSTATUS IntWinGetVersionString(DWORD FullStringSize, DWORD VersionStringSize, CHAR *FullString, CHAR *VersionString)
Gets the version string for a Windows guest.
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
static HOOK_GVA * gSudExecHook
The hook object protecting against executions on SharedUserData.
DWORD KernelBufferSize
The size of the KernelBuffer.
#define INT_STATUS_INVALID_DATA_VALUE
void IntWinProcUninit(void)
This function removes all process objects from the list, and registers the calls the cleanup function...
#define THS_CHECK_DETOURS
Will check if any RIP is inside detours.
INTSTATUS IntPeValidateHeader(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD ImageBaseBufferSize, INTRO_PE_INFO *PeInfo, QWORD Cr3)
Validates a PE header.
PCHAR VersionString
A NULL terminated string containing Windows version information.
INTSTATUS IntSyscallRead(DWORD CpuNumber, QWORD *SysStar, QWORD *SysLstar)
Queries the IA32_STAR, and IA32_LSTAR guest MSRs.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
#define _In_reads_bytes_(expr)
#define PROCESS_SEARCH_LIMIT_THREAD_LOWER
The lower limit of the area in which the idle process is searched.
Holds information about a Windows guest.
#define INT_STATUS_INVALID_OBJECT_TYPE
#define SWAPMEM_OPT_BP_FAULT
If set, the #PF will be generated from an int3 detour. Use this when injecting kernel PFs...
__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.
INTSTATUS IntWinDrvIterateLoadedModules(PFUNC_IterateListCallback Callback, QWORD Aux)
Used to iterate trough the WINDOWS_GUEST::PsLoadedModuleList.
INTSTATUS IntWinGuestInit(void)
Initializes a new Windows guest.
INTSTATUS IntWinProcAdd(QWORD Eprocess, QWORD Aux)
Adds a new process to the Introcore list of processes.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
INTSTATUS IntRegisterBreakpointHandler(PFUNC_IntBreakpointCallback Callback)
INTSTATUS IntWinProcIsPsActiveProcessHead(QWORD Gva)
Checks if a guest memory area is the list head of the process list (PsActiveProcessHead) ...
QWORD KeServiceDescriptorTable
Guest virtual address of the KeServiceDescriptorTable variable.
GUEST_STATE gGuest
The current guest state.
void IntAlertFillWinProcessByCr3(QWORD ProcessCr3, INTRO_PROCESS *EventProcess)
Saves information about a Windows process inside an alert. The process is searched by its kernel CR3...
struct _EXCEPTION_UM_ORIGINATOR::@72 Return
INTSTATUS IntWinIdtProtectAll(void)
Activates the IDT protection for all the guest CPUs.
INTSTATUS IntWinGuestUnprotectSudExec(void)
Removes the execution EPT hook on SharedUserData.
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
#define FIX_GUEST_POINTER(is64, x)
Masks the unused part of a Windows guest virtual address.
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
#define IMAGE_SCN_MEM_DISCARDABLE
TIMER_FRIENDLY void IntDumpBuffer(void *Buffer, QWORD Gva, DWORD Length, DWORD RowLength, DWORD ElementLength, BOOLEAN LogHeader, BOOLEAN DumpAscii)
This function dumps a given buffer in a user friendly format.
QWORD Rsp
The value of the guest RSP register at the moment of execution.
LIST_HEAD InitSwapHandles
A list of swap handles used to read KernelBuffer.
DWORD RemainingSections
The number of kernel sections not yet read into KernelBuffer.
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.
KERNEL_DRIVER * IntDriverFindByAddress(QWORD Gva)
Returns the driver in which Gva resides.
INTSTATUS IntUDAddToPendingList(const QWORD Cr3, const QWORD Rip, const QWORD Thread, INFO_UD_PENDING **CurrentPendingUD)
Add a new UD to the list of pending injections.
INTSTATUS IntSwapgsStartMitigation(void)
Scan the kernel for vulnerable SWAPGS gadgets, and mitigate CVE-2019-1125, when such gadgets are foun...
BOOLEAN KptiInstalled
True if KPTI was detected as installed (not necessarily active).
IMAGE_FILE_HEADER FileHeader
The initialization swap handle.
PAGING_MODE Mode
The paging mode used by the guest.
INTSTATUS IntWinGuestIsSupported(void)
Load os information from cami.
INTSTATUS IntCr3Read(DWORD CpuNumber, QWORD *Cr3Value)
Reads the value of the guest CR3.
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
INTSTATUS IntExceptUserGetExecOriginator(void *Process, EXCEPTION_UM_ORIGINATOR *Originator)
This function is used to get the originator for heap execution.
Encapsulates information about a virtual to physical memory translation.
BYTE * KernelBuffer
A buffer containing the entire kernel image.
KERNEL_DRIVER * KernelDriver
Points to the driver object that describes the kernel image.
void IntWinUmCacheUninit(void)
Uninit the module cache system. This will remove all cache entries. Use this during Introcore uninit...
#define INT_STATUS_NOT_SUPPORTED
INTRO_PROCESS CurrentProcess
The current process.
#define INTRO_OPT_PROT_KM_SUD_EXEC
Enable protection against executions on SharedUserData.
VCPU_STATE * gVcpu
The state of the current VCPU.
The action was blocked because there was no exception for it.
static void IntWinGuestSendSudAlert(void *Originator, EXCEPTION_VICTIM_ZONE *Victim, BOOLEAN IsKernel, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Constructs and sends an EVENT_EPT_VIOLATION alert which occurred due to an execution in SharedUserDat...
void IntAlertFillWinUmModule(const WIN_PROCESS_MODULE *Module, INTRO_MODULE *EventModule)
Fills information about a user mode module inside an alert.
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
DWORD NtBuildNumberValue
The value of the NtBuildNumber kernel variable.
INTSTATUS IntWinGuestFindIdleCr3(void)
Searches the Cr3 used by the idle process.
DWORD ActiveCpuCount
The number of CPUs actually used by the guest.
#define INTRO_OPT_PROT_KM_CR4
Enable CR4.SMEP and CR4.SMAP protection.
DWORD SizeOfImage
Size of the image.
INTRO_EXEC_INFO ExecInfo
Execution information. Valid only if Violation is IG_EPT_HOOK_EXECUTE.
Event structure for EPT violations.
#define INT_STATUS_NOT_READY
BOOLEAN Image64Bit
True if the image is 64 bit.
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
BOOLEAN DisableOnReturn
Set to True if after returning from this event handler, introcore must be unloaded.
DWORD Length
The length of the instruction.
static INTSTATUS IntWinGuestReadKernel(PBYTE KernelHeaders)
Reads the whole kernel image in memory, including swapped-out sections.
INTSTATUS IntWinAgentInjectTrampoline(void)
Inject the agent trampoline inside the guest.
unsigned long long * PQWORD
INTSTATUS IntCr4Protect(void)
Activates the Cr4 protection.
INTSTATUS IntVeDeployAgent(void)
Inject the VE agent inside the guest.
Exploitation of Remote Services.
void * SwapHandle
The actual swap handle returned by IntSwapMemRead.
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
#define IMAGE_SCN_MEM_NOT_PAGED
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.
INTSTATUS IntNotifyIntroDetectedOs(INTRO_GUEST_TYPE OsType, DWORD OsVersion, BOOLEAN Is64)
Wrapper over GLUE_IFACE.NotifyIntrospectionDetectedOs.
#define INT_STATUS_INVALID_PARAMETER_2
static INTSTATUS IntWinGuestValidateKernel(QWORD KernelBase, QWORD KernelGva, BYTE *KernelHeaders)
Validates if the presumed kernel base is the real kernel base, based on various checks.
INTSTATUS IntHandleBreakpoint(void *GuestHandle, QWORD GuestPhysicalAddress, DWORD CpuNumber)
Handle guest breakpoints.
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
QWORD Rip
Where the write/exec came.
UINT16 SizeOfOptionalHeader
INTSTATUS IntCamiGetWinSupportedList(BOOLEAN KptiInstalled, BOOLEAN Guest64, DWORD *NtBuildNumberList, DWORD *Count)
Return a list of supported Windows NtBuildNumbers.
void IntExcept(EXCEPTION_VICTIM_ZONE *Victim, void *Originator, EXCEPTION_TYPE Type, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason, INTRO_EVENT_TYPE EventClass)
This function is the entry point for the exception mechanism.
#define INTRO_OPT_PROT_KM_GDTR
Enable global descriptor-table registers protection.
static INTSTATUS IntWinGuestFindKernelObjectsInternal(void)
Finds all the objects of interest from the Windows kernel.
#define INT_STATUS_INVALID_DATA_SIZE
INTRO_MODULE ReturnModule
The module to which the current code returns to.
This structure describes a running process inside the guest.
#define INT_STATUS_INSUFFICIENT_RESOURCES