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 
49 
57 VCPU_STATE *gVcpu = NULL;
58 
61 
64 
67 
69 #define SYSCALL_SIG_FLAG_KPTI 0x80000000
70 
80 
84 static HOOK_CR *gCr3WriteHook = NULL;
85 
86 
87 void
89  _In_ INTRO_ERROR_STATE State,
91  )
98 {
99  gErrorState = State;
100  gErrorStateContext = Context;
101 }
102 
103 
106  void
107  )
113 {
114  return gErrorState;
115 }
116 
117 
120  void
121  )
127 {
128  return gErrorStateContext;
129 }
130 
131 
132 BOOLEAN
134  void
135  )
141 {
142  return gErrorState != intErrNone;
143 }
144 
145 
146 static void
148  _In_ BYTE *SyscallBuffer,
149  _In_ DWORD Size,
150  _Out_ BOOLEAN *IsKptiActive
151  )
161 {
162  INTSTATUS status;
163 
164  *IsKptiActive = FALSE;
165 
166  for (DWORD it = 0; it < Size;)
167  {
168  INSTRUX instrux;
169 
170  status = IntDecDecodeInstructionFromBuffer(SyscallBuffer + it,
171  Size - it,
173  &instrux);
174  if (!INT_SUCCESS(status))
175  {
176  it++;
177  continue;
178  }
179 
180  if (instrux.Instruction == ND_INS_MOV_CR &&
181  ND_IS_OP_REG(&instrux.Operands[0], ND_REG_CR, (DWORD)gGuest.WordSize, NDR_CR3))
182  {
183  *IsKptiActive = TRUE;
184  return;
185  }
186 
187  it += instrux.Length;
188  }
189 }
190 
191 
192 static INTSTATUS
194  _In_ QWORD SyscallHandler,
195  _Out_ INTRO_GUEST_TYPE *OsType,
196  _Out_ BOOLEAN *KptiInstalled,
197  _Out_ BOOLEAN *KptiActive
198  )
210 {
211  INTSTATUS status;
212  DWORD i, j;
213  BYTE buffer[SIG_MAX_PATTERN] = {0};
214  BOOLEAN found;
215 
216  *OsType = introGuestUnknown;
217  *KptiInstalled = FALSE;
218  *KptiActive = FALSE;
219 
220  status = IntKernVirtMemRead(SyscallHandler, sizeof(buffer), buffer, NULL);
221  if (!INT_SUCCESS(status))
222  {
223  ERROR("[ERROR] IntKernVirtMemRead failed for %llx: 0x%08x\n", SyscallHandler, status);
224  return status;
225  }
226 
228  if (!INT_SUCCESS(status))
229  {
230  ERROR("[ERROR] IntCamiLoadSection failed: 0x%08x\n", status);
231  return status;
232  }
233 
234  for (i = 0; i < gSysenterSignaturesCount; i++)
235  {
236  found = TRUE;
237 
238  for (j = 0; j < gSysenterSignatures[i].Length; j++)
239  {
240  if (gSysenterSignatures[i].Pattern[j] != 0x100 && gSysenterSignatures[i].Pattern[j] != buffer[j])
241  {
242  found = FALSE;
243  break;
244  }
245  }
246 
247  if (found)
248  {
249  TRACE("[INTRO-INIT] Found the syscall handler %d address at 0x%016llx\n", i, SyscallHandler);
250 
251  *OsType = gSysenterSignatures[i].SignatureId & 0xFF;
252  *KptiInstalled = !!(gSysenterSignatures[i].SignatureId & SYSCALL_SIG_FLAG_KPTI);
253 
254  IntGuestIsKptiActive(buffer, sizeof(buffer), KptiActive);
255 
256  status = INT_STATUS_SUCCESS;
257  goto _free_and_exit;
258  }
259  }
260 
261  LOG("Syscall/interrupt @0x%016llx handler not identified... Dumping %zu bytes from it!\n",
262  SyscallHandler, sizeof(buffer));
263 
264  for (i = 0; i < sizeof(buffer); i += 8)
265  {
266  NLOG("%02x %02x %02x %02x %02x %02x %02x %02x\n", buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3],
267  buffer[i + 4], buffer[i + 5], buffer[i + 6], buffer[i + 7]);
268  }
269 
270  status = INT_STATUS_NOT_FOUND;
271 
272 _free_and_exit:
273  HpFreeAndNullWithTag(&gSysenterSignatures, IC_TAG_CAMI);
274 
275  return status;
276 }
277 
278 
279 static INTSTATUS
281  _Out_ INTRO_GUEST_TYPE *OsType,
282  _Out_ BOOLEAN *KptiInstalled,
283  _Out_ BOOLEAN *KptiActive
284  )
295 {
296  INTSTATUS status;
297  QWORD analyzeAddress[3] = {0};
298 
299  *OsType = introGuestUnknown;
300  *KptiInstalled = FALSE;
301  *KptiActive = FALSE;
302 
303  status = IntSyscallRead(IG_CURRENT_VCPU, NULL, &analyzeAddress[0]);
304  if (!INT_SUCCESS(status))
305  {
306  ERROR("[ERROR] Failed reading SYSCALL MSRs: 0x%08x\n", status);
308  return status;
309  }
310 
311  status = IntSysenterRead(IG_CURRENT_VCPU, NULL, &analyzeAddress[1], NULL);
312  if (!INT_SUCCESS(status))
313  {
314  ERROR("[ERROR] Failed reading SYSENTER MSRs: 0x%08x\n", status);
316  return status;
317  }
318 
319  status = IntIdtGetEntry(IG_CURRENT_VCPU, VECTOR_DE, &analyzeAddress[2]);
320  if (!INT_SUCCESS(status))
321  {
322  ERROR("[ERROR] Failed reading INT 0 handler: 0x%08x\n", status);
324  return status;
325  }
326 
327  for (DWORD l = 0; l < ARRAYSIZE(analyzeAddress); l++)
328  {
329  if (analyzeAddress[l] == 0)
330  {
331  continue;
332  }
333 
334  status = IntGuestDetectOsSysCall(analyzeAddress[l], OsType, KptiInstalled, KptiActive);
335  if (INT_SUCCESS(status))
336  {
337  TRACE("[INTRO-INIT] Found the syscall/interrupt handler address at %llx\n", analyzeAddress[l]);
338 
339  return INT_STATUS_SUCCESS;
340  }
341  }
342 
343  return INT_STATUS_NOT_FOUND;
344 }
345 
346 
347 INTSTATUS
349  _Out_ PGUEST_INFO GuestInfo
350  )
360 {
361  if (NULL == GuestInfo)
362  {
364  }
365 
366  GuestInfo->Guest64 = gGuest.Guest64;
367  GuestInfo->StartupTime = IG_INVALID_TIME;
368  GuestInfo->OsVersion = gGuest.OSVersion;
369 
370  switch (gGuest.OSType)
371  {
372  case introGuestWindows:
373  {
374  QWORD time = 0;
375  INTSTATUS status;
376 
377  GuestInfo->Type = introGuestWindows;
378  GuestInfo->BuildNumber = gWinGuest->NtBuildNumberValue;
379 
380  status = IntWinGetStartUpTime(&time);
381  if (INT_SUCCESS(status))
382  {
383  GuestInfo->StartupTime = time;
384  }
385 
386  break;
387  }
388 
389  case introGuestLinux:
390  GuestInfo->Type = introGuestLinux;
391  GuestInfo->BuildNumber = gLixGuest->Version.Value;
392  break;
393 
394  default:
396  }
397 
398  return INT_STATUS_SUCCESS;
399 }
400 
401 
402 static PAGING_MODE
404  _In_opt_ QWORD Efer,
405  _In_opt_ QWORD Cr4,
406  _In_opt_ QWORD Cr0
407  )
416 {
417  INTSTATUS status;
418 
419  if (!Efer)
420  {
421  status = IntEferRead(gVcpu->Index, &Efer);
422  if (!INT_SUCCESS(status))
423  {
424  ERROR("[ERROR] IntEferRead failed: 0x%08x\n", status);
425  return PAGING_NONE;
426  }
427  }
428 
429  if (!Cr4)
430  {
431  Cr4 = gVcpu->Regs.Cr4;
432  }
433 
434  if (!Cr0)
435  {
436  Cr0 = gVcpu->Regs.Cr0;
437  }
438 
439  if (0 != (Efer & EFER_LMA) && 0 != (Cr4 & CR4_LA57))
440  {
441  return PAGING_5_LEVEL_MODE;
442  }
443  else if (0 != (Efer & EFER_LMA))
444  {
445  return PAGING_4_LEVEL_MODE;
446  }
447  else if (0 != (Cr4 & CR4_PAE))
448  {
449  return PAGING_PAE_MODE;
450  }
451  else if (0 != (Cr0 & CR0_PG))
452  {
453  return PAGING_NORMAL_MODE;
454  }
455 
456  return PAGING_NONE;
457 }
458 
459 
460 static INTSTATUS
462  void
463  )
469 {
470  INTSTATUS status;
471 
472  gGuest.Mm.Cr0 = gVcpu->Regs.Cr0;
473  gGuest.Mm.Cr4 = gVcpu->Regs.Cr4;
474 
475  status = IntEferRead(gVcpu->Index, &gGuest.Mm.Efer);
476  if (!INT_SUCCESS(status))
477  {
478  ERROR("[ERROR] IntEferRead failed: 0x%08x\n", status);
479  return status;
480  }
481 
482  gGuest.Guest64 = FALSE;
483  gGuest.PaeEnabled = FALSE;
484  gGuest.LA57 = FALSE;
485 
486  gGuest.Mm.Mode = IntGuestGetPagingMode(gGuest.Mm.Efer, gGuest.Mm.Cr4, gGuest.Mm.Cr0);
487 
488  if (PAGING_5_LEVEL_MODE == gGuest.Mm.Mode)
489  {
490  gGuest.Guest64 = TRUE;
491  gGuest.PaeEnabled = TRUE;
492  gGuest.LA57 = TRUE;
493  }
494  else if (PAGING_4_LEVEL_MODE == gGuest.Mm.Mode)
495  {
496  gGuest.Guest64 = TRUE;
497  gGuest.PaeEnabled = TRUE;
498  }
499  else if (PAGING_PAE_MODE == gGuest.Mm.Mode)
500  {
501  gGuest.PaeEnabled = TRUE;
502  }
503 
504  gGuest.WordSize = gGuest.Guest64 ? 8 : 4;
505 
506  return INT_STATUS_SUCCESS;
507 }
508 
509 
510 static INTSTATUS
512  _In_opt_ void *Context,
513  _In_ DWORD Cr,
514  _In_ QWORD OldValue,
515  _In_ QWORD NewValue,
516  _Out_ INTRO_ACTION *Action
517  )
545 {
546 #define MAX_INIT_RETRIES 32
547  INTSTATUS status, status2;
548  QWORD syscall = 0;
549  QWORD sysenter = 0;
550  INTRO_GUEST_TYPE osType;
551  BOOLEAN bKptiInstalled, bKptiActive, bSameCr3;
552 
553  UNREFERENCED_PARAMETER(Context);
555 
556  *Action = introGuestAllowed;
557 
558  if (__unlikely(gGuest.GuestInitialized))
559  {
560  ERROR("[ERROR] Introspection is already initialized, this should not happen... Remove the hook!\n");
561 
562  IntHookCrRemoveHook(gCr3WriteHook);
563  gCr3WriteHook = NULL;
564 
565  return INT_STATUS_SUCCESS;
566  }
567 
568  if (!(gVcpu->Regs.Cr0 & CR0_PG))
569  {
570  return INT_STATUS_SUCCESS;
571  }
572 
573  // Temporary initialize the gGuest.Mm (in case we want to do translations or anything)
574  status = IntGuestInitMemoryInfo();
575  if (!INT_SUCCESS(status))
576  {
577  ERROR("[ERROR] IntGuestInitMemoryInfo failed: 0x%08x\n", status);
578  return status;
579  }
580 
581  status = IntSyscallRead(IG_CURRENT_VCPU, NULL, &syscall);
582  if (!INT_SUCCESS(status))
583  {
584  ERROR("[ERROR] IntSyscallRead failed: 0x%08x\n", status);
585  return status;
586  }
587 
588  status = IntSysenterRead(IG_CURRENT_VCPU, NULL, &sysenter, NULL);
589  if (!INT_SUCCESS(status))
590  {
591  ERROR("[ERROR] IntSysenterRead failed: 0x%08x\n", status);
592  return status;
593  }
594 
595  if (0 == syscall && 0 == sysenter)
596  {
597  return INT_STATUS_SUCCESS;
598  }
599 
600  bSameCr3 = FALSE;
601 
602  switch (gGuest.Mm.Mode)
603  {
604  case PAGING_NONE:
605  // Still in 16-bit mode, nothing to do yet
606  return INT_STATUS_SUCCESS;
607 
608  case PAGING_NORMAL_MODE:
609  bSameCr3 = (NewValue & CR3_LEGACY_NON_PAE_MASK) == (OldValue & CR3_LEGACY_NON_PAE_MASK);
610  break;
611 
612  case PAGING_PAE_MODE:
613  bSameCr3 = (NewValue & CR3_LEGACY_PAE_MASK) == (OldValue & CR3_LEGACY_PAE_MASK);
614  break;
615 
616  case PAGING_4_LEVEL_MODE:
617  bSameCr3 = (NewValue & CR3_LONG_MODE_MASK) == (OldValue & CR3_LONG_MODE_MASK);
618  break;
619 
620  case PAGING_5_LEVEL_MODE:
621  ERROR("[ERROR] Guest has activated LA57 mode, we don't support it yet!\n");
622 
624 
626  }
627 
628  if (bSameCr3)
629  {
630  return INT_STATUS_SUCCESS;
631  }
632 
633  IntPauseVcpus();
634 
635  // This is the final MM info (the one which is supposed to be good)
636  status = IntGuestInitMemoryInfo();
637  if (!INT_SUCCESS(status))
638  {
639  ERROR("[ERROR] IntGuestInitMemoryInfo failed: %08x\n", status);
640  goto _resume_and_leave;
641  }
642 
643  LOG("[INTRO-INIT] Will try %d time to static init the guest on CPU %02d with EFER 0x%08llx and %s paging mode...\n",
645  gVcpu->Index, gGuest.Mm.Efer,
646  gGuest.Mm.Mode == PAGING_5_LEVEL_MODE ? "5-level" :
647  gGuest.Mm.Mode == PAGING_4_LEVEL_MODE ? "4-level" :
648  gGuest.Mm.Mode == PAGING_PAE_MODE ? "PAE" :
649  gGuest.Mm.Mode == PAGING_NORMAL_MODE ? "Normal" : "Invalid");
650 
651  for (DWORD i = 0; i < gGuest.CpuCount; i++)
652  {
653  status = IntGetGprs(i, &gGuest.VcpuArray[i].Regs);
654  if (!INT_SUCCESS(status))
655  {
656  ERROR("[ERROR] IntGetGprs failed on CPU %d: %08x\n", i, status);
657  goto _resume_and_leave;
658  }
659 
660  LOG("[INTRO-INIT] CPU %02d: CR0 = %08llx, CR3 = %016llx, CR4 = %08llx, RIP = %016llx\n",
661  i, gGuest.VcpuArray[i].Regs.Cr0, gGuest.VcpuArray[i].Regs.Cr3,
662  gGuest.VcpuArray[i].Regs.Cr4, gGuest.VcpuArray[i].Regs.Rip);
663  }
664 
665  // Temporary, until we find the actual one (os-dependent)
666  gGuest.Mm.SystemCr3 = gVcpu->Regs.Cr3;
667 
668  status = IntGuestDetectOs(&osType, &bKptiInstalled, &bKptiActive);
669  if (!INT_SUCCESS(status))
670  {
671  ERROR("[ERROR] IntGuestDetectOs failed: 0x%08x\n", status);
672  goto _resume_and_leave;
673  }
674 
675  LOG("[INTRO-INIT] Identified OS type %s\n",
676  osType == introGuestWindows ? "Windows" : "Linux");
677 
678  if (osType == introGuestWindows)
679  {
680  gGuest.KptiInstalled = bKptiInstalled;
681  gGuest.KptiActive = bKptiActive;
682 
683  TRACE("[INTRO-INIT] Guest has KPTI installed: %d, enabled: %d\n",
684  gGuest.KptiInstalled, gGuest.KptiActive);
685 
686  status = IntWinGuestNew();
687  }
688  else if (osType == introGuestLinux)
689  {
690  status = IntLixGuestNew();
691  }
692  else
693  {
695  gGuest.DisableOnReturn = TRUE;
696  }
697 
698  if (!INT_SUCCESS(status) || gGuest.DisableOnReturn)
699  {
700  goto _resume_and_leave;
701  }
702 
703  status = IntCallbacksInit();
704  if (!INT_SUCCESS(status))
705  {
706  ERROR("[ERROR] IntCallbacksInit failed: 0x%08x\n", status);
707 
708  gGuest.DisableOnReturn = TRUE;
709 
710  goto _resume_and_leave;
711  }
712 
713  TRACE("[INTRO-INIT] Callbacks initialized successfully!\n");
714 
715  // Introcore is fully initialized, we can remove the cr3 write hook
716  status2 = IntHookCrRemoveHook(gCr3WriteHook);
717  if (INT_SUCCESS(status2))
718  {
719  gCr3WriteHook = NULL;
720  }
721  else
722  {
723  ERROR("[ERROR] IntHookCrRemoveHook failed: %08x\n", status2);
724  }
725 
726 _resume_and_leave:
727  if ((++gInitRetryCount >= MAX_INIT_RETRIES) && !INT_SUCCESS(status))
728  {
729  ERROR("[ERROR] [CRITICAL] Tried %d times to init the introspection, bail out...\n", gInitRetryCount);
730 
731  gGuest.DisableOnReturn = TRUE;
732  }
733 
734  if (gGuest.DisableOnReturn)
735  {
736  ERROR("[ERROR] An error occurred in init: %08x, %d. Will uninit the introspection!\n",
737  status, gGuest.DisableOnReturn);
738 
739  if (gAbortLoad)
740  {
741  status = INT_STATUS_LOAD_ABORTED;
742  }
743  }
744 
745  IntResumeVcpus();
746 
747  return status;
748 #undef MAX_INIT_RETRIES
749 }
750 
751 
752 INTSTATUS
754  _In_ QWORD Options
755  )
772 {
773  INTSTATUS status;
774 
775  memzero(&gGuest, sizeof(gGuest));
776 
777  gInitRetryCount = 0;
778  gGuest.CoreOptions.Current = Options;
779  gGuest.CoreOptions.Original = Options;
780  gGuest.KernelBetaDetections = 0 != (Options & INTRO_OPT_KM_BETA_DETECTIONS);
782  gGuest.Mm.Mode = PAGING_NONE;
783 
784  gGuest.Initialized = TRUE;
785 
786  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_CPU_COUNT, NULL, &gGuest.CpuCount, sizeof(DWORD));
787  if (!INT_SUCCESS(status))
788  {
789  ERROR("[ERROR] IntQueryGuestInfo failed for feature CPU COUNT: 0x%08x\n", status);
790  goto _cleanup_and_exit;
791  }
792  TRACE("[INTRO-INIT] CPU_COUNT = %d \n", gGuest.CpuCount);
793 
794  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_TSC_SPEED, NULL, &gGuest.TscSpeed, sizeof(QWORD));
795  if (!INT_SUCCESS(status))
796  {
797  ERROR("[ERROR] IntQueryGuestInfo failed for feature TSC SPEED: 0x%08x\n", status);
798  return status;
799  }
800  TRACE("[INTRO-INIT] TSC speed = 0x%016llx ticks/second\n", gGuest.TscSpeed);
801 
802  // Query for supported features.
803  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_VE_SUPPORT, NULL, &gGuest.SupportVE, sizeof(BOOLEAN));
804  if (!INT_SUCCESS(status))
805  {
806  WARNING("[WARNING] IntQueryGuestInfo failed for feature #VE: 0x%08x\n", status);
807  gGuest.SupportVE = FALSE;
808  }
809 
811  if (!INT_SUCCESS(status))
812  {
813  WARNING("[WARNING] IntQueryGuestInfo failed for feature VMFUNC: 0x%08x\n", status);
814  gGuest.SupportVMFUNC = FALSE;
815  }
816 
817  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_SPP_SUPPORT, NULL, &gGuest.SupportSPP, sizeof(BOOLEAN));
818  if (!INT_SUCCESS(status))
819  {
820  WARNING("[WARNING] IntQueryGuestInfo failed for feature SPP: 0x%08x\n", status);
821  gGuest.SupportSPP = FALSE;
822  }
823 
824  status = IntQueryGuestInfo(IG_QUERY_INFO_CLASS_DTR_SUPPORT, NULL, &gGuest.SupportDTR, sizeof(BOOLEAN));
825  if (!INT_SUCCESS(status))
826  {
827  WARNING("[WARNING] IntQueryGuestInfo failed for feature DTR: 0x%08x\n", status);
828  gGuest.SupportDTR = FALSE;
829  }
830 
831  LOG("[INTRO-INIT] CPU/HV support: #VE: %s, VMFUNC: %s, SPP: %s, DTR events: %s\n",
832  gGuest.SupportVE ? "yes" : "no", gGuest.SupportVMFUNC ? "yes" : "no",
833  gGuest.SupportSPP ? "yes" : "no", gGuest.SupportDTR ? "yes" : "no");
834 
835  // Start initializing sub-components.
836  gGuest.VcpuArray = HpAllocWithTag(gGuest.CpuCount * sizeof(VCPU_STATE), IC_TAG_CPUS);
837  if (NULL == gGuest.VcpuArray)
838  {
840  goto _cleanup_and_exit;
841  }
842 
843  for (DWORD i = 0; i < gGuest.CpuCount; i++)
844  {
845  gGuest.VcpuArray[i].Index = i;
846  // For now, assume that the guest is using this VCPU
847  // For Windows guests this may change in IntWinGetActiveCpuCount
848  gGuest.VcpuArray[i].Initialized = TRUE;
849  }
850 
851  gVcpu = &gGuest.VcpuArray[IntGetCurrentCpu()];
852 
853  IntStatsInit();
854  TRACE("[INTRO-INIT] Stats module initialized successfully!\n");
855 
856  status = IntHookInit();
857  if (!INT_SUCCESS(status))
858  {
859  ERROR("[ERROR] IntHookInit failed: 0x%08x\n", status);
860  goto _cleanup_and_exit;
861  }
862  TRACE("[INTRO-INIT] New Hook module initialized successfully!\n");
863 
864  status = IntHookMsrInit();
865  if (!INT_SUCCESS(status))
866  {
867  ERROR("[ERROR] IntHookMsrInit failed: 0x%08x\n", status);
868  goto _cleanup_and_exit;
869  }
870  TRACE("[INTRO-INIT] MSR Hook module initialized successfully!\n");
871 
872  status = IntHookDtrInit();
873  if (!INT_SUCCESS(status))
874  {
875  ERROR("[ERROR] IntHookDtrInit failed: 0x%08x\n", status);
876  goto _cleanup_and_exit;
877  }
878  TRACE("[INTRO-INIT] DTR Hook module initialized successfully!\n");
879 
880  status = IntHookCrInit();
881  if (!INT_SUCCESS(status))
882  {
883  ERROR("[ERROR] IntHookCrInit failed: 0x%08x\n", status);
884  goto _cleanup_and_exit;
885  }
886  TRACE("[INTRO-INIT] CR Hook module initialized successfully!\n");
887 
888  status = IntHookXcrInit();
889  if (!INT_SUCCESS(status))
890  {
891  ERROR("[ERROR] IntHookXcrInit failed: 0x%08x\n", status);
892  goto _cleanup_and_exit;
893  }
894  TRACE("[INTRO-INIT] XCR Hook module initialized successfully!\n");
895 
896  status = IntIcCreate((PINS_CACHE *)&gGuest.InstructionCache, 512, 16, 512);
897  if (!INT_SUCCESS(status))
898  {
899  ERROR("[ERROR] IntIcCreate failed: 0x%08x\n", status);
900  goto _cleanup_and_exit;
901  }
902  TRACE("[INTRO-INIT] Instruction cache module initialized successfully!\n");
903 
904  // Init the GPA cache (on USER_MODE is bigger, because we have more memory)
905 #ifndef USER_MODE
906  status = IntGpaCacheInit((PGPA_CACHE *)&gGuest.GpaCache, 256, 4);
907 #else
908  status = IntGpaCacheInit((PGPA_CACHE *)&gGuest.GpaCache, 512, 8);
909 #endif // !USER_MODE
910  if (!INT_SUCCESS(status))
911  {
912  ERROR("[ERROR] IntGpaCacheInit failed: 0x%08x\n", status);
913  goto _cleanup_and_exit;
914  }
915  TRACE("[INTRO-INIT] GPA cache module initialized successfully!\n");
916 
917  status = IntSwapMemInit();
918  if (!INT_SUCCESS(status))
919  {
920  ERROR("[ERROR] IntSwapMemInit failed: 0x%08x\n", status);
921  goto _cleanup_and_exit;
922  }
923  TRACE("[INTRO-INIT] Swapmem module initialized successfully!\n");
924 
925  status = IntVasInit();
926  if (!INT_SUCCESS(status))
927  {
928  ERROR("[ERROR] IntVasInit failed: 0x%08x\n", status);
929  goto _cleanup_and_exit;
930  }
931  TRACE("[INTRO-INIT] VAS Monitor module initialized successfully!\n");
932 
933  status = IntExceptInit();
934  if (!INT_SUCCESS(status))
935  {
936  ERROR("[ERROR] IntExceptInit failed: 0x%08x\n", status);
937  goto _cleanup_and_exit;
938  }
939  TRACE("[INTRO-INIT] Kernel-mode exception module initialized successfully!\n");
940 
941  // If both VE and PT options are set, choose only one, depending on whether #VE is active or not.
943  {
944  gGuest.PtFilterFlagRemoved = FALSE;
945 
946  if (gGuest.VeInitialized)
947  {
948  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, "
949  "will ignore INTRO_OPT_IN_GUEST_PT_FILTER, because #VE is initialized!\n");
951  gGuest.PtFilterFlagRemoved = TRUE;
952  }
953  else
954  {
955  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, "
956  "will ignore INTRO_OPT_VE, because #VE is NOT initialized!\n");
957  gGuest.CoreOptions.Current &= ~INTRO_OPT_VE;
958  }
959  }
960 
961  // After we initialized all the subsystems, hook CR3 writes so we can gracefully init the rest
962  status = IntHookCrSetHook(3, 0, IntGuestHandleCr3Write, NULL, &gCr3WriteHook);
963  if (!INT_SUCCESS(status))
964  {
965  ERROR("[ERROR] IntHookCrSetHook failed: 0x%08x\n", status);
966  goto _cleanup_and_exit;
967  }
968 
969  status = INT_STATUS_SUCCESS;
970 
971 _cleanup_and_exit:
972  if (!INT_SUCCESS(status))
973  {
974  IntGuestUninit();
975  }
976 
977  return status;
978 }
979 
980 
981 void
983  void
984  )
994 {
995  if (gGuest.UninitPrepared)
996  {
997  return;
998  }
999 
1001 
1003 
1005 
1007 
1009 
1010  IntMtblDisable();
1011 
1012  IntSwapgsDisable();
1013 
1014  if (gGuest.OSType == introGuestWindows)
1015  {
1016  IntWinObjCleanup();
1017 
1019  }
1020 
1021  if (gCr3WriteHook)
1022  {
1023  IntHookCrRemoveHook(gCr3WriteHook);
1024  gCr3WriteHook = NULL;
1025  }
1026 
1028 
1029  gGuest.UninitPrepared = TRUE;
1030 }
1031 
1032 
1033 void
1035  void
1036  )
1047 {
1048  // We dump some statistics to know what happened while Introcore was running.
1050  IntStatsDumpAll();
1051 
1052  if (gCr3WriteHook)
1053  {
1054  IntHookCrRemoveHook(gCr3WriteHook);
1055  gCr3WriteHook = NULL;
1056  }
1057 
1058  if (gGuest.OSType == introGuestWindows)
1059  {
1060  TRACE("[INTRO-UNINIT] Uninit the Windows guest...\n");
1062  }
1063  else if (gGuest.OSType == introGuestLinux)
1064  {
1065  TRACE("[INTRO-UNINIT] Uninit the Linux guest...\n");
1067  }
1068 
1069  TRACE("[INTRO-UNINIT] Uninit #VE...\n");
1070  IntVeUnInit();
1071 
1072  TRACE("[INTRO-UNINIT] Uninit exceptions...\n");
1073  IntExceptUninit();
1074 
1075  TRACE("[INTRO-UNINIT] Uninit integrity...\n");
1077 
1078  TRACE("[INTRO-UNINIT] Uninit VAS monitor...\n");
1079  IntVasUnInit();
1080 
1081  TRACE("[INTRO-UNINIT] Uninit memory tables...\n");
1082  IntMtblUninit();
1083 
1084  TRACE("[INTRO-UNINIT] Uninit SWAPGS mitigations...\n");
1085  IntSwapgsUninit();
1086 
1087  TRACE("[INTRO-UNINIT] Uninit detours-guest...\n");
1088  IntDetUninit();
1089 
1090  TRACE("[INTRO-UNINIT] Uninit slack...\n");
1091  IntSlackUninit();
1092 
1093  TRACE("[INTRO-UNINIT] Uninit instruction cache...\n");
1094  if (NULL != gGuest.InstructionCache)
1095  {
1097  }
1098 
1099  TRACE("[INTRO-UNINIT] Uninit memcloak...\n");
1100  IntMemClkUnInit();
1101 
1102  TRACE("[INTRO-UNINIT] Uninit swapmem...\n");
1103  IntSwapMemUnInit();
1104 
1105  if (gGuest.OSType == introGuestWindows)
1106  {
1107  // Page-lock uninit. Do it after detours and memclk (they have references to it)
1108  TRACE("[INTRO-UNINIT] Uninit windows pfn locks...\n");
1109  IntWinPfnUnInit();
1110  }
1111 
1112  TRACE("[INTRO-UNINIT] Uninit unpack...\n");
1113  IntUnpUninit();
1114 
1115  TRACE("[INTRO-UNINIT] Uninit new hooks...\n");
1116  IntHookUninit();
1117 
1118  TRACE("[INTRO-UNINIT] Uninit hooker-msr...\n");
1119  IntHookMsrUninit();
1120 
1121  TRACE("[INTRO-UNINIT] Uninit hooker-dtr...\n");
1122  IntHookDtrUninit();
1123 
1124  TRACE("[INTRO-UNINIT] Uninit hooker-cr...\n");
1125  IntHookCrUninit();
1126 
1127  TRACE("[INTRO-UNINIT] Uninit hooker-xcr...\n");
1128  IntHookXcrUninit();
1129 
1130  TRACE("[INTRO-UNINIT] Uninit GPA cache...\n");
1131  if (NULL != gGuest.GpaCache)
1132  {
1134  }
1135 
1136  // The callbacks must be uninitialized AFTER the detours. Otherwise, we may end up with a pending event
1137  // after we have removed the callbacks but before we have removed the detours. This way, we would erroneously
1138  // emulate the attempt instead of faking the original content.
1139  TRACE("[INTRO-UNINIT] Uninit callbacks...\n");
1141 
1142  TRACE("[INTRO-UNINIT] Free cami protected processes array ...\n");
1144 
1145  if (NULL != gGuest.VcpuArray)
1146  {
1148  }
1149 
1150  gWinGuest = NULL;
1151  gLixGuest = NULL;
1152 
1153  TRACE("Calling the notification callback...\n");
1154 
1156 
1157  memzero(&gGuest, sizeof(gGuest));
1158 
1159  TRACE("All done!\n");
1160 }
1161 
1162 
1163 static BOOLEAN
1165  void
1166  )
1176 {
1177  INTSTATUS status;
1178  AG_WAITSTATE agWaitState;
1179  DWORD agTag;
1180 
1181  agWaitState = IntAgentGetState(&agTag);
1182  if (agWaitState != agNone)
1183  {
1184  WARNING("[SAFENESS] We have a %s agent with tag %u!\n",
1185  agWaitState == agActive ? "Active" : "Waiting", agTag);
1186  return FALSE;
1187  }
1188 
1191  if (INT_STATUS_CANNOT_UNLOAD == status)
1192  {
1193  return FALSE;
1194  }
1195 
1196  return TRUE;
1197 }
1198 
1199 
1200 INTSTATUS
1202  _In_ QWORD Flags
1203  )
1217 {
1218  INTSTATUS status = INT_STATUS_SUCCESS;
1219 
1220  IntPauseVcpus();
1221 
1222  if (gGuest.EnterHibernate)
1223  {
1224  LOG("Introcore shutdown requested while the guest is transitioning into hibernate...\n");
1225  }
1226 
1227  if (gGuest.BugCheckInProgress)
1228  {
1229  Flags |= IG_DISABLE_IGNORE_SAFENESS;
1230  }
1231 
1233  {
1236  }
1237 
1239 
1240  // Unless the caller specified to ignore it, we check all the threads so they won't return into our
1241  // detours/memtables/agents/etc. stubs.
1242  if (!!(Flags & IG_DISABLE_IGNORE_SAFENESS))
1243  {
1244  LOG("[INFO] Ignore safeness!\n");
1245  goto do_uninit;
1246  }
1247 
1248  if (!IntGuestIsSafeToDisable())
1249  {
1250  LOG("[INFO] It's not safe to unload yet!\n");
1251 
1252  status = INT_STATUS_CANNOT_UNLOAD;
1253  goto resume_and_exit;
1254  }
1255 
1256  if (gGuest.OSType == introGuestLinux)
1257  {
1259 
1261  {
1262  status = INT_STATUS_CANNOT_UNLOAD;
1263  goto resume_and_exit;
1264  }
1265  }
1266 
1267 do_uninit:
1268  IntGuestUninit();
1269 
1270 resume_and_exit:
1271  IntResumeVcpus();
1272 
1273  return status;
1274 }
1275 
1276 
1277 INTSTATUS
1279  _In_ DWORD Options
1280  )
1290 {
1291  INTSTATUS status;
1292  BOOLEAN skipAgentActivation = FALSE;
1293 
1294  if (__unlikely((Options & POST_RETRY_PERFAGENT) && gGuest.PtFilterWaiting))
1295  {
1296  LOG("[PTCORE] Will try to reinject the PT Filter...\n");
1297  status = IntPtiInjectPtFilter();
1298  if (!INT_SUCCESS(status))
1299  {
1300  ERROR("[ERROR] IntPtiInjectPtFilter failed: 0x%08x\n", status);
1301  }
1302  else
1303  {
1304  gGuest.PtFilterWaiting = FALSE;
1305  skipAgentActivation = TRUE;
1306  LOG("[PTCORE] PT Filter was re-injected with success!\n");
1307  }
1308  }
1309  else if (__unlikely((Options & POST_RETRY_PERFAGENT) && gGuest.VeAgentWaiting))
1310  {
1311  LOG("[VECORE] Will try to reinject the #VE Agent...\n");
1312  status = IntVeDeployAgent();
1313  if (!INT_SUCCESS(status))
1314  {
1315  ERROR("[ERROR] IntVeDeployAgent failed: 0x%08x\n", status);
1316  }
1317  else
1318  {
1319  gGuest.VeAgentWaiting = FALSE;
1320  skipAgentActivation = TRUE;
1321  LOG("[VECORE] The #VE Agent was re-injected with success!\n");
1322  }
1323  }
1324 
1325  if (!skipAgentActivation)
1326  {
1327  // Always try to wake up a pending agent, if there are any, except for when we successfully re-injected the PT
1328  // Filter.
1329  status = IntAgentActivatePendingAgent();
1330  if (!INT_SUCCESS(status))
1331  {
1332  ERROR("[ERROR] IntAgentActivatePendingAgent failed: 0x%08x\n", status);
1333  }
1334  }
1335 
1336  if (__likely(Options & POST_COMMIT_MEM))
1337  {
1338  status = IntHookCommitAllHooks();
1339  if (!INT_SUCCESS(status))
1340  {
1341  ERROR("[ERROR] IntHookCommitAllHooks failed: 0x%08x\n", status);
1342  }
1343  }
1344 
1345  if (Options & POST_COMMIT_MSR)
1346  {
1347  status = IntHookMsrCommit();
1348  if (!INT_SUCCESS(status))
1349  {
1350  ERROR("[ERROR] IntHookMsrCommit failed: 0x%08x\n", status);
1351  }
1352  }
1353 
1354  if (Options & POST_COMMIT_DTR)
1355  {
1356  status = IntHookDtrCommit();
1357  if (!INT_SUCCESS(status))
1358  {
1359  ERROR("[ERROR] IntHookDtrCommit failed: 0x%08x\n", status);
1360  }
1361  }
1362 
1363  if (Options & POST_COMMIT_CR)
1364  {
1365  status = IntHookCrCommit();
1366  if (!INT_SUCCESS(status))
1367  {
1368  ERROR("[ERROR] IntHookCrCommit failed: 0x%08x\n", status);
1369  }
1370  }
1371 
1372  if (Options & POST_COMMIT_XCR)
1373  {
1374  status = IntHookXcrCommit();
1375  if (!INT_SUCCESS(status))
1376  {
1377  ERROR("[ERROR] IntHookXcrCommit failed: 0x%08x\n", status);
1378  }
1379  }
1380 
1381  if (__likely(Options & POST_INJECT_PF))
1382  {
1383  status = IntSwapMemInjectPendingPF();
1384  if (!INT_SUCCESS(status))
1385  {
1386  ERROR("[ERROR] IntSwapMemInjectPendingPF failed: 0x%08x\n", status);
1387  }
1388  }
1389 
1390  return INT_STATUS_SUCCESS;
1391 }
1392 
1393 
1394 void
1396  _In_ QWORD NewOptions
1397  )
1406 {
1407  // We must save them in case an update comes which removes a previously set ForceOff (and the NewOptions set it too)
1408  gGuest.ShemuOptions.Original = NewOptions;
1409 
1410  NewOptions &= ~gGuest.ShemuOptions.ForceOff;
1411 
1412  if (NewOptions == gGuest.ShemuOptions.Current)
1413  {
1414  return;
1415  }
1416 
1417  LOG("[DYNOPT] Change shemu options from %llx to %llx\n", gGuest.ShemuOptions.Current, NewOptions);
1418 
1419  gGuest.ShemuOptions.Current = NewOptions;
1420 }
1421 
1422 
1423 void
1425  _In_ QWORD NewOptions
1426  )
1435 {
1436  // We must save them in case an update comes which removes a previously set ForceOff (and the NewOptions set it too)
1437  gGuest.CoreOptions.Original = NewOptions;
1438 
1439  NewOptions &= ~gGuest.CoreOptions.ForceOff;
1440 
1441  if (NewOptions == gGuest.CoreOptions.Current)
1442  {
1443  return;
1444  }
1445 
1446  if (gGuest.UninitPrepared)
1447  {
1448  WARNING("[WARNING] Cannot modify options now, an uninit is pending!\n");
1449  return;
1450  }
1451 
1452  if (!!(NewOptions & INTRO_OPT_IN_GUEST_PT_FILTER) && !!(NewOptions & INTRO_OPT_VE))
1453  {
1454  gGuest.PtFilterFlagRemoved = FALSE;
1455 
1456  if (gGuest.VeInitialized)
1457  {
1458  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, will ignore"
1459  "INTRO_OPT_IN_GUEST_PT_FILTER, because #VE is initialized!\n");
1460  NewOptions &= ~INTRO_OPT_IN_GUEST_PT_FILTER;
1461  gGuest.PtFilterFlagRemoved = TRUE;
1462  }
1463  else
1464  {
1465  WARNING("[WARNING] Both INTRO_OPT_IN_GUEST_PT_FILTER and INTRO_OPT_VE are set, will ignore INTRO_OPT_VE, "
1466  "because #VE is NOT initialized!\n");
1467  NewOptions &= ~INTRO_OPT_VE;
1468  }
1469  }
1470 
1471  LOG("[DYNOPT] Change core options from %llx to %llx\n", gGuest.CoreOptions.Current, NewOptions);
1472 
1473  gGuest.CoreOptions.Current = NewOptions;
1476 
1477  // We don't know what os this is, or we can't apply options yet... we can bail out now.
1478  if (!gGuest.GuestInitialized || !gGuest.SafeToApplyOptions)
1479  {
1480  return;
1481  }
1482 
1483  IntPauseVcpus();
1484 
1485  if (introGuestWindows == gGuest.OSType)
1486  {
1487  // Enable or disable detours, depending on active options.
1489 
1490  // Enable or disable driver object and fast I/O dispatch table hooks.
1491  // Covers INTRO_OPT_PROT_KM_DRVOBJ.
1493 
1494  // Enable or disable nt, hal, core, av and xen drivers protection.
1495  // Covers INTRO_OPT_PROT_KM_NT, INTRO_OPT_PROT_KM_SSDT, INTRO_OPT_PROT_KM_HAL,
1496  // INTRO_OPT_PROT_KM_NT_DRIVERS, INTRO_OPT_PROT_KM_AV_DRIVERS and INTRO_OPT_PROT_KM_XEN_DRIVERS
1498 
1499  // Enable or disable hal dispatch table, hal heap and hal interrupt controller protection.
1500  // Covers INTRO_OPT_PROT_KM_HAL_DISP_TABLE, INTRO_OPT_PROT_KM_HAL_HEAP_EXEC and INTRO_OPT_PROT_KM_HAL_INT_CTRL.
1502 
1503  // Enable or disable process protection.
1504  // Covers INTRO_OPT_PROT_UM_MISC_PROCS and INTRO_OPT_PROT_UM_SYS_PROCS.
1506 
1508  {
1510  }
1511  else
1512  {
1514  }
1515 
1517  {
1519  }
1520  else
1521  {
1523  }
1524 
1526  {
1527  IntCr4Protect();
1528  }
1529  else
1530  {
1531  IntCr4Unprotect();
1532  }
1533 
1534  // INTRO_OPT_PROT_KM_SYSTEM_CR3 and INTRO_OPT_PROT_KM_TOKEN_PTR are tested directly in the timer, so no need
1535  // to do anything here.
1536  // All the other options are not protection related and can be toggled as well.
1537 
1538  // First of, schedule agents removal.
1539  if (!(gGuest.CoreOptions.Current & INTRO_OPT_IN_GUEST_PT_FILTER))
1540  {
1542  }
1543 
1544  if (!(gGuest.CoreOptions.Current & INTRO_OPT_VE))
1545  {
1546  IntVeRemoveAgent(0);
1547  }
1548 
1549  if (gGuest.CoreOptions.Current & INTRO_OPT_IN_GUEST_PT_FILTER)
1550  {
1552  }
1553 
1554  if (gGuest.CoreOptions.Current & INTRO_OPT_VE)
1555  {
1556  IntVeDeployAgent();
1557  }
1558 
1560  {
1562  }
1563  else
1564  {
1566  }
1567 
1569  {
1570  IntIdtrProtect();
1571  }
1572  else
1573  {
1574  IntIdtrUnprotect();
1575  }
1576 
1578  {
1579  IntGdtrProtect();
1580  }
1581  else
1582  {
1583  IntGdtrUnprotect();
1584  }
1585 
1587  {
1589  }
1590  else
1591  {
1593  }
1594 
1596  {
1598  }
1599  else
1600  {
1602  }
1603 
1605  {
1607  }
1608  else
1609  {
1611  }
1612 
1614  {
1616  }
1617  else
1618  {
1620  }
1621  }
1622  else if (introGuestLinux == gGuest.OSType)
1623  {
1624  // Enable or disable detours, depending on active options.
1626 
1628  {
1630  }
1631  else
1632  {
1634  }
1635 
1637  {
1639  }
1640  else
1641  {
1643  }
1644 
1646  {
1648  }
1649  else
1650  {
1652  }
1653 
1655  {
1657  }
1658  else
1659  {
1661  }
1662 
1664  {
1665  IntCr4Protect();
1666  }
1667  else
1668  {
1669  IntCr4Unprotect();
1670  }
1671 
1673  {
1675  }
1676  else
1677  {
1679  }
1680 
1682  {
1683  IntIdtrProtect();
1684  }
1685  else
1686  {
1687  IntIdtrUnprotect();
1688  }
1689 
1691  {
1692  IntGdtrProtect();
1693  }
1694  else
1695  {
1696  IntGdtrUnprotect();
1697  }
1698 
1699  // INTRO_OPT_PROT_KM_TOKEN_PTR is checked before integrity checks for creds.
1700 
1702 
1704  }
1705  else
1706  {
1707  WARNING("[WARNING] Unknown os type %d.\n", gGuest.OSType);
1708  }
1709 
1710  IntResumeVcpus();
1711 }
1712 
1713 
1714 INTSTATUS
1716  _Out_ QWORD *MaxGpa
1717  )
1729 {
1730 
1731  if (gGuest.Mm.LastGpa == 0)
1732  {
1733  QWORD maxGpfn = 0;
1734  INTSTATUS status = IntGetMaxGpfn(&maxGpfn);
1735 
1736  if (!INT_SUCCESS(status))
1737  {
1738  ERROR("[ERROR] IntGetMaxGpfn failed: 0x%08x\n", status);
1739  return status;
1740  }
1741 
1742  // IntGetMaxGpfn will return the last accessible page frame number, we need to set LastGpa to the next page
1743  gGuest.Mm.LastGpa = (maxGpfn << 12) + PAGE_SIZE;
1744  }
1745 
1746  *MaxGpa = gGuest.Mm.LastGpa;
1747  return INT_STATUS_SUCCESS;
1748 }
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:2620
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:47
#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:1737
BOOLEAN SupportDTR
Set to True if support for DTR access exits was detected.
Definition: guests.h:354
INTSTATUS IntGuestInit(QWORD Options)
Initialize the given guest state.
Definition: guests.c:753
#define INTRO_OPT_VE
Enable the Virtualization exception page table access pre-filtering agent (64-bit Windows only)...
Definition: intro_types.h:459
#define IC_TAG_CAMI
Live update allocations.
Definition: memtags.h:122
void IntCamiClearUpdateBuffer(void)
Uninitialize the update buffer and notify the integrator that we don&#39;t need it anymore.
Success.
Definition: intro_types.h:2272
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:79
Commit all the MSR hooks.
Definition: guests.h:433
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:35
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:57
#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:207
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
QWORD Efer
Definition: guests.h:210
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:393
static INTSTATUS IntGuestDetectOs(INTRO_GUEST_TYPE *OsType, BOOLEAN *KptiInstalled, BOOLEAN *KptiActive)
Detect the type of the currently running guest kernel.
Definition: guests.c:280
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:403
BOOLEAN SysprocBetaDetections
Definition: guests.h:300
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:147
INTSTATUS IntWinGuestUnprotectSudExec(void)
Removes the execution EPT hook on SharedUserData.
Definition: winguest.c:1135
DWORD IntGetCurrentCpu(void)
Returns the current CPU number.
Definition: introcpu.c:802
void IntDetUninit(void)
Uninitializes the detour module.
Definition: detours.c:1762
BOOLEAN Initialized
True if this structure was initialized and can be used.
Definition: guests.h:285
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 IntWinTokenUnprotectPrivs(void)
Unprotects all the currently protected tokens belonging to processes against privileges manipulation...
Definition: wintoken.c:1135
A critical structure was not found inside the guest kernel.
Definition: intro_types.h:2278
#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:441
#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:297
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
Definition: guests.h:299
#define INTRO_OPT_PROT_KM_LX_TEXT_READS
Enable kernel &#39;_text&#39; section read protection (Linux only).
Definition: intro_types.h:483
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:290
INTSTATUS IntWinTokenProtectPrivs(void)
Protects all the currently unprotected tokens belonging to processes against privileges manipulation...
Definition: wintoken.c:1094
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:2006
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:2274
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:277
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:352
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 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:84
INTSTATUS IntCallbacksUnInit(void)
Uninit all the Introcore callbacks.
Definition: callbacks.c:3385
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
Definition: guests.h:368
#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:396
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:274
BOOLEAN VeAgentWaiting
True if the #VE agent was not yet injected, but it should be.
Definition: guests.h:348
INTSTATUS IntSwapMemUnInit(void)
Uninit the swapmem system.
Definition: swapmem.c:1044
Commit all the memory hooks.
Definition: guests.h:432
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:208
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:2577
void IntLixApiUpdateHooks(void)
Update the hookable APIs according to the current Introcore options.
Definition: lixapi.c:340
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:484
INTSTATUS IntWinDrvObjUpdateProtection(void)
Updates the protection for all the driver objects in the gWinDriverObjects list.
Definition: windrvobj.c:1330
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:2760
INTSTATUS IntWinUnprotectReadNtEat(void)
Used to remove the EAT read hook from ntoskrnl.exe.
Definition: windriver.c:674
static DWORD gInitRetryCount
The number of times initialization was tried.
Definition: guests.c:60
INTSTATUS IntGdtrProtect(void)
Enable GDTR protection.
#define INTRO_OPT_PROT_KM_SELF_MAP_ENTRY
Definition: intro_types.h:422
BOOLEAN PtFilterWaiting
True if the in-guest PT filter was not yet injected, but it should be.
Definition: guests.h:341
INTSTATUS IntWinIdtUnprotectAll(void)
Removes the IDT protection for all the guest CPUs.
Definition: winidt.c:591
BOOLEAN IntLixGuestDeployUninitAgent(void)
Inject the &#39;uninit&#39; agent to free the previously allocated memory for detours/agents.
Definition: lixguest.c:2291
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
Definition: guests.h:287
#define CR4_LA57
Definition: processor.h:55
#define INTRO_OPT_SYSPROC_BETA_DETECTIONS
Enable system processes beta (log only) detection.
Definition: intro_types.h:456
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:434
#define INTRO_OPT_PROT_KM_MSR_SYSCALL
Definition: intro_types.h:411
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
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:353
#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
#define IC_TAG_CPUS
CPU state.
Definition: memtags.h:66
The context of an error state.
Definition: intro_types.h:2252
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:291
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:78
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:438
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:286
unsigned long long QWORD
Definition: intro_types.h:53
static INTRO_ERROR_STATE gErrorState
The last error reported.
Definition: guests.c:63
QWORD Current
The currently used options.
Definition: guests.h:232
#define INTRO_OPT_PROT_KM_IDTR
Enable interrupt descriptor-table registers protection.
Definition: intro_types.h:413
INTSTATUS IntGuestPreReturnCallback(DWORD Options)
Handles all the operations that must be done before returning from a VMEXIT event handler...
Definition: guests.c:1278
BOOLEAN IntGuestShouldNotifyErrorState(void)
Checks if an event should be sent to the integrator.
Definition: guests.c:133
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:1789
INTSTATUS IntLixVdsoProtect(void)
Activates protection for the vDSO image and VSYSCALL.
Definition: lixvdso.c:883
void * GpaCache
The currently used GPA cache.
Definition: guests.h:399
#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:215
BOOLEAN GuestInitialized
True if the OS-specific portion has been initialized.
Definition: guests.h:289
#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:105
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:363
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:511
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:119
INTSTATUS IntNotifyIntroInactive(void)
Definition: glue.c:941
BOOLEAN UninitPrepared
Definition: guests.h:316
#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:66
QWORD ForceOff
Options that are forcibly disabled.
Definition: guests.h:238
void IntGuestUninit(void)
Completely unloads the introspection engine.
Definition: guests.c:1034
4-level paging
Definition: introcore.h:71
void IntGuestPrepareUninit(void)
Prepares introcore to be unloaded.
Definition: guests.c:982
#define SYSCALL_SIG_FLAG_KPTI
Indicates that a syscall pattern belongs to a KPTI enabled OS.
Definition: guests.c:69
#define INTRO_OPT_PROT_KM_NT_EAT_READS
Enable kernel EAT read protection (Windows only).
Definition: intro_types.h:481
DWORD CpuCount
The number of logical CPUs.
Definition: guests.h:275
INTSTATUS IntSwapMemInjectPendingPF(void)
Inject a PF for a pending page.
Definition: swapmem.c:698
#define PAGE_SIZE
Definition: common.h:53
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
void IntStatsDumpAll(void)
Prints all the non-zero stats.
Definition: stats.c:213
INTSTATUS IntGuestGetLastGpa(QWORD *MaxGpa)
Get the upper limit of the guest physical memory range.
Definition: guests.c:1715
INTRO_GUEST_TYPE
The type of the introspected operating system.
Definition: intro_types.h:1877
void * InstructionCache
The currently used instructions cache.
Definition: guests.h:400
#define INTRO_OPT_KM_BETA_DETECTIONS
Definition: intro_types.h:441
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:1201
INTSTATUS IntWinHalUpdateProtection(void)
Updates any of the HAL protections.
Definition: winhal.c:1385
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:606
void IntSlackUninit(void)
Uninit the slack system. Must be called only during uninit.
Definition: slack.c:466
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTSTATUS IntGuestGetInfo(PGUEST_INFO GuestInfo)
Get basic information about the guest.
Definition: guests.c:348
BOOLEAN VeInitialized
Set to True if #VE initialization was done.
Definition: guests.h:349
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:48
PAGING_MODE
Paging modes.
Definition: introcore.h:66
void IntWinGuestUninit(void)
Uninits a Windows guest.
Definition: winguest.c:675
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:4458
BOOLEAN EnterHibernate
True if the guest is entering into hibernate.
Definition: guests.h:315
QWORD Cr0
Cr0 value used when deducing the paging mode.
Definition: guests.h:209
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:370
void IntGuestUpdateCoreOptions(QWORD NewOptions)
Updates Introcore options.
Definition: guests.c:1424
void IntDetDisableAllHooks(void)
Removes all detours from the guest.
Definition: detours.c:1742
static BOOLEAN IntGuestIsSafeToDisable(void)
Checks if it is safe to unload.
Definition: guests.c:1164
INTSTATUS IntWinProcUpdateProtection(void)
Iterates trough the global process list (gWinProcesses) in order to update the protection state for e...
Definition: winprocess.c:1155
INTSTATUS IntWinIdtProtectAll(void)
Activates the IDT protection for all the guest CPUs.
Definition: winidt.c:560
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:2270
#define EFER_LMA
Definition: processor.h:94
Guest information.
Definition: intro_types.h:2214
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:268
#define THS_CHECK_ONLY
Will check for safeness, without moving any RIP or stack value.
Commit all the XCR hooks.
Definition: guests.h:435
INTSTATUS IntWinGuestProtectSudExec(void)
Protects SharedUserData against executions by establishing an EPT hook on it.
Definition: winguest.c:1100
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:288
QWORD Original
The original options as received from GLUE_IFACE.NewGuestNotification. This is updated when GLUE_IFAC...
Definition: guests.h:227
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:88
#define NLOG(fmt,...)
Definition: glue.h:43
BOOLEAN SupportVE
Set to True if support for #VE was detected.
Definition: guests.h:351
BOOLEAN LA57
True if 5-level paging is being used.
Definition: guests.h:292
PAGING_MODE Mode
The paging mode used by the guest.
Definition: guests.h:217
#define THS_CHECK_TRAMPOLINE
Will check if any RIP is inside the agent loader.
void IntGuestUpdateShemuOptions(QWORD NewOptions)
Update shemu options.
Definition: guests.c:1395
void IntLixGuestUninit(void)
Uninitialize the Linux guest.
Definition: lixguest.c:1673
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:272
#define __likely(x)
Definition: common.h:46
void IntWinGuestCancelKernelRead(void)
Cancels the kernel read.
Definition: winguest.c:611
INTSTATUS IntWinSelfMapEnableSelfMapEntryProtection(void)
Enables the self map protection mechanism for the entire system.
Definition: winselfmap.c:508
#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:499
#define INTRO_OPT_PROT_KM_TOKEN_PRIVS
Enable protection over Token Privileges bitmaps.
Definition: intro_types.h:489
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:802
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:410
BOOLEAN BugCheckInProgress
Definition: guests.h:329
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:361
INTSTATUS IntCallbacksInit(void)
Initialize the callbacks.
Definition: callbacks.c:3336
BOOLEAN DisableOnReturn
Set to True if after returning from this event handler, introcore must be unloaded.
Definition: guests.h:324
BYTE Version
The version field of the version string.
Definition: lixguest.h:484
Describes a guest.
Definition: guests.h:265
#define INTRO_OPT_IN_GUEST_PT_FILTER
Enable in-guest page-table filtering (64-bit Windows only).
Definition: intro_types.h:445
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:647
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:267
static INTSTATUS IntGuestInitMemoryInfo(void)
Initializes gGuest.Mm.
Definition: guests.c:461
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:193
#define INTRO_OPT_PROT_KM_LOGGER_CONTEXT
Enable protection on WMI_LOGGER_CONTEXT.GetCpuClock used by InfinityHook (Windows only)...
Definition: intro_types.h:469
#define INTRO_OPT_PROT_KM_GDTR
Enable global descriptor-table registers protection.
Definition: intro_types.h:424
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
Definition: lixguest.c:29
Inject pending page faults.
Definition: guests.h:437
Commit all the DTR hooks.
Definition: guests.h:436
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