Bitdefender Hypervisor Memory Introspection
guests.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "guests.h"
6 #include "callbacks.h"
7 #include "cr_protection.h"
8 #include "decoder.h"
9 #include "dtr_protection.h"
10 #include "exceptions.h"
11 #include "gpacache.h"
12 #include "hook.h"
13 #include "hook_cr.h"
14 #include "hook_dtr.h"
15 #include "hook_msr.h"
16 #include "hook_xcr.h"
17 #include "icache.h"
18 #include "lixapi.h"
19 #include "lixidt.h"
20 #include "lixkernel.h"
21 #include "lixvdso.h"
22 #include "memcloak.h"
23 #include "memtables.h"
24 #include "msr_protection.h"
25 #include "ptfilter.h"
26 #include "slack.h"
27 #include "swapgs.h"
28 #include "swapmem.h"
29 #include "unpacker.h"
30 #include "vasmonitor.h"
31 #include "vecore.h"
32 #include "visibility.h"
33 #include "winapi.h"
34 #include "winhal.h"
35 #include "winidt.h"
36 #include "wininfinityhook.h"
37 #include "winobj.h"
38 #include "winpfn.h"
39 #include "winselfmap.h"
40 #include "wintoken.h"
41 #include "winsud.h"
42 #include "winintobj.h"
43 
51 
59 VCPU_STATE *gVcpu = NULL;
60 
63 
66 
69 
71 #define SYSCALL_SIG_FLAG_KPTI 0x80000000
72 
82 
86 static HOOK_CR *gCr3WriteHook = NULL;
87 
88 
89 void
91  _In_ INTRO_ERROR_STATE State,
93  )
100 {
101  gErrorState = State;
102  gErrorStateContext = Context;
103 }
104 
105 
108  void
109  )
115 {
116  return gErrorState;
117 }
118 
119 
122  void
123  )
129 {
130  return gErrorStateContext;
131 }
132 
133 
134 BOOLEAN
136  void
137  )
143 {
144  return gErrorState != intErrNone;
145 }
146 
147 
148 static void
150  _In_ BYTE *SyscallBuffer,
151  _In_ DWORD Size,
152  _Out_ BOOLEAN *IsKptiActive
153  )
163 {
164  INTSTATUS status;
165 
166  *IsKptiActive = FALSE;
167 
168  for (DWORD it = 0; it < Size;)
169  {
170  INSTRUX instrux;
171 
172  status = IntDecDecodeInstructionFromBuffer(SyscallBuffer + it,
173  Size - it,
175  &instrux);
176  if (!INT_SUCCESS(status))
177  {
178  it++;
179  continue;
180  }
181 
182  if (instrux.Instruction == ND_INS_MOV_CR &&
183  ND_IS_OP_REG(&instrux.Operands[0], ND_REG_CR, (DWORD)gGuest.WordSize, NDR_CR3))
184  {
185  *IsKptiActive = TRUE;
186  return;
187  }
188 
189  it += instrux.Length;
190  }
191 }
192 
193 
194 static INTSTATUS
196  _In_ QWORD SyscallHandler,
197  _Out_ INTRO_GUEST_TYPE *OsType,
198  _Out_ BOOLEAN *KptiInstalled,
199  _Out_ BOOLEAN *KptiActive
200  )
212 {
213  INTSTATUS status;
214  DWORD i, j;
215  BYTE buffer[SIG_MAX_PATTERN] = {0};
216  BOOLEAN found;
217 
218  *OsType = introGuestUnknown;
219  *KptiInstalled = FALSE;
220  *KptiActive = FALSE;
221 
222  status = IntKernVirtMemRead(SyscallHandler, sizeof(buffer), buffer, NULL);
223  if (!INT_SUCCESS(status))
224  {
225  ERROR("[ERROR] IntKernVirtMemRead failed for %llx: 0x%08x\n", SyscallHandler, status);
226  return status;
227  }
228 
230  if (!INT_SUCCESS(status))
231  {
232  ERROR("[ERROR] IntCamiLoadSection failed: 0x%08x\n", status);
233  return status;
234  }
235 
236  for (i = 0; i < gSysenterSignaturesCount; i++)
237  {
238  found = TRUE;
239 
240  for (j = 0; j < gSysenterSignatures[i].Length; j++)
241  {
242  if (gSysenterSignatures[i].Pattern[j] != 0x100 && gSysenterSignatures[i].Pattern[j] != buffer[j])
243  {
244  found = FALSE;
245  break;
246  }
247  }
248 
249  if (found)
250  {
251  TRACE("[INTRO-INIT] Found the syscall handler %d address at 0x%016llx\n", i, SyscallHandler);
252 
253  *OsType = gSysenterSignatures[i].SignatureId & 0xFF;
254  *KptiInstalled = !!(gSysenterSignatures[i].SignatureId & SYSCALL_SIG_FLAG_KPTI);
255 
256  IntGuestIsKptiActive(buffer, sizeof(buffer), KptiActive);
257 
258  status = INT_STATUS_SUCCESS;
259  goto _free_and_exit;
260  }
261  }
262 
263  LOG("Syscall/interrupt @0x%016llx handler not identified... Dumping %zu bytes from it!\n",
264  SyscallHandler, sizeof(buffer));
265 
266  for (i = 0; i < sizeof(buffer); i += 8)
267  {
268  NLOG("%02x %02x %02x %02x %02x %02x %02x %02x\n", buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3],
269  buffer[i + 4], buffer[i + 5], buffer[i + 6], buffer[i + 7]);
270  }
271 
272  status = INT_STATUS_NOT_FOUND;
273 
274 _free_and_exit:
275  HpFreeAndNullWithTag(&gSysenterSignatures, IC_TAG_CAMI);
276 
277  return status;
278 }
279 
280 
281 static INTSTATUS
283  _Out_ INTRO_GUEST_TYPE *OsType,
284  _Out_ BOOLEAN *KptiInstalled,
285  _Out_ BOOLEAN *KptiActive
286  )
297 {
298  INTSTATUS status;
299  QWORD analyzeAddress[3] = {0};
300 
301  *OsType = introGuestUnknown;
302  *KptiInstalled = FALSE;
303  *KptiActive = FALSE;
304 
305  status = IntSyscallRead(IG_CURRENT_VCPU, NULL, &analyzeAddress[0]);
306  if (!INT_SUCCESS(status))
307  {
308  ERROR("[ERROR] Failed reading SYSCALL MSRs: 0x%08x\n", status);
310  return status;
311  }
312 
313  status = IntSysenterRead(IG_CURRENT_VCPU, NULL, &analyzeAddress[1], NULL);
314  if (!INT_SUCCESS(status))
315  {
316  ERROR("[ERROR] Failed reading SYSENTER MSRs: 0x%08x\n", status);
318  return status;
319  }
320 
321  status = IntIdtGetEntry(IG_CURRENT_VCPU, VECTOR_DE, &analyzeAddress[2]);
322  if (!INT_SUCCESS(status))
323  {
324  ERROR("[ERROR] Failed reading INT 0 handler: 0x%08x\n", status);
326  return status;
327  }
328 
329  for (DWORD l = 0; l < ARRAYSIZE(analyzeAddress); l++)
330  {
331  if (analyzeAddress[l] == 0)
332  {
333  continue;
334  }
335 
336  status = IntGuestDetectOsSysCall(analyzeAddress[l], OsType, KptiInstalled, KptiActive);
337  if (INT_SUCCESS(status))
338  {
339  TRACE("[INTRO-INIT] Found the syscall/interrupt handler address at %llx\n", analyzeAddress[l]);
340 
341  return INT_STATUS_SUCCESS;
342  }
343  }
344 
345  return INT_STATUS_NOT_FOUND;
346 }
347 
348 
349 INTSTATUS
351  _Out_ PGUEST_INFO GuestInfo
352  )
362 {
363  if (NULL == GuestInfo)
364  {
366  }
367 
368  GuestInfo->Guest64 = gGuest.Guest64;
369  GuestInfo->StartupTime = IG_INVALID_TIME;
370  GuestInfo->OsVersion = gGuest.OSVersion;
371 
372  switch (gGuest.OSType)
373  {
374  case introGuestWindows:
375  {
376  QWORD time = 0;
377  INTSTATUS status;
378 
379  GuestInfo->Type = introGuestWindows;
380  GuestInfo->BuildNumber = gWinGuest->NtBuildNumberValue;
381 
382  status = IntWinGetStartUpTime(&time);
383  if (INT_SUCCESS(status))
384  {
385  GuestInfo->StartupTime = time;
386  }
387 
388  break;
389  }
390 
391  case introGuestLinux:
392  GuestInfo->Type = introGuestLinux;
393  GuestInfo->BuildNumber = gLixGuest->Version.Value;
394  break;
395 
396  default:
398  }
399 
400  return INT_STATUS_SUCCESS;
401 }
402 
403 
404 static PAGING_MODE
406  _In_opt_ QWORD Efer,
407  _In_opt_ QWORD Cr4,
408  _In_opt_ QWORD Cr0
409  )
418 {
419  INTSTATUS status;
420 
421  if (!Efer)
422  {
423  status = IntEferRead(gVcpu->Index, &Efer);
424  if (!INT_SUCCESS(status))
425  {
426  ERROR("[ERROR] IntEferRead failed: 0x%08x\n", status);
427  return PAGING_NONE;
428  }
429  }
430 
431  if (!Cr4)
432  {
433  Cr4 = gVcpu->Regs.Cr4;
434  }
435 
436  if (!Cr0)
437  {
438  Cr0 = gVcpu->Regs.Cr0;
439  }
440 
441  if (0 != (Efer & EFER_LMA) && 0 != (Cr4 & CR4_LA57))
442  {
443  return PAGING_5_LEVEL_MODE;
444  }
445  else if (0 != (Efer & EFER_LMA))
446  {
447  return PAGING_4_LEVEL_MODE;
448  }
449  else if (0 != (Cr4 & CR4_PAE))
450  {
451  return PAGING_PAE_MODE;
452  }
453  else if (0 != (Cr0 & CR0_PG))
454  {
455  return PAGING_NORMAL_MODE;
456  }
457 
458  return PAGING_NONE;
459 }
460 
461 
462 static INTSTATUS
464  void
465  )
471 {
472  INTSTATUS status;
473 
474  gGuest.Mm.Cr0 = gVcpu->Regs.Cr0;
475  gGuest.Mm.Cr4 = gVcpu->Regs.Cr4;
476 
477  status = IntEferRead(gVcpu->Index, &gGuest.Mm.Efer);
478  if (!INT_SUCCESS(status))
479  {
480  ERROR("[ERROR] IntEferRead failed: 0x%08x\n", status);
481  return status;
482  }
483 
484  gGuest.Guest64 = FALSE;
485  gGuest.PaeEnabled = FALSE;
486  gGuest.LA57 = FALSE;
487 
488  gGuest.Mm.Mode = IntGuestGetPagingMode(gGuest.Mm.Efer, gGuest.Mm.Cr4, gGuest.Mm.Cr0);
489 
490  if (PAGING_5_LEVEL_MODE == gGuest.Mm.Mode)
491  {
492  gGuest.Guest64 = TRUE;
493  gGuest.PaeEnabled = TRUE;
494  gGuest.LA57 = TRUE;
495  }
496  else if (PAGING_4_LEVEL_MODE == gGuest.Mm.Mode)
497  {
498  gGuest.Guest64 = TRUE;
499  gGuest.PaeEnabled = TRUE;
500  }
501  else if (PAGING_PAE_MODE == gGuest.Mm.Mode)
502  {
503  gGuest.PaeEnabled = TRUE;
504  }
505 
506  gGuest.WordSize = gGuest.Guest64 ? 8 : 4;
507 
508  return INT_STATUS_SUCCESS;
509 }
510 
511 
512 static INTSTATUS
514  _In_opt_ void *Context,
515  _In_ DWORD Cr,
516  _In_ QWORD OldValue,
517  _In_ QWORD NewValue,
518  _Out_ INTRO_ACTION *Action
519  )
547 {
548 #define MAX_INIT_RETRIES 32
549  INTSTATUS status, status2;
550  QWORD syscall = 0;
551  QWORD sysenter = 0;
552  INTRO_GUEST_TYPE osType;
553  BOOLEAN bKptiInstalled, bKptiActive, bSameCr3;
554 
555  UNREFERENCED_PARAMETER(Context);
557 
558  *Action = introGuestAllowed;
559 
560  if (__unlikely(gGuest.GuestInitialized))
561  {
562  ERROR("[ERROR] Introspection is already initialized, this should not happen... Remove the hook!\n");
563 
564  IntHookCrRemoveHook(gCr3WriteHook);
565  gCr3WriteHook = NULL;
566 
567  return INT_STATUS_SUCCESS;
568  }
569 
570  if (!(gVcpu->Regs.Cr0 & CR0_PG))
571  {
572  return INT_STATUS_SUCCESS;
573  }
574 
575  // Temporary initialize the gGuest.Mm (in case we want to do translations or anything)
576  status = IntGuestInitMemoryInfo();
577  if (!INT_SUCCESS(status))
578  {
579  ERROR("[ERROR] IntGuestInitMemoryInfo failed: 0x%08x\n", status);
580  return status;
581  }
582 
583  status = IntSyscallRead(IG_CURRENT_VCPU, NULL, &syscall);
584  if (!INT_SUCCESS(status))
585  {
586  ERROR("[ERROR] IntSyscallRead failed: 0x%08x\n", status);
587  return status;
588  }
589 
590  status = IntSysenterRead(IG_CURRENT_VCPU, NULL, &sysenter, NULL);
591  if (!INT_SUCCESS(status))
592  {
593  ERROR("[ERROR] IntSysenterRead failed: 0x%08x\n", status);
594  return status;
595  }
596 
597  if (0 == syscall && 0 == sysenter)
598  {
599  return INT_STATUS_SUCCESS;
600  }
601 
602  bSameCr3 = FALSE;
603 
604  switch (gGuest.Mm.Mode)
605  {
606  case PAGING_NONE:
607  // Still in 16-bit mode, nothing to do yet
608  return INT_STATUS_SUCCESS;
609 
610  case PAGING_NORMAL_MODE:
611  bSameCr3 = (NewValue & CR3_LEGACY_NON_PAE_MASK) == (OldValue & CR3_LEGACY_NON_PAE_MASK);
612  break;
613 
614  case PAGING_PAE_MODE:
615  bSameCr3 = (NewValue & CR3_LEGACY_PAE_MASK) == (OldValue & CR3_LEGACY_PAE_MASK);
616  break;
617 
618  case PAGING_4_LEVEL_MODE:
619  bSameCr3 = (NewValue & CR3_LONG_MODE_MASK) == (OldValue & CR3_LONG_MODE_MASK);
620  break;
621 
622  case PAGING_5_LEVEL_MODE:
623  ERROR("[ERROR] Guest has activated LA57 mode, we don't support it yet!\n");
624 
626 
628  }
629 
630  if (bSameCr3)
631  {
632  return INT_STATUS_SUCCESS;
633  }
634 
635  IntPauseVcpus();
636 
637  // This is the final MM info (the one which is supposed to be good)
638  status = IntGuestInitMemoryInfo();
639  if (!INT_SUCCESS(status))
640  {
641  ERROR("[ERROR] IntGuestInitMemoryInfo failed: %08x\n", status);
642  goto _resume_and_leave;
643  }
644 
645  LOG("[INTRO-INIT] Will try %d time to static init the guest on CPU %02d with EFER 0x%08llx and %s paging mode...\n",
647  gVcpu->Index, gGuest.Mm.Efer,
648  gGuest.Mm.Mode == PAGING_5_LEVEL_MODE ? "5-level" :
649  gGuest.Mm.Mode == PAGING_4_LEVEL_MODE ? "4-level" :
650  gGuest.Mm.Mode == PAGING_PAE_MODE ? "PAE" :
651  gGuest.Mm.Mode == PAGING_NORMAL_MODE ? "Normal" : "Invalid");
652 
653  for (DWORD i = 0; i < gGuest.CpuCount; i++)
654  {
655  status = IntGetGprs(i, &gGuest.VcpuArray[i].Regs);
656  if (!INT_SUCCESS(status))
657  {
658  ERROR("[ERROR] IntGetGprs failed on CPU %d: %08x\n", i, status);
659  goto _resume_and_leave;
660  }
661 
662  LOG("[INTRO-INIT] CPU %02d: CR0 = %08llx, CR3 = %016llx, CR4 = %08llx, RIP = %016llx\n",
663  i, gGuest.VcpuArray[i].Regs.Cr0, gGuest.VcpuArray[i].Regs.Cr3,
664  gGuest.VcpuArray[i].Regs.Cr4, gGuest.VcpuArray[i].Regs.Rip);
665  }
666 
667  // Temporary, until we find the actual one (os-dependent)
668  gGuest.Mm.SystemCr3 = gVcpu->Regs.Cr3;
669 
670  status = IntGuestDetectOs(&osType, &bKptiInstalled, &bKptiActive);
671  if (!INT_SUCCESS(status))
672  {
673  ERROR("[ERROR] IntGuestDetectOs failed: 0x%08x\n", status);
674  goto _resume_and_leave;
675  }
676 
677  LOG("[INTRO-INIT] Identified OS type %s\n",
678  osType == introGuestWindows ? "Windows" : "Linux");
679 
680  if (osType == introGuestWindows)
681  {
682  gGuest.KptiInstalled = bKptiInstalled;
683  gGuest.KptiActive = bKptiActive;
684 
685  TRACE("[INTRO-INIT] Guest has KPTI installed: %d, enabled: %d\n",
686  gGuest.KptiInstalled, gGuest.KptiActive);
687 
688  status = IntWinGuestNew();
689  }
690  else if (osType == introGuestLinux)
691  {
692  status = IntLixGuestNew();
693  }
694  else
695  {
697  gGuest.DisableOnReturn = TRUE;
698  }
699 
700  if (!INT_SUCCESS(status) || gGuest.DisableOnReturn)
701  {
702  goto _resume_and_leave;
703  }
704 
705  status = IntCallbacksInit();
706  if (!INT_SUCCESS(status))
707  {
708  ERROR("[ERROR] IntCallbacksInit failed: 0x%08x\n", status);
709 
710  gGuest.DisableOnReturn = TRUE;
711 
712  goto _resume_and_leave;
713  }
714 
715  TRACE("[INTRO-INIT] Callbacks initialized successfully!\n");
716 
717  // Introcore is fully initialized, we can remove the cr3 write hook
718  status2 = IntHookCrRemoveHook(gCr3WriteHook);
719  if (INT_SUCCESS(status2))
720  {
721  gCr3WriteHook = NULL;
722  }
723  else
724  {
725  ERROR("[ERROR] IntHookCrRemoveHook failed: %08x\n", status2);
726  }
727 
728 _resume_and_leave:
729  if ((++gInitRetryCount >= MAX_INIT_RETRIES) && !INT_SUCCESS(status))
730  {
731  ERROR("[ERROR] [CRITICAL] Tried %d times to init the introspection, bail out...\n", gInitRetryCount);
732 
733  gGuest.DisableOnReturn = TRUE;
734  }
735 
736  if (gGuest.DisableOnReturn)
737  {
738  ERROR("[ERROR] An error occurred in init: %08x, %d. Will uninit the introspection!\n",
739  status, gGuest.DisableOnReturn);
740 
741  if (gAbortLoad)
742  {
743  status = INT_STATUS_LOAD_ABORTED;
744  }
745  }
746 
747  IntResumeVcpus();
748 
749  return status;
750 #undef MAX_INIT_RETRIES
751 }
752 
753 
754 INTSTATUS
756  _In_ QWORD Options
757  )
774 {
775  INTSTATUS status;
776 
777  memzero(&gGuest, sizeof(gGuest));
778 
779  gInitRetryCount = 0;
780  gGuest.CoreOptions.Current = Options;
781  gGuest.CoreOptions.Original = Options;
782  gGuest.KernelBetaDetections = 0 != (Options & INTRO_OPT_KM_BETA_DETECTIONS);
784  gGuest.Mm.Mode = PAGING_NONE;
785 
786  gGuest.Initialized = TRUE;
787 
788  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_CPU_COUNT, NULL, &gGuest.CpuCount, sizeof(DWORD));
789  if (!INT_SUCCESS(status))
790  {
791  ERROR("[ERROR] IntQueryGuestInfo failed for feature CPU COUNT: 0x%08x\n", status);
792  goto _cleanup_and_exit;
793  }
794  TRACE("[INTRO-INIT] CPU_COUNT = %d \n", gGuest.CpuCount);
795 
796  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_TSC_SPEED, NULL, &gGuest.TscSpeed, sizeof(QWORD));
797  if (!INT_SUCCESS(status))
798  {
799  ERROR("[ERROR] IntQueryGuestInfo failed for feature TSC SPEED: 0x%08x\n", status);
800  return status;
801  }
802  TRACE("[INTRO-INIT] TSC speed = 0x%016llx ticks/second\n", gGuest.TscSpeed);
803 
804  // Query for supported features.
805  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_VE_SUPPORT, NULL, &gGuest.SupportVE, sizeof(BOOLEAN));
806  if (!INT_SUCCESS(status))
807  {
808  WARNING("[WARNING] IntQueryGuestInfo failed for feature #VE: 0x%08x\n", status);
809  gGuest.SupportVE = FALSE;
810  }
811 
813  if (!INT_SUCCESS(status))
814  {
815  WARNING("[WARNING] IntQueryGuestInfo failed for feature VMFUNC: 0x%08x\n", status);
816  gGuest.SupportVMFUNC = FALSE;
817  }
818 
819  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_SPP_SUPPORT, NULL, &gGuest.SupportSPP, sizeof(BOOLEAN));
820  if (!INT_SUCCESS(status))
821  {
822  WARNING("[WARNING] IntQueryGuestInfo failed for feature SPP: 0x%08x\n", status);
823  gGuest.SupportSPP = FALSE;
824  }
825 
826  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_DTR_SUPPORT, NULL, &gGuest.SupportDTR, sizeof(BOOLEAN));
827  if (!INT_SUCCESS(status))
828  {
829  WARNING("[WARNING] IntQueryGuestInfo failed for feature DTR: 0x%08x\n", status);
830  gGuest.SupportDTR = FALSE;
831  }
832 
833  LOG("[INTRO-INIT] CPU/HV support: #VE: %s, VMFUNC: %s, SPP: %s, DTR events: %s\n",
834  gGuest.SupportVE ? "yes" : "no", gGuest.SupportVMFUNC ? "yes" : "no",
835  gGuest.SupportSPP ? "yes" : "no", gGuest.SupportDTR ? "yes" : "no");
836 
837  // Start initializing sub-components.
838  gGuest.VcpuArray = HpAllocWithTag(gGuest.CpuCount * sizeof(VCPU_STATE), IC_TAG_CPUS);
839  if (NULL == gGuest.VcpuArray)
840  {
842  goto _cleanup_and_exit;
843  }
844 
845  for (DWORD i = 0; i < gGuest.CpuCount; i++)
846  {
847  gGuest.VcpuArray[i].Index = i;
848  // For now, assume that the guest is using this VCPU
849  // For Windows guests this may change in IntWinGetActiveCpuCount
850  gGuest.VcpuArray[i].Initialized = TRUE;
851  }
852 
853  gVcpu = &gGuest.VcpuArray[IntGetCurrentCpu()];
854 
855  IntStatsInit();
856  TRACE("[INTRO-INIT] Stats module initialized successfully!\n");
857 
858  status = IntHookInit();
859  if (!INT_SUCCESS(status))
860  {
861  ERROR("[ERROR] IntHookInit failed: 0x%08x\n", status);
862  goto _cleanup_and_exit;
863  }
864  TRACE("[INTRO-INIT] New Hook module initialized successfully!\n");
865 
866  status = IntHookMsrInit();
867  if (!INT_SUCCESS(status))
868  {
869  ERROR("[ERROR] IntHookMsrInit failed: 0x%08x\n", status);
870  goto _cleanup_and_exit;
871  }
872  TRACE("[INTRO-INIT] MSR Hook module initialized successfully!\n");
873 
874  status = IntHookDtrInit();
875  if (!INT_SUCCESS(status))
876  {
877  ERROR("[ERROR] IntHookDtrInit failed: 0x%08x\n", status);
878  goto _cleanup_and_exit;
879  }
880  TRACE("[INTRO-INIT] DTR Hook module initialized successfully!\n");
881 
882  status = IntHookCrInit();
883  if (!INT_SUCCESS(status))
884  {
885  ERROR("[ERROR] IntHookCrInit failed: 0x%08x\n", status);
886  goto _cleanup_and_exit;
887  }
888  TRACE("[INTRO-INIT] CR Hook module initialized successfully!\n");
889 
890  status = IntHookXcrInit();
891  if (!INT_SUCCESS(status))
892  {
893  ERROR("[ERROR] IntHookXcrInit failed: 0x%08x\n", status);
894  goto _cleanup_and_exit;
895  }
896  TRACE("[INTRO-INIT] XCR Hook module initialized successfully!\n");
897 
898  status = IntIcCreate((PINS_CACHE *)&gGuest.InstructionCache, 512, 16, 512);
899  if (!INT_SUCCESS(status))
900  {
901  ERROR("[ERROR] IntIcCreate failed: 0x%08x\n", status);
902  goto _cleanup_and_exit;
903  }
904  TRACE("[INTRO-INIT] Instruction cache module initialized successfully!\n");
905 
906  // Init the GPA cache (on USER_MODE is bigger, because we have more memory)
907 #ifndef USER_MODE
908  status = IntGpaCacheInit((PGPA_CACHE *)&gGuest.GpaCache, 256, 4);
909 #else
910  status = IntGpaCacheInit((PGPA_CACHE *)&gGuest.GpaCache, 512, 8);
911 #endif // !USER_MODE
912  if (!INT_SUCCESS(status))
913  {
914  ERROR("[ERROR] IntGpaCacheInit failed: 0x%08x\n", status);
915  goto _cleanup_and_exit;
916  }
917  TRACE("[INTRO-INIT] GPA cache module initialized successfully!\n");
918 
919  status = IntSwapMemInit();
920  if (!INT_SUCCESS(status))
921  {
922  ERROR("[ERROR] IntSwapMemInit failed: 0x%08x\n", status);
923  goto _cleanup_and_exit;
924  }
925  TRACE("[INTRO-INIT] Swapmem module initialized successfully!\n");
926 
927  status = IntVasInit();
928  if (!INT_SUCCESS(status))
929  {
930  ERROR("[ERROR] IntVasInit failed: 0x%08x\n", status);
931  goto _cleanup_and_exit;
932  }
933  TRACE("[INTRO-INIT] VAS Monitor module initialized successfully!\n");
934 
935  status = IntExceptInit();
936  if (!INT_SUCCESS(status))
937  {
938  ERROR("[ERROR] IntExceptInit failed: 0x%08x\n", status);
939  goto _cleanup_and_exit;
940  }
941  TRACE("[INTRO-INIT] Kernel-mode exception module initialized successfully!\n");
942 
943  // If both VE and PT options are set, choose only one, depending on whether #VE is active or not.
945  {
946  gGuest.PtFilterFlagRemoved = FALSE;
947 
948  if (gGuest.VeInitialized)
949  {
950  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, "
951  "will ignore INTRO_OPT_IN_GUEST_PT_FILTER, because #VE is initialized!\n");
953  gGuest.PtFilterFlagRemoved = TRUE;
954  }
955  else
956  {
957  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, "
958  "will ignore INTRO_OPT_VE, because #VE is NOT initialized!\n");
959  gGuest.CoreOptions.Current &= ~INTRO_OPT_VE;
960  }
961  }
962 
963  // After we initialized all the subsystems, hook CR3 writes so we can gracefully init the rest
964  status = IntHookCrSetHook(3, 0, IntGuestHandleCr3Write, NULL, &gCr3WriteHook);
965  if (!INT_SUCCESS(status))
966  {
967  ERROR("[ERROR] IntHookCrSetHook failed: 0x%08x\n", status);
968  goto _cleanup_and_exit;
969  }
970 
971  status = INT_STATUS_SUCCESS;
972 
973 _cleanup_and_exit:
974  if (!INT_SUCCESS(status))
975  {
976  IntGuestUninit();
977  }
978 
979  return status;
980 }
981 
982 
983 void
985  void
986  )
996 {
997  if (gGuest.UninitPrepared)
998  {
999  return;
1000  }
1001 
1003 
1005 
1007 
1009 
1011 
1012  IntMtblDisable();
1013 
1014  IntSwapgsDisable();
1015 
1016  if (gGuest.OSType == introGuestWindows)
1017  {
1018  IntWinObjCleanup();
1019 
1021  }
1022 
1023  if (gCr3WriteHook)
1024  {
1025  IntHookCrRemoveHook(gCr3WriteHook);
1026  gCr3WriteHook = NULL;
1027  }
1028 
1030 
1031  gGuest.UninitPrepared = TRUE;
1032 }
1033 
1034 
1035 void
1037  void
1038  )
1049 {
1050  // We dump some statistics to know what happened while Introcore was running.
1052  IntStatsDumpAll();
1053 
1054  if (gCr3WriteHook)
1055  {
1056  IntHookCrRemoveHook(gCr3WriteHook);
1057  gCr3WriteHook = NULL;
1058  }
1059 
1060  if (gGuest.OSType == introGuestWindows)
1061  {
1062  TRACE("[INTRO-UNINIT] Uninit the Windows guest...\n");
1064  }
1065  else if (gGuest.OSType == introGuestLinux)
1066  {
1067  TRACE("[INTRO-UNINIT] Uninit the Linux guest...\n");
1069  }
1070 
1071  TRACE("[INTRO-UNINIT] Uninit #VE...\n");
1072  IntVeUnInit();
1073 
1074  TRACE("[INTRO-UNINIT] Uninit exceptions...\n");
1075  IntExceptUninit();
1076 
1077  TRACE("[INTRO-UNINIT] Uninit integrity...\n");
1079 
1080  TRACE("[INTRO-UNINIT] Uninit VAS monitor...\n");
1081  IntVasUnInit();
1082 
1083  TRACE("[INTRO-UNINIT] Uninit memory tables...\n");
1084  IntMtblUninit();
1085 
1086  TRACE("[INTRO-UNINIT] Uninit SWAPGS mitigations...\n");
1087  IntSwapgsUninit();
1088 
1089  TRACE("[INTRO-UNINIT] Uninit detours-guest...\n");
1090  IntDetUninit();
1091 
1092  TRACE("[INTRO-UNINIT] Uninit slack...\n");
1093  IntSlackUninit();
1094 
1095  TRACE("[INTRO-UNINIT] Uninit instruction cache...\n");
1096  if (NULL != gGuest.InstructionCache)
1097  {
1099  }
1100 
1101  TRACE("[INTRO-UNINIT] Uninit memcloak...\n");
1102  IntMemClkUnInit();
1103 
1104  TRACE("[INTRO-UNINIT] Uninit swapmem...\n");
1105  IntSwapMemUnInit();
1106 
1107  if (gGuest.OSType == introGuestWindows)
1108  {
1109  // Page-lock uninit. Do it after detours and memclk (they have references to it)
1110  TRACE("[INTRO-UNINIT] Uninit windows pfn locks...\n");
1111  IntWinPfnUnInit();
1112  }
1113 
1114  TRACE("[INTRO-UNINIT] Uninit unpack...\n");
1115  IntUnpUninit();
1116 
1117  TRACE("[INTRO-UNINIT] Uninit new hooks...\n");
1118  IntHookUninit();
1119 
1120  TRACE("[INTRO-UNINIT] Uninit hooker-msr...\n");
1121  IntHookMsrUninit();
1122 
1123  TRACE("[INTRO-UNINIT] Uninit hooker-dtr...\n");
1124  IntHookDtrUninit();
1125 
1126  TRACE("[INTRO-UNINIT] Uninit hooker-cr...\n");
1127  IntHookCrUninit();
1128 
1129  TRACE("[INTRO-UNINIT] Uninit hooker-xcr...\n");
1130  IntHookXcrUninit();
1131 
1132  TRACE("[INTRO-UNINIT] Uninit GPA cache...\n");
1133  if (NULL != gGuest.GpaCache)
1134  {
1136  }
1137 
1138  // The callbacks must be uninitialized AFTER the detours. Otherwise, we may end up with a pending event
1139  // after we have removed the callbacks but before we have removed the detours. This way, we would erroneously
1140  // emulate the attempt instead of faking the original content.
1141  TRACE("[INTRO-UNINIT] Uninit callbacks...\n");
1143 
1144  TRACE("[INTRO-UNINIT] Free cami protected processes array ...\n");
1146 
1147  if (NULL != gGuest.VcpuArray)
1148  {
1150  }
1151 
1152  gWinGuest = NULL;
1153  gLixGuest = NULL;
1154 
1155  TRACE("Calling the notification callback...\n");
1156 
1158 
1159  memzero(&gGuest, sizeof(gGuest));
1160 
1161  TRACE("All done!\n");
1162 }
1163 
1164 
1165 static BOOLEAN
1167  void
1168  )
1178 {
1179  INTSTATUS status;
1180  AG_WAITSTATE agWaitState;
1181  DWORD agTag;
1182 
1183  agWaitState = IntAgentGetState(&agTag);
1184  if (agWaitState != agNone)
1185  {
1186  WARNING("[SAFENESS] We have a %s agent with tag %u!\n",
1187  agWaitState == agActive ? "Active" : "Waiting", agTag);
1188  return FALSE;
1189  }
1190 
1193  if (INT_STATUS_CANNOT_UNLOAD == status)
1194  {
1195  return FALSE;
1196  }
1197 
1198  return TRUE;
1199 }
1200 
1201 
1202 INTSTATUS
1204  _In_ QWORD Flags
1205  )
1219 {
1220  INTSTATUS status = INT_STATUS_SUCCESS;
1221 
1222  IntPauseVcpus();
1223 
1224  if (gGuest.EnterHibernate)
1225  {
1226  LOG("Introcore shutdown requested while the guest is transitioning into hibernate...\n");
1227  }
1228 
1229  if (gGuest.BugCheckInProgress)
1230  {
1231  Flags |= IG_DISABLE_IGNORE_SAFENESS;
1232  }
1233 
1235  {
1238  }
1239 
1241 
1242  // Unless the caller specified to ignore it, we check all the threads so they won't return into our
1243  // detours/memtables/agents/etc. stubs.
1244  if (!!(Flags & IG_DISABLE_IGNORE_SAFENESS))
1245  {
1246  LOG("[INFO] Ignore safeness!\n");
1247  goto do_uninit;
1248  }
1249 
1250  if (!IntGuestIsSafeToDisable())
1251  {
1252  LOG("[INFO] It's not safe to unload yet!\n");
1253 
1254  status = INT_STATUS_CANNOT_UNLOAD;
1255  goto resume_and_exit;
1256  }
1257 
1258  if (gGuest.OSType == introGuestLinux)
1259  {
1261 
1263  {
1264  status = INT_STATUS_CANNOT_UNLOAD;
1265  goto resume_and_exit;
1266  }
1267  }
1268 
1269 do_uninit:
1270  IntGuestUninit();
1271 
1272 resume_and_exit:
1273  IntResumeVcpus();
1274 
1275  return status;
1276 }
1277 
1278 
1279 INTSTATUS
1281  _In_ DWORD Options
1282  )
1292 {
1293  INTSTATUS status;
1294  BOOLEAN skipAgentActivation = FALSE;
1295 
1296  if (__unlikely((Options & POST_RETRY_PERFAGENT) && gGuest.PtFilterWaiting))
1297  {
1298  LOG("[PTCORE] Will try to reinject the PT Filter...\n");
1299  status = IntPtiInjectPtFilter();
1300  if (!INT_SUCCESS(status))
1301  {
1302  ERROR("[ERROR] IntPtiInjectPtFilter failed: 0x%08x\n", status);
1303  }
1304  else
1305  {
1306  gGuest.PtFilterWaiting = FALSE;
1307  skipAgentActivation = TRUE;
1308  LOG("[PTCORE] PT Filter was re-injected with success!\n");
1309  }
1310  }
1311  else if (__unlikely((Options & POST_RETRY_PERFAGENT) && gGuest.VeAgentWaiting))
1312  {
1313  LOG("[VECORE] Will try to reinject the #VE Agent...\n");
1314  status = IntVeDeployAgent();
1315  if (!INT_SUCCESS(status))
1316  {
1317  ERROR("[ERROR] IntVeDeployAgent failed: 0x%08x\n", status);
1318  }
1319  else
1320  {
1321  gGuest.VeAgentWaiting = FALSE;
1322  skipAgentActivation = TRUE;
1323  LOG("[VECORE] The #VE Agent was re-injected with success!\n");
1324  }
1325  }
1326 
1327  if (!skipAgentActivation)
1328  {
1329  // Always try to wake up a pending agent, if there are any, except for when we successfully re-injected the PT
1330  // Filter.
1331  status = IntAgentActivatePendingAgent();
1332  if (!INT_SUCCESS(status))
1333  {
1334  ERROR("[ERROR] IntAgentActivatePendingAgent failed: 0x%08x\n", status);
1335  }
1336  }
1337 
1338  if (__likely(Options & POST_COMMIT_MEM))
1339  {
1340  status = IntHookCommitAllHooks();
1341  if (!INT_SUCCESS(status))
1342  {
1343  ERROR("[ERROR] IntHookCommitAllHooks failed: 0x%08x\n", status);
1344  }
1345  }
1346 
1347  if (Options & POST_COMMIT_MSR)
1348  {
1349  status = IntHookMsrCommit();
1350  if (!INT_SUCCESS(status))
1351  {
1352  ERROR("[ERROR] IntHookMsrCommit failed: 0x%08x\n", status);
1353  }
1354  }
1355 
1356  if (Options & POST_COMMIT_DTR)
1357  {
1358  status = IntHookDtrCommit();
1359  if (!INT_SUCCESS(status))
1360  {
1361  ERROR("[ERROR] IntHookDtrCommit failed: 0x%08x\n", status);
1362  }
1363  }
1364 
1365  if (Options & POST_COMMIT_CR)
1366  {
1367  status = IntHookCrCommit();
1368  if (!INT_SUCCESS(status))
1369  {
1370  ERROR("[ERROR] IntHookCrCommit failed: 0x%08x\n", status);
1371  }
1372  }
1373 
1374  if (Options & POST_COMMIT_XCR)
1375  {
1376  status = IntHookXcrCommit();
1377  if (!INT_SUCCESS(status))
1378  {
1379  ERROR("[ERROR] IntHookXcrCommit failed: 0x%08x\n", status);
1380  }
1381  }
1382 
1383  if (__likely(Options & POST_INJECT_PF))
1384  {
1385  status = IntSwapMemInjectPendingPF();
1386  if (!INT_SUCCESS(status))
1387  {
1388  ERROR("[ERROR] IntSwapMemInjectPendingPF failed: 0x%08x\n", status);
1389  }
1390  }
1391 
1392  return INT_STATUS_SUCCESS;
1393 }
1394 
1395 
1396 void
1398  _In_ QWORD NewOptions
1399  )
1408 {
1409  // We must save them in case an update comes which removes a previously set ForceOff (and the NewOptions set it too)
1410  gGuest.ShemuOptions.Original = NewOptions;
1411 
1412  NewOptions &= ~gGuest.ShemuOptions.ForceOff;
1413 
1414  if (NewOptions == gGuest.ShemuOptions.Current)
1415  {
1416  return;
1417  }
1418 
1419  LOG("[DYNOPT] Change shemu options from %llx to %llx\n", gGuest.ShemuOptions.Current, NewOptions);
1420 
1421  gGuest.ShemuOptions.Current = NewOptions;
1422 }
1423 
1424 
1425 void
1427  _In_ QWORD NewOptions
1428  )
1437 {
1438  // We must save them in case an update comes which removes a previously set ForceOff (and the NewOptions set it too)
1439  gGuest.CoreOptions.Original = NewOptions;
1440 
1441  NewOptions &= ~gGuest.CoreOptions.ForceOff;
1442 
1443  if (NewOptions == gGuest.CoreOptions.Current)
1444  {
1445  return;
1446  }
1447 
1448  if (gGuest.UninitPrepared)
1449  {
1450  WARNING("[WARNING] Cannot modify options now, an uninit is pending!\n");
1451  return;
1452  }
1453 
1454  if (!!(NewOptions & INTRO_OPT_IN_GUEST_PT_FILTER) && !!(NewOptions & INTRO_OPT_VE))
1455  {
1456  gGuest.PtFilterFlagRemoved = FALSE;
1457 
1458  if (gGuest.VeInitialized)
1459  {
1460  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, will ignore"
1461  "INTRO_OPT_IN_GUEST_PT_FILTER, because #VE is initialized!\n");
1462  NewOptions &= ~INTRO_OPT_IN_GUEST_PT_FILTER;
1463  gGuest.PtFilterFlagRemoved = TRUE;
1464  }
1465  else
1466  {
1467  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, will ignore INTRO_OPT_VE, "
1468  "because #VE is NOT initialized!\n");
1469  NewOptions &= ~INTRO_OPT_VE;
1470  }
1471  }
1472 
1473  LOG("[DYNOPT] Change core options from %llx to %llx\n", gGuest.CoreOptions.Current, NewOptions);
1474 
1475  gGuest.CoreOptions.Current = NewOptions;
1478 
1479  // We don't know what os this is, or we can't apply options yet... we can bail out now.
1480  if (!gGuest.GuestInitialized || !gGuest.SafeToApplyOptions)
1481  {
1482  return;
1483  }
1484 
1485  IntPauseVcpus();
1486 
1487  if (introGuestWindows == gGuest.OSType)
1488  {
1489  // Enable or disable detours, depending on active options.
1491 
1492  // Enable or disable driver object and fast I/O dispatch table hooks.
1493  // Covers INTRO_OPT_PROT_KM_DRVOBJ.
1495 
1496  // Enable or disable nt, hal, core, av and xen drivers protection.
1497  // Covers INTRO_OPT_PROT_KM_NT, INTRO_OPT_PROT_KM_SSDT, INTRO_OPT_PROT_KM_HAL,
1498  // INTRO_OPT_PROT_KM_NT_DRIVERS, INTRO_OPT_PROT_KM_AV_DRIVERS and INTRO_OPT_PROT_KM_XEN_DRIVERS
1500 
1501  // Enable or disable hal dispatch table, hal heap and hal interrupt controller protection.
1502  // Covers INTRO_OPT_PROT_KM_HAL_DISP_TABLE, INTRO_OPT_PROT_KM_HAL_HEAP_EXEC and INTRO_OPT_PROT_KM_HAL_INT_CTRL.
1504 
1505  // Enable or disable process protection.
1506  // Covers INTRO_OPT_PROT_UM_MISC_PROCS and INTRO_OPT_PROT_UM_SYS_PROCS.
1508 
1510  {
1512  }
1513  else
1514  {
1516  }
1517 
1519  {
1521  }
1522  else
1523  {
1525  }
1526 
1528  {
1529  IntCr4Protect();
1530  }
1531  else
1532  {
1533  IntCr4Unprotect();
1534  }
1535 
1536  // INTRO_OPT_PROT_KM_SYSTEM_CR3 and INTRO_OPT_PROT_KM_TOKEN_PTR are tested directly in the timer, so no need
1537  // to do anything here.
1538  // All the other options are not protection related and can be toggled as well.
1539 
1540  // First of, schedule agents removal.
1541  if (!(gGuest.CoreOptions.Current & INTRO_OPT_IN_GUEST_PT_FILTER))
1542  {
1544  }
1545 
1546  if (!(gGuest.CoreOptions.Current & INTRO_OPT_VE))
1547  {
1548  IntVeRemoveAgent(0);
1549  }
1550 
1551  if (gGuest.CoreOptions.Current & INTRO_OPT_IN_GUEST_PT_FILTER)
1552  {
1554  }
1555 
1556  if (gGuest.CoreOptions.Current & INTRO_OPT_VE)
1557  {
1558  IntVeDeployAgent();
1559  }
1560 
1562  {
1564  }
1565  else
1566  {
1568  }
1569 
1571  {
1572  IntIdtrProtect();
1573  }
1574  else
1575  {
1576  IntIdtrUnprotect();
1577  }
1578 
1580  {
1581  IntGdtrProtect();
1582  }
1583  else
1584  {
1585  IntGdtrUnprotect();
1586  }
1587 
1589  {
1591  }
1592  else
1593  {
1595  }
1596 
1598  {
1600  }
1601  else
1602  {
1604  }
1605 
1607  {
1609  }
1610  else
1611  {
1613  }
1614 
1616  {
1618  }
1619  else
1620  {
1622  }
1623 
1625  {
1627  }
1628  else
1629  {
1631  }
1632 
1634  {
1636  }
1637  else
1638  {
1640  }
1641  }
1642  else if (introGuestLinux == gGuest.OSType)
1643  {
1644  // Enable or disable detours, depending on active options.
1646 
1648  {
1650  }
1651  else
1652  {
1654  }
1655 
1657  {
1659  }
1660  else
1661  {
1663  }
1664 
1666  {
1668  }
1669  else
1670  {
1672  }
1673 
1675  {
1677  }
1678  else
1679  {
1681  }
1682 
1684  {
1685  IntCr4Protect();
1686  }
1687  else
1688  {
1689  IntCr4Unprotect();
1690  }
1691 
1693  {
1695  }
1696  else
1697  {
1699  }
1700 
1702  {
1703  IntIdtrProtect();
1704  }
1705  else
1706  {
1707  IntIdtrUnprotect();
1708  }
1709 
1711  {
1712  IntGdtrProtect();
1713  }
1714  else
1715  {
1716  IntGdtrUnprotect();
1717  }
1718 
1719  // INTRO_OPT_PROT_KM_TOKEN_PTR is checked before integrity checks for creds.
1720 
1722 
1724  }
1725  else
1726  {
1727  WARNING("[WARNING] Unknown os type %d.\n", gGuest.OSType);
1728  }
1729 
1730  IntResumeVcpus();
1731 }
1732 
1733 
1734 INTSTATUS
1736  _Out_ QWORD *MaxGpa
1737  )
1749 {
1750 
1751  if (gGuest.Mm.LastGpa == 0)
1752  {
1753  QWORD maxGpfn = 0;
1754  INTSTATUS status = IntGetMaxGpfn(&maxGpfn);
1755 
1756  if (!INT_SUCCESS(status))
1757  {
1758  ERROR("[ERROR] IntGetMaxGpfn failed: 0x%08x\n", status);
1759  return status;
1760  }
1761 
1762  // IntGetMaxGpfn will return the last accessible page frame number, we need to set LastGpa to the next page
1763  gGuest.Mm.LastGpa = (maxGpfn << 12) + PAGE_SIZE;
1764  }
1765 
1766  *MaxGpa = gGuest.Mm.LastGpa;
1767  return INT_STATUS_SUCCESS;
1768 }
void IntUnpUninit(void)
Uninit the unpacker. This will stop the monitor on all pages.
Definition: unpacker.c:505
#define INT_STATUS_GUEST_OS_NOT_SUPPORTED
Indicates that the guest operating system is not supported.
Definition: introstatus.h:446
#define THS_CHECK_SWAPGS
Will check if any RIP is inside a mitigated SWAPGS gadget.
INTSTATUS IntHookXcrCommit(void)
Commit the extended control register hooks.
Definition: hook_xcr.c:169
#define _In_opt_
Definition: intro_sal.h:16
INTSTATUS IntLixGuestNew(void)
Starts the initialization and enable protection for a new Linux guest.
Definition: lixguest.c:2561
INTSTATUS IntPtiInjectPtFilter(void)
Inject the PT filter inside the guest.
Definition: ptfilter.c:1676
#define VECTOR_DE
Definition: processor.h:104
#define __unlikely(x)
Definition: common.h:64
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
INTSTATUS IntWinDrvUpdateProtection(void)
Used to update the protection for all the loaded modules (gKernelDrivers).
Definition: windriver.c:1751
BOOLEAN SupportDTR
Set to True if support for DTR access exits was detected.
Definition: guests.h:358
INTSTATUS IntGuestInit(QWORD Options)
Initialize the given guest state.
Definition: guests.c:755
#define INTRO_OPT_VE
Enable the Virtualization exception page table access pre-filtering agent (64-bit Windows only)...
Definition: intro_types.h:475
#define IC_TAG_CAMI
Live update allocations.
Definition: memtags.h:124
void IntCamiClearUpdateBuffer(void)
Uninitialize the update buffer and notify the integrator that we don&#39;t need it anymore.
Success.
Definition: intro_types.h:2435
INTSTATUS IntVasUnInit(void)
Uninit the VAS monitor state.
Definition: vasmonitor.c:1143
DWORD gSysenterSignaturesCount
The number of entries in the gSysenterSignatures array.
Definition: guests.c:81
Commit all the MSR hooks.
Definition: guests.h:437
INTSTATUS IntHookInit(void)
Initialize the global hook system.
Definition: hook.c:165
INTSTATUS IntIdtrUnprotect(void)
Remove the IDTR protection.
uint8_t BYTE
Definition: intro_types.h:47
void IntSwapgsDisable(void)
Disable SWAPGS mitigations. Must be used only for PrepareUninit.
Definition: swapgs.c:501
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
Definition: winguest.c:37
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:59
#define CR0_PG
Definition: processor.h:40
No active/pending agents.
Definition: agent.h:15
IG_ARCH_REGS Regs
The current state of the guest registers.
Definition: guests.h:95
INTSTATUS IntIdtGetEntry(DWORD CpuNumber, DWORD Entry, QWORD *Handler)
Get the handler of an interrupt from the IDT.
Definition: introcpu.c:145
DWORD Index
The VCPU number.
Definition: guests.h:172
INTSTATUS IntIdtrProtect(void)
Enable IDTR protection.
INTSTATUS IntLixKernelReadProtect(void)
Activates kernel protection.
Definition: lixkernel.c:781
BOOLEAN Initialized
True if the VCPU is initialized and used by the guest, False if it is not.
Definition: guests.h:199
#define _In_
Definition: intro_sal.h:21
INTSTATUS IntAgentActivatePendingAgent(void)
Activate a pending Windows or Linux agent.
Definition: agent.c:70
INTSTATUS IntHookCommitAllHooks(void)
Commits all the hooks.
Definition: hook.c:12
QWORD SystemCr3
The Cr3 used to map the kernel.
Definition: guests.h:211
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
QWORD Efer
Definition: guests.h:214
INTSTATUS IntGetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Get the current guest GPR state.
Definition: introcpu.c:827
INTSTATUS IntVasInit(void)
Initialize the VAS monitor state.
Definition: vasmonitor.c:1125
#define INTRO_OPT_PROT_KM_LX
Enable kernel image protection (Linux only).
Definition: intro_types.h:409
static INTSTATUS IntGuestDetectOs(INTRO_GUEST_TYPE *OsType, BOOLEAN *KptiInstalled, BOOLEAN *KptiActive)
Detect the type of the currently running guest kernel.
Definition: guests.c:282
Get the availability of the IDTR/GDTR exits.
Definition: glueiface.h:288
static PAGING_MODE IntGuestGetPagingMode(QWORD Efer, QWORD Cr4, QWORD Cr0)
Get the paging mode used by the guest on the current VCPU.
Definition: guests.c:405
BOOLEAN SysprocBetaDetections
Definition: guests.h:304
INTSTATUS IntHookCrSetHook(DWORD Cr, DWORD Flags, PFUNC_CrWriteHookCallback Callback, void *Context, HOOK_CR **Hook)
Set a control register write hook.
Definition: hook_cr.c:11
void IntWinPfnUnInit(void)
Uninits the PFN locks.
Definition: winpfn.c:922
static void IntGuestIsKptiActive(BYTE *SyscallBuffer, DWORD Size, BOOLEAN *IsKptiActive)
Checks if the Syscall handler is specific to a System with KPTI enabled.
Definition: guests.c:149
DWORD IntGetCurrentCpu(void)
Returns the current CPU number.
Definition: introcpu.c:802
void IntDetUninit(void)
Uninitializes the detour module.
Definition: detours.c:1868
BOOLEAN Initialized
True if this structure was initialized and can be used.
Definition: guests.h:289
INTSTATUS IntWinInfHookProtect(void)
This function initializes protection against infinity hook mechanism.
INTSTATUS IntHookMsrInit(void)
Initialize the model specific registers hook state.
Definition: hook_msr.c:262
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
INTSTATUS IntWinSudProtectIntegrity(void)
Initializes the SharedUserData integrity protection.
Definition: winsud.c:1099
INTSTATUS IntWinTokenUnprotectPrivs(void)
Unprotects all the currently protected tokens belonging to processes against privileges manipulation...
Definition: wintoken.c:1299
A critical structure was not found inside the guest kernel.
Definition: intro_types.h:2441
#define CR3_LONG_MODE_MASK
Definition: pgtable.h:112
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
Definition: introcore.c:2355
void IntStatsInit(void)
Initialization routine.
Definition: stats.c:448
#define ARRAYSIZE(A)
Definition: introdefs.h:101
void IntWinApiUpdateHooks(void)
Iterate through all hookable APIs and enable or disable them according to the current Introcore optio...
Definition: winapi.c:317
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
Definition: guests.h:303
#define INTRO_OPT_PROT_KM_LX_TEXT_READS
Enable kernel &#39;_text&#39; section read protection (Linux only).
Definition: intro_types.h:499
INTSTATUS IntHookCrUninit(void)
Uninit the control register hooks state.
Definition: hook_cr.c:295
BOOLEAN SafeToApplyOptions
True if the current options can be changed dynamically.
Definition: guests.h:294
INTSTATUS IntWinTokenProtectPrivs(void)
Protects all the currently unprotected tokens belonging to processes against privileges manipulation...
Definition: wintoken.c:1258
INTSTATUS IntGpaCacheInit(PGPA_CACHE *Cache, DWORD LinesCount, DWORD EntriesCount)
Initialize a GPA cache.
Definition: gpacache.c:115
#define ERROR(fmt,...)
Definition: glue.h:62
void IntWinObjCleanup(void)
Cleans up any resources allocated by the object search.
Definition: winobj.c:2080
INTSTATUS IntHookDtrCommit(void)
Commit the descriptor registers hooks.
Definition: hook_dtr.c:165
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
int INTSTATUS
The status data type.
Definition: introstatus.h:24
The operating system version is not supported.
Definition: intro_types.h:2437
INTSTATUS IntHookXcrInit(void)
Initialize the extended control registers hook state.
Definition: hook_xcr.c:207
INTSTATUS IntMsrSyscallProtect(void)
Enable protection for all SYSCALL and SYSENTER MSRs.
DWORD OSVersion
Os version.
Definition: guests.h:281
INTSTATUS IntGetMaxGpfn(QWORD *MaxGpfn)
Get the last physical page frame number accessible by the guest.
Definition: introcpu.c:1273
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
BOOLEAN SupportVMFUNC
Set to True if support for VMFUNC was detected.
Definition: guests.h:356
INTSTATUS IntQueryGuestInfo(DWORD InfoClass, void *InfoParam, void *Buffer, DWORD BufferLength)
Definition: glue.c:226
INTSTATUS IntMemClkUnInit(void)
Uninits the memory cloak subsystem.
Definition: memcloak.c:1169
void IntSwapgsUninit(void)
Uninit the SWAPGS mitigation.
Definition: swapgs.c:446
INTSTATUS IntExceptUninit(void)
This function removes and frees all exceptions and signatures.
Definition: exceptions.c:513
INTSTATUS IntWinIntObjProtect(void)
Protects the interrupt objects which are present in the KPRCB&#39;s InterruptObject array.
Definition: winintobj.c:473
#define INTRO_OPT_PROT_KM_SUD_INTEGRITY
Enable integrity checks over various SharedUserData fields, as well as the zero-filled zone after the...
Definition: intro_types.h:528
INTSTATUS IntSwapMemInit(void)
Init the swapmem system.
Definition: swapmem.c:1026
static HOOK_CR * gCr3WriteHook
The Cr2 write hook handle used for initialization.
Definition: guests.c:86
INTSTATUS IntCallbacksUnInit(void)
Uninit all the Introcore callbacks.
Definition: callbacks.c:3576
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
Definition: guests.h:372
#define INT_STATUS_LOAD_ABORTED
Indicates that Introcore loading was aborted.
Definition: introstatus.h:454
INTSTATUS IntIcCreate(INS_CACHE **Cache, DWORD LinesCount, DWORD EntriesCount, DWORD InvCount)
Create anew instruction cache.
Definition: icache.c:1086
INTSTATUS IntCr4Unprotect(void)
Disables the CR4 protection.
INTSTATUS IntHookXcrUninit(void)
Uninit the extended control register hooks state.
Definition: hook_xcr.c:230
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
Definition: introcore.c:2320
void IntLixVdsoUnprotect(void)
Remove protection for the vDSO image and VSYSCALL.
Definition: lixvdso.c:928
#define INTRO_OPT_PROT_KM_IDT
Definition: intro_types.h:412
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:278
BOOLEAN VeAgentWaiting
True if the #VE agent was not yet injected, but it should be.
Definition: guests.h:352
INTSTATUS IntSwapMemUnInit(void)
Uninit the swapmem system.
Definition: swapmem.c:1044
Commit all the memory hooks.
Definition: guests.h:436
INTSTATUS IntHookDtrUninit(void)
Uninit the descriptor registers hooks state.
Definition: hook_dtr.c:226
QWORD Cr4
Cr4 value used when deducing the paging mode.
Definition: guests.h:212
INTSTATUS IntVeUnInit(void)
Uninit the VE system.
Definition: vecore.c:2654
INTSTATUS IntThrSafeCheckThreads(QWORD Options)
Checks if any of the guest threads have their RIP or have any stack pointers pointing to regions of c...
void IntLixGuestUninitGuestCode(void)
Removes the EPT hooks from detours/agents memory zone and clears these memory zones.
Definition: lixguest.c:2524
void IntLixApiUpdateHooks(void)
Update the hookable APIs according to the current Introcore options.
Definition: lixapi.c:341
void IntMtblDisable(void)
Disables mem-table instructions instrumentation.
Definition: memtables.c:644
#define INTRO_OPT_PROT_KM_VDSO
Enable vDSO image protection (Linux only).
Definition: intro_types.h:500
INTSTATUS IntWinDrvObjUpdateProtection(void)
Updates the protection for all the driver objects in the gWinDriverObjects list.
Definition: windrvobj.c:1385
void IntLixDrvUpdateProtection(void)
Update Linux drivers protection according to the new core options.
Definition: lixmodule.c:487
#define LOG(fmt,...)
Definition: glue.h:61
32-bit selector.
Definition: glueiface.h:187
INTSTATUS IntWinGuestNew(void)
Starts the initialization and protection process for a new Windows guest.
Definition: winguest.c:2346
INTSTATUS IntWinUnprotectReadNtEat(void)
Used to remove the EAT read hook from ntoskrnl.exe.
Definition: windriver.c:690
static DWORD gInitRetryCount
The number of times initialization was tried.
Definition: guests.c:62
INTSTATUS IntGdtrProtect(void)
Enable GDTR protection.
#define INTRO_OPT_PROT_KM_SELF_MAP_ENTRY
Definition: intro_types.h:438
BOOLEAN PtFilterWaiting
True if the in-guest PT filter was not yet injected, but it should be.
Definition: guests.h:345
INTSTATUS IntWinIdtUnprotectAll(void)
Removes the IDT protection for all the guest CPUs.
Definition: winidt.c:590
BOOLEAN IntLixGuestDeployUninitAgent(void)
Inject the &#39;uninit&#39; agent to free the previously allocated memory for detours/agents.
Definition: lixguest.c:2238
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
Definition: guests.h:291
#define CR4_LA57
Definition: processor.h:55
#define INTRO_OPT_SYSPROC_BETA_DETECTIONS
Enable system processes beta (log only) detection.
Definition: intro_types.h:472
INTSTATUS IntHookCrInit(void)
Initialize the control registers hook state.
Definition: hook_cr.c:272
INTSTATUS IntHookCrCommit(void)
Commit the control register hooks.
Definition: hook_cr.c:234
Commit all the CR hooks.
Definition: guests.h:438
#define INTRO_OPT_PROT_KM_MSR_SYSCALL
Definition: intro_types.h:427
Get the number of VCPUs available to the guest.
Definition: glueiface.h:235
BOOLEAN gAbortLoad
Set to True if introcore should abort the initialization process.
Definition: introcore.c:59
INTSTATUS IntWinSudProtectSudExec(void)
Protects SharedUserData against executions by establishing an EPT hook on it.
Definition: winsud.c:661
DWORD Length
The valid size of the Pattern array.
Definition: patsig.h:25
No paging.
Definition: introcore.h:68
BOOLEAN SupportSPP
Set to True if support for SPP was detected.
Definition: guests.h:357
#define INT_STATUS_CANNOT_UNLOAD
Indicates that Introcore can not unload in a safely manner.
Definition: introstatus.h:450
INTSTATUS IntLixIdtUnprotectAll(void)
Disable protection for IDT on all CPUs.
Definition: lixidt.c:261
5-level paging
Definition: introcore.h:72
INTSTATUS IntWinSudUnprotectSudExec(void)
Removes the execution EPT hook on SharedUserData.
Definition: winsud.c:697
#define IC_TAG_CPUS
CPU state.
Definition: memtags.h:66
The context of an error state.
Definition: intro_types.h:2415
INTSTATUS IntIntegrityUninit(void)
Uninits the integrity mechanism by removing every integrity region from the list. ...
Definition: integrity.c:503
#define INT_STATUS_NOT_INITIALIZED
Definition: introstatus.h:266
#define CR4_PAE
Definition: processor.h:48
INTSTATUS IntSysenterRead(DWORD CpuNumber, QWORD *SysCs, QWORD *SysEip, QWORD *SysEsp)
Queries the IA32_SYSENTER_CS, IA32_SYSENTER_EIP, and IA32_SYSENTER_ESP guest MSRs.
Definition: introcpu.c:571
#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...
Definition: glueiface.h:324
BOOLEAN PaeEnabled
True if Physical Address Extension is enabled.
Definition: guests.h:295
INTSTATUS IntHookUninit(void)
Uninit the global hooks system.
Definition: hook.c:238
#define IG_DISABLE_IGNORE_SAFENESS
Definition: glueiface.h:365
PATTERN_SIGNATURE * gSysenterSignatures
The syscall and sysenter signatures used to identify an OS.
Definition: guests.c:80
INTSTATUS IntCamiProtectedProcessFree(void)
Uninitialize the global holding custom process protection options.
#define memzero(a, s)
Definition: introcrt.h:35
Reinject the #VE or PT filtering agent, based on the active options.
Definition: guests.h:442
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
unsigned long long QWORD
Definition: intro_types.h:53
static INTRO_ERROR_STATE gErrorState
The last error reported.
Definition: guests.c:65
QWORD Current
The currently used options.
Definition: guests.h:236
#define INTRO_OPT_PROT_KM_IDTR
Enable interrupt descriptor-table registers protection.
Definition: intro_types.h:429
INTSTATUS IntGuestPreReturnCallback(DWORD Options)
Handles all the operations that must be done before returning from a VMEXIT event handler...
Definition: guests.c:1280
BOOLEAN IntGuestShouldNotifyErrorState(void)
Checks if an event should be sent to the integrator.
Definition: guests.c:135
Structure encapsulating VCPU-specific information.
Definition: guests.h:83
void IntDetDumpDetours(void)
Prints all the detours in the gDetours list of detours.
Definition: detours.c:1895
INTSTATUS IntLixVdsoProtect(void)
Activates protection for the vDSO image and VSYSCALL.
Definition: lixvdso.c:883
#define INTRO_OPT_PROT_KM_INTERRUPT_OBJ
Enable protection against modifications of interrupt objects from KPRCB&#39;s InterruptObject.
Definition: intro_types.h:531
void * GpaCache
The currently used GPA cache.
Definition: guests.h:403
INTSTATUS IntWinIntObjUnprotect(void)
Uninitializes the interrupt objects protection.
Definition: winintobj.c:609
#define TRUE
Definition: intro_types.h:30
#define CR3_LEGACY_PAE_MASK
Definition: pgtable.h:110
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
Definition: decoder.c:308
QWORD LastGpa
The upper limit of the guest physical address range.
Definition: guests.h:219
BOOLEAN GuestInitialized
True if the OS-specific portion has been initialized.
Definition: guests.h:293
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
#define TRACE(fmt,...)
Definition: glue.h:58
INTSTATUS IntVeRemoveAgent(DWORD AgOpts)
Removes the VE agent from guest memory.
Definition: vecore.c:2116
INTSTATUS IntGdtrUnprotect(void)
Remove the GDTR protection.
INTSTATUS IntIcDestroy(PINS_CACHE *Cache)
Destroy an instruction cache.
Definition: icache.c:1211
INTRO_ERROR_STATE IntGuestGetIntroErrorState(void)
Gets the last reported error-state.
Definition: guests.c:107
INTSTATUS IntHookCrRemoveHook(HOOK_CR *Hook)
Remove a control register hook.
Definition: hook_cr.c:135
#define CR3_LEGACY_NON_PAE_MASK
Definition: pgtable.h:111
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
Definition: guests.h:367
static INTSTATUS IntGuestHandleCr3Write(void *Context, DWORD Cr, QWORD OldValue, QWORD NewValue, INTRO_ACTION *Action)
Handles Cr3 writes done by the guest. This is used to initialize the introspection engine...
Definition: guests.c:513
INTSTATUS IntExceptInit(void)
This function allocates the exceptions data and initialize the exception lists and the signature list...
Definition: exceptions.c:441
32-bit paging with PAE
Definition: introcore.h:70
INTRO_ERROR_CONTEXT * IntGuestGetIntroErrorStateContext(void)
Gets the last reported error-context appropriate to the error-state.
Definition: guests.c:121
INTSTATUS IntNotifyIntroInactive(void)
Definition: glue.c:941
BOOLEAN UninitPrepared
Definition: guests.h:320
#define WARNING(fmt,...)
Definition: glue.h:60
void IntLixKernelReadUnprotect(void)
Deactivates the kernel protection against read.
Definition: lixkernel.c:883
static INTRO_ERROR_CONTEXT * gErrorStateContext
The last error-context reported.
Definition: guests.c:68
QWORD ForceOff
Options that are forcibly disabled.
Definition: guests.h:242
void IntGuestUninit(void)
Completely unloads the introspection engine.
Definition: guests.c:1036
4-level paging
Definition: introcore.h:71
void IntGuestPrepareUninit(void)
Prepares introcore to be unloaded.
Definition: guests.c:984
#define SYSCALL_SIG_FLAG_KPTI
Indicates that a syscall pattern belongs to a KPTI enabled OS.
Definition: guests.c:71
#define INTRO_OPT_PROT_KM_NT_EAT_READS
Enable kernel EAT read protection (Windows only).
Definition: intro_types.h:497
DWORD CpuCount
The number of logical CPUs.
Definition: guests.h:279
INTSTATUS IntSwapMemInjectPendingPF(void)
Inject a PF for a pending page.
Definition: swapmem.c:698
#define PAGE_SIZE
Definition: common.h:70
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
void IntStatsDumpAll(void)
Prints all the non-zero stats.
Definition: stats.c:220
INTSTATUS IntGuestGetLastGpa(QWORD *MaxGpa)
Get the upper limit of the guest physical memory range.
Definition: guests.c:1735
INTRO_GUEST_TYPE
The type of the introspected operating system.
Definition: intro_types.h:2040
void * InstructionCache
The currently used instructions cache.
Definition: guests.h:404
#define INTRO_OPT_KM_BETA_DETECTIONS
Definition: intro_types.h:457
uint32_t DWORD
Definition: intro_types.h:49
INTSTATUS IntWinGetStartUpTime(QWORD *StartUpTime)
Gets the system startup time.
Definition: visibility.c:14
#define THS_CHECK_DETOURS
Will check if any RIP is inside detours.
#define IG_INVALID_TIME
Definition: glueiface.h:329
INTSTATUS IntSyscallRead(DWORD CpuNumber, QWORD *SysStar, QWORD *SysLstar)
Queries the IA32_STAR, and IA32_LSTAR guest MSRs.
Definition: introcpu.c:635
#define MAX_INIT_RETRIES
INTSTATUS IntGuestDisableIntro(QWORD Flags)
Disables and unloads the introspection engine.
Definition: guests.c:1203
INTSTATUS IntWinHalUpdateProtection(void)
Updates any of the HAL protections.
Definition: winhal.c:2405
INTSTATUS IntGpaCacheUnInit(PGPA_CACHE *Cache)
Uninit a GPA cache.
Definition: gpacache.c:209
INTSTATUS IntWinProtectReadNtEat(void)
Used to place a read hook on the ntoskrnl.exe EAT.
Definition: windriver.c:622
void IntSlackUninit(void)
Uninit the slack system. Must be called only during uninit.
Definition: slack.c:536
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTSTATUS IntGuestGetInfo(PGUEST_INFO GuestInfo)
Get basic information about the guest.
Definition: guests.c:350
BOOLEAN VeInitialized
Set to True if #VE initialization was done.
Definition: guests.h:353
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
PAGING_MODE
Paging modes.
Definition: introcore.h:66
void IntWinGuestUninit(void)
Uninits a Windows guest.
Definition: winguest.c:671
void IntAgentDisablePendingAgents(void)
Disable the Windows or Linux pending agents.
Definition: agent.c:102
void IntLixTaskUpdateProtection(void)
Adjusts protection for all active Linux processes.
Definition: lixprocess.c:4495
BOOLEAN EnterHibernate
True if the guest is entering into hibernate.
Definition: guests.h:319
QWORD Cr0
Cr0 value used when deducing the paging mode.
Definition: guests.h:213
Get the availability of the VMFUNC feature in hardware and the hypervisor.
Definition: glueiface.h:282
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Definition: guests.h:374
void IntGuestUpdateCoreOptions(QWORD NewOptions)
Updates Introcore options.
Definition: guests.c:1426
void IntDetDisableAllHooks(void)
Removes all detours from the guest.
Definition: detours.c:1848
static BOOLEAN IntGuestIsSafeToDisable(void)
Checks if it is safe to unload.
Definition: guests.c:1166
INTSTATUS IntWinProcUpdateProtection(void)
Iterates trough the global process list (gWinProcesses) in order to update the protection state for e...
Definition: winprocess.c:1162
INTSTATUS IntWinIdtProtectAll(void)
Activates the IDT protection for all the guest CPUs.
Definition: winidt.c:559
INTSTATUS IntHookMsrCommit(void)
Commit the model specific register hooks.
Definition: hook_msr.c:224
INTSTATUS IntMsrSyscallUnprotect(void)
Remove protection from all protected MSRs.
INTRO_ERROR_STATE
Error states.
Definition: intro_types.h:2433
#define EFER_LMA
Definition: processor.h:94
Guest information.
Definition: intro_types.h:2377
void IntLixKernelWriteUnprotect(void)
Deactivates the kernel protection against write.
Definition: lixkernel.c:866
INTRO_PROT_OPTIONS ShemuOptions
Flags which describe the way shemu will give detections.
Definition: guests.h:272
#define THS_CHECK_ONLY
Will check for safeness, without moving any RIP or stack value.
Commit all the XCR hooks.
Definition: guests.h:439
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
Definition: introcore.c:674
#define SIG_MAX_PATTERN
The maximum size of a pattern.
Definition: patsig.h:11
BOOLEAN KptiInstalled
True if KPTI was detected as installed (not necessarily active).
Definition: guests.h:292
QWORD Original
The original options as received from GLUE_IFACE.NewGuestNotification. This is updated when GLUE_IFAC...
Definition: guests.h:231
void IntGuestSetIntroErrorState(INTRO_ERROR_STATE State, INTRO_ERROR_CONTEXT *Context)
Updates the value of the gErrorState and the value of the gErrorStateContext.
Definition: guests.c:90
#define NLOG(fmt,...)
Definition: glue.h:43
BOOLEAN SupportVE
Set to True if support for #VE was detected.
Definition: guests.h:355
BOOLEAN LA57
True if 5-level paging is being used.
Definition: guests.h:296
PAGING_MODE Mode
The paging mode used by the guest.
Definition: guests.h:221
#define THS_CHECK_TRAMPOLINE
Will check if any RIP is inside the agent loader.
void IntGuestUpdateShemuOptions(QWORD NewOptions)
Update shemu options.
Definition: guests.c:1397
void IntLixGuestUninit(void)
Uninitialize the Linux guest.
Definition: lixguest.c:1674
INTSTATUS IntLixIdtProtectAll(void)
Activates protection for IDT on all CPUs.
Definition: lixidt.c:234
INTSTATUS IntPtiRemovePtFilter(DWORD AgOpts)
Removes the PT filter.
Definition: ptfilter.c:1736
QWORD TscSpeed
Number of ticks/second of this given guest. Should be the same as the global (physical) one...
Definition: guests.h:276
#define __likely(x)
Definition: common.h:63
void IntWinGuestCancelKernelRead(void)
Cancels the kernel read.
Definition: winguest.c:607
INTSTATUS IntWinSelfMapEnableSelfMapEntryProtection(void)
Enables the self map protection mechanism for the entire system.
Definition: winselfmap.c:516
INTSTATUS IntWinSudUnprotectIntegrity(void)
Uninitializes the SharedUserData integrity protection.
Definition: winsud.c:1178
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
#define INT_STATUS_NOT_SUPPORTED
Definition: introstatus.h:287
#define INTRO_OPT_PROT_KM_SUD_EXEC
Enable protection against executions on SharedUserData.
Definition: intro_types.h:515
#define INTRO_OPT_PROT_KM_TOKEN_PRIVS
Enable protection over Token Privileges bitmaps.
Definition: intro_types.h:505
INTSTATUS IntNotifyIntroErrorState(INTRO_ERROR_STATE State, INTRO_ERROR_CONTEXT *Context)
Definition: glue.c:989
DWORD NtBuildNumberValue
The value of the NtBuildNumber kernel variable.
Definition: winguest.h:816
64-bit selector.
Definition: glueiface.h:188
Get the availability of the SPP feature in hardware and the hypervisor.
Definition: glueiface.h:285
32-bit paging
Definition: introcore.h:69
Get the TSC speed.
Definition: glueiface.h:242
Describes a signature that can be used for searching or matching guest contents.
Definition: patsig.h:23
enum _AG_WAITSTATE AG_WAITSTATE
#define INTRO_OPT_PROT_KM_CR4
Enable CR4.SMEP and CR4.SMAP protection.
Definition: intro_types.h:426
BOOLEAN BugCheckInProgress
Definition: guests.h:333
Get the availability of the Virtualization Exception feature in hardware and the hypervisor.
Definition: glueiface.h:279
BOOLEAN PtFilterFlagRemoved
Set to True if the INTRO_OPT_IN_GUEST_PT_FILTER was given, but it was removed.
Definition: guests.h:365
INTSTATUS IntCallbacksInit(void)
Initialize the callbacks.
Definition: callbacks.c:3527
BOOLEAN DisableOnReturn
Set to True if after returning from this event handler, introcore must be unloaded.
Definition: guests.h:328
BYTE Version
The version field of the version string.
Definition: lixguest.h:487
Describes a guest.
Definition: guests.h:269
#define INTRO_OPT_IN_GUEST_PT_FILTER
Enable in-guest page-table filtering (64-bit Windows only).
Definition: intro_types.h:461
DWORD SignatureId
Signature ID.
Definition: patsig.h:26
INTSTATUS IntLixKernelWriteProtect(void)
Activates kernel protection.
Definition: lixkernel.c:754
INTSTATUS IntCr4Protect(void)
Activates the Cr4 protection.
We have an active agent, currently injected inside the guest.
Definition: agent.h:16
INTSTATUS IntVeDeployAgent(void)
Inject the VE agent inside the guest.
Definition: vecore.c:2063
INTSTATUS IntWinInfHookUnprotect(void)
Removes the protection against infinity hook.
INTSTATUS IntHookDtrInit(void)
Initialize the descriptor registers hook state.
Definition: hook_dtr.c:203
Section will contain syscall signatures.
Definition: update_guests.h:43
#define THS_CHECK_MEMTABLES
Will check if any RIP is inside memtables.
INTSTATUS IntHookMsrUninit(void)
Uninit the model specific register hooks state.
Definition: hook_msr.c:285
void IntVeDumpVeInfoPages(void)
Dumps the VE info pages on all VCPUs.
Definition: vecore.c:2698
INTSTATUS IntWinSelfMapDisableSelfMapEntryProtection(void)
Disables the self map entry protection for all the processes on the system.
Definition: winselfmap.c:656
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:271
static INTSTATUS IntGuestInitMemoryInfo(void)
Initializes gGuest.Mm.
Definition: guests.c:463
INTSTATUS IntEferRead(QWORD CpuNumber, QWORD *Efer)
Reads the value of the guest IA32 EFER MSR.
Definition: introcpu.c:12
static INTSTATUS IntGuestDetectOsSysCall(QWORD SyscallHandler, INTRO_GUEST_TYPE *OsType, BOOLEAN *KptiInstalled, BOOLEAN *KptiActive)
Checks if any of the predefined syscall signatures match to the given syscall handler.
Definition: guests.c:195
#define INTRO_OPT_PROT_KM_LOGGER_CONTEXT
Enable protection on WMI_LOGGER_CONTEXT.GetCpuClock used by InfinityHook (Windows only)...
Definition: intro_types.h:485
#define INTRO_OPT_PROT_KM_GDTR
Enable global descriptor-table registers protection.
Definition: intro_types.h:440
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
Definition: lixguest.c:30
Inject pending page faults.
Definition: guests.h:441
Commit all the DTR hooks.
Definition: guests.h:440
INTSTATUS IntCamiLoadSection(DWORD CamiSectionHint)
Load CAMI objects from section with given hint.
AG_WAITSTATE IntAgentGetState(DWORD *Tag)
Get the current Windows or Linux agent state.
Definition: agent.c:121
INTSTATUS IntMtblUninit(void)
Completely uninit the mem-tables, removing all the handlers from the NT slack space.
Definition: memtables.c:745
#define FALSE
Definition: intro_types.h:34
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281