Bitdefender Hypervisor Memory Introspection
winselfmap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "winselfmap.h"
6 #include "alerts.h"
7 #include "hook.h"
8 
10 
11 
12 __forceinline static void
14  _In_ QWORD ModifiedCr3,
15  _Inout_ WIN_PROCESS_OBJECT *Process,
16  _In_ QWORD NewValue
17  )
28 {
29  if (Process->Cr3 == ModifiedCr3)
30  {
31  Process->SelfMapEntryValue = NewValue;
32  }
33  else
34  {
35  Process->UserSelfMapEntryValue = NewValue;
36  }
37 }
38 
39 
40 static INTSTATUS
42  _In_ QWORD NewValue,
43  _In_ QWORD OldValue,
44  _Inout_ WIN_PROCESS_OBJECT *Process,
45  _In_ QWORD Cr3
46  )
57 {
58  INTSTATUS status;
59  INTRO_ACTION action;
60  INTRO_ACTION_REASON reason;
62 
63  action = introGuestNotAllowed;
64  reason = introReasonNoException;
65 
66  memzero(pTr, sizeof(*pTr));
67 
68  WARNING("[WARNING] Self-mapping entry modified for process '%s' with CR3 %llx (%s), addr %llx, "
69  "from 0x%016llx to 0x%016llx\n", Process->Name, Cr3, Cr3 == Process->Cr3 ? "kernel" : "user",
70  SELF_MAP_ENTRY(Cr3), OldValue, NewValue);
71 
73  {
74  LOG("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (B) ROOTKIT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n");
75  }
76  else
77  {
78  LOG("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ROOTKIT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n");
79 
80  QWORD *pPage = NULL;
81 
82  status = IntPhysMemMap(SELF_MAP_ENTRY(Cr3), sizeof(QWORD), 0, &pPage);
83  if (!INT_SUCCESS(status))
84  {
85  ERROR("[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
86  goto _just_send_alert;
87  }
88 
89  // restore only the US bit in case of modification
90  pPage[0] = NewValue & (~PT_US);
91 
92  IntPhysMemUnmap(&pPage);
93  }
94 
95  // We always update the selfmap with the new value
96  IntWinSelfMapSelfMapUpdate(Cr3, Process, NewValue);
97 
98 _just_send_alert:
100  {
101  pTr->Header.Action = action;
102  pTr->Header.Reason = reason;
103  pTr->Header.MitreID = idRootkit;
104 
106 
107  if (Process->SystemProcess)
108  {
110  }
111 
113 
115 
117 
118  pTr->WriteInfo.NewValue[0] = NewValue;
119  pTr->WriteInfo.OldValue[0] = OldValue;
120  pTr->WriteInfo.Size = sizeof(QWORD);
121 
122  pTr->Originator.Module.Valid = FALSE;
123  pTr->Header.CpuContext.Valid = FALSE;
125 
128 
129  status = IntNotifyIntroEvent(introEventTranslationViolation, pTr, sizeof(*pTr));
130  if (!INT_SUCCESS(status))
131  {
132  WARNING("[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
133  }
134  }
135 
136  return INT_STATUS_SUCCESS;
137 }
138 
139 
140 static INTSTATUS
142  _Inout_ WIN_PROCESS_OBJECT *Process,
143  _In_opt_ const QWORD *CurrentKernelValue,
144  _In_opt_ const QWORD *CurrentUserValue
145  )
162 {
163  QWORD currentKern, currentUser;
164  INTSTATUS status = INT_STATUS_SUCCESS;
165 
166  if (NULL == CurrentKernelValue)
167  {
168  status = IntPhysicalMemRead(SELF_MAP_ENTRY(Process->Cr3), sizeof(QWORD), &currentKern, NULL);
169  if (!INT_SUCCESS(status))
170  {
171  ERROR("[ERROR] IntPhysicalMemRead failed: 0x%08x\n", status);
172  goto _exit;
173  }
174  }
175  else
176  {
177  currentKern = *CurrentKernelValue;
178  }
179 
180  if (NULL == CurrentUserValue && Process->Cr3 != Process->UserCr3)
181  {
182  status = IntPhysicalMemRead(SELF_MAP_ENTRY(Process->UserCr3), sizeof(QWORD), &currentUser, NULL);
183  if (!INT_SUCCESS(status))
184  {
185  ERROR("[ERROR] IntPhysicalMemRead failed: 0x%08x\n", status);
186  goto _exit;
187  }
188  }
189  else if (Process->Cr3 != Process->UserCr3)
190  {
191  currentUser = *CurrentUserValue;
192  }
193  else
194  {
195  goto _only_kern_check;
196  }
197 
198  // When in beta, we should also verify that our stored value didn't have the U/S bit as on kernel beta detections
199  // we only want to give an alert when this bit was modified vs. what we have stored instead of sending an alert
200  // every time we check, but if KernelBetaDetections was changed on the fly we should also consider a detection
201  // even if our previously stored value had U/S bit activated.
202  if (Process->Cr3 != Process->UserCr3)
203  {
204  if (SELF_MAP_ENTRY_IS_DETECTION(currentUser) &&
205  ((Process->UserSelfMapEntryValue & PT_US) != (currentUser & PT_US) || !gGuest.KernelBetaDetections))
206  {
207  status = IntWinSelfMapHandleCr3SelfMapModification(currentUser, Process->UserSelfMapEntryValue, Process,
208  Process->UserCr3);
209  if (!INT_SUCCESS(status))
210  {
211  ERROR("[ERROR] IntWinSelfMapCr3SelfMapModification failed: 0x%x\n", status);
212  }
213  }
214  else if (Process->UserSelfMapEntryValue != currentUser)
215  {
216  Process->UserSelfMapEntryValue = currentUser;
217  }
218  }
219 
220 _only_kern_check:
221  if (SELF_MAP_ENTRY_IS_DETECTION(currentKern) &&
222  ((Process->SelfMapEntryValue & PT_US) != (currentKern & PT_US) || !gGuest.KernelBetaDetections))
223  {
224  status = IntWinSelfMapHandleCr3SelfMapModification(currentKern,
225  Process->SelfMapEntryValue,
226  Process,
227  Process->Cr3);
228  if (!INT_SUCCESS(status))
229  {
230  ERROR("[ERROR] IntWinSelfMapCr3SelfMapModification failed: 0x%x\n", status);
231  }
232  }
233  else if (Process->SelfMapEntryValue != currentKern)
234  {
235  Process->SelfMapEntryValue = currentKern;
236  }
237 
238 _exit:
239  return status;
240 }
241 
242 
243 static INTSTATUS
245  _Inout_ WIN_PROCESS_OBJECT *Context,
246  _In_ void *Hook,
247  _In_ QWORD Address,
248  _Out_ INTRO_ACTION *Action
249  )
268 {
269  WIN_PROCESS_OBJECT *pProc = Context;
270  INTSTATUS status;
271  EXCEPTION_KM_ORIGINATOR originator = { 0 };
272  EXCEPTION_VICTIM_ZONE victim = { 0 };
273  IG_ARCH_REGS *regs;
274  INTRO_ACTION action;
275  INTRO_ACTION_REASON reason;
276  QWORD gva;
277  QWORD cr3Modified;
278  BOOLEAN isBeta;
279 
280  regs = &gVcpu->Regs;
281  action = introGuestNotAllowed;
282  reason = introReasonNoException;
284 
285  cr3Modified = CLEAN_PHYS_ADDRESS64(pProc->Cr3) == CLEAN_PHYS_ADDRESS64(Address) ? pProc->Cr3 : pProc->UserCr3;
286 
287  if (!gVcpu->PtEmuBuffer.Valid)
288  {
289  action = introGuestAllowed;
290  reason = introReasonAllowed;
291  goto cleanup_and_exit;
292  }
293 
294  // KPTI is enabled and relevant only for non-privileged processes. Processes which are already privileged
295  // (running as system/admin/etc.), do start with both the kernel and user CR3 allocated & initialized, but soon
296  // after the process is created, the user CR3 will be freed. The self-map mechanism will keep the protection on
297  // that user CR3. Eliminate the self-map protection on user CR3 once they are removed; we can figure out that a
298  // user CR3 is deleted when the self-map entry for tit is made invalid (present bit == 0).
299  if (!!(gVcpu->PtEmuBuffer.Old & PT_P) &&
300  !(gVcpu->PtEmuBuffer.New & PT_P))
301  {
302  action = introGuestAllowed;
303  reason = introReasonAllowed;
304 
305  if (Hook == pProc->SelfMapHook)
306  {
307  pProc->SelfMapHook = NULL;
308  }
309  else if (Hook == pProc->UserSelfMapHook)
310  {
311  pProc->UserSelfMapHook = NULL;
312  }
313 
314  status = IntHookGpaRemoveHook((HOOK_GPA **)&Hook, 0);
315  if (!INT_SUCCESS(status))
316  {
317  ERROR("[ERROR] IntHookGpaRemoveHook failed: 0x%08x\n", status);
318  }
319 
320  return INT_STATUS_SUCCESS;
321  }
322 
323  if (gVcpu->PtEmuBuffer.Old == 0 ||
325  {
326  action = introGuestAllowed;
327  reason = introReasonAllowed;
328 
329  IntWinSelfMapSelfMapUpdate(cr3Modified, pProc, gVcpu->PtEmuBuffer.New);
330 
331  goto cleanup_and_exit;
332  }
333 
335 
336  status = IntExceptKernelGetOriginator(&originator, 0);
337  if (!INT_SUCCESS(status))
338  {
339  WARNING("[WARNING] IntExceptKernelGetOriginator failed: 0x%08x\n", status);
340  }
341 
342  gva = SELF_MAP_ENTRY_VA;
343 
344  status = IntExceptGetVictimEpt(Context, Address, gva, introObjectTypeSelfMapEntry, ZONE_WRITE, &victim);
345 
346  if (!INT_SUCCESS(status))
347  {
348  reason = introReasonInternalError;
349  ERROR("[ERROR] Failed getting zone details: 0x%08x\n", status);
350  goto _exit_exceptions;
351  }
352 
353  // overwrite with these values
354  victim.WriteInfo.NewValue[0] = gVcpu->PtEmuBuffer.New;
355  victim.WriteInfo.OldValue[0] = gVcpu->PtEmuBuffer.Old;
356  victim.WriteInfo.AccessSize = sizeof(QWORD);
357 
358  IntExcept(&victim, &originator, exceptionTypeKm, &action, &reason, introEventEptViolation);
359 
360 _exit_exceptions:
362 
364  {
365  EVENT_EPT_VIOLATION *pEpt = &gAlert.Ept;
366 
367  memzero(pEpt, sizeof(*pEpt));
368 
369  WARNING("[WARNING] Self-mapping entry modified for process '%s' with CR3 %llx (%s), "
370  "addr %llx, from 0x%016llx to 0x%016llx from RIP 0x%016llx\n",
371  pProc->Name,
372  cr3Modified,
373  cr3Modified == pProc->Cr3 ? "kernel" : "user",
374  Address,
377  regs->Rip);
378 
379  if (!isBeta)
380  {
381  QWORD *pPage = NULL;
382 
383  status = IntPhysMemMap(Address, sizeof(QWORD), 0, &pPage);
384  if (!INT_SUCCESS(status))
385  {
386  ERROR("[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
387  goto just_send_alert;
388  }
389 
390  gVcpu->PtEmuBuffer.New &= (~PT_US);
391 
392  pPage[0] = gVcpu->PtEmuBuffer.New;
393 
394  IntPhysMemUnmap(&pPage);
395 
396  IntWinSelfMapSelfMapUpdate(cr3Modified, pProc, gVcpu->PtEmuBuffer.New);
397  }
398 
399 just_send_alert:
400  pEpt->Header.Action = action;
401  pEpt->Header.Reason = reason;
402  pEpt->Header.MitreID = idRootkit;
403 
405 
406  IntAlertEptFillFromKmOriginator(&originator, pEpt);
407  IntAlertEptFillFromVictimZone(&victim, pEpt);
408 
410 
411  if (pProc->SystemProcess)
412  {
414  }
415 
417 
418  IntAlertFillCodeBlocks(originator.Original.Rip, regs->Cr3, FALSE, &pEpt->CodeBlocks);
419  IntAlertFillExecContext(regs->Cr3, &pEpt->ExecContext);
420 
422 
423  status = IntNotifyIntroEvent(introEventEptViolation, pEpt, sizeof(*pEpt));
424  if (!INT_SUCCESS(status))
425  {
426  WARNING("[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
427  }
428  }
429 
430 cleanup_and_exit:
431  if (isBeta || action == introGuestAllowed)
432  {
433  IntWinSelfMapSelfMapUpdate(cr3Modified, pProc, gVcpu->PtEmuBuffer.New);
434  }
435 
437 
438  *Action = action;
439 
440  return INT_STATUS_SUCCESS;
441 }
442 
443 
446  void
447  )
463 {
464  LIST_ENTRY *pList = NULL;
465 
467  {
469  }
470 
472  {
474  }
475 
476  if ((introGuestWindows != gGuest.OSType) ||
480  {
482  }
483 
485 
486  pList = gWinProcesses.Flink;
487  while (pList != &gWinProcesses)
488  {
489  WIN_PROCESS_OBJECT *pProcess = CONTAINING_RECORD(pList, WIN_PROCESS_OBJECT, Link);
490  INTSTATUS status;
491 
492  pList = pList->Flink;
493 
494  status = IntWinSelfMapCheckSelfMapEntry(pProcess, NULL, NULL);
495  if (!INT_SUCCESS(status))
496  {
497  ERROR("[ERROR] IntWinCheckSelfMapEntry failed: 0x%08x\n", status);
498  }
499  }
500 
502 
503  return INT_STATUS_SUCCESS;
504 }
505 
506 
507 INTSTATUS
509  void
510  )
522 {
523  PLIST_ENTRY pList = NULL;
524 
526  {
528  }
529 
531  {
533  }
534 
535  if ((introGuestWindows != gGuest.OSType) ||
538  {
540  }
541 
542  pList = gWinProcesses.Flink;
543  while (pList != &gWinProcesses)
544  {
545  WIN_PROCESS_OBJECT *pProcess = CONTAINING_RECORD(pList, WIN_PROCESS_OBJECT, Link);
546  INTSTATUS status;
547 
548  pList = pList->Flink;
549 
550  status = IntWinSelfMapCheckSelfMapEntry(pProcess, NULL, NULL);
551 
552  // no point in protecting the process if it already has a hook on it...
553  if (pProcess->SelfMapHook != NULL && pProcess->UserSelfMapHook != NULL)
554  {
555  continue;
556  }
557 
558  status = IntWinSelfMapProtectSelfMapIndex(pProcess);
559  if (!INT_SUCCESS(status))
560  {
561  ERROR("[ERROR] IntWinProtectSelfMapIndex failed: 0x%08x\n", status);
562  continue;
563  }
564  }
565 
566  return INT_STATUS_SUCCESS;
567 }
568 
569 
570 INTSTATUS
572  _Inout_ WIN_PROCESS_OBJECT *Process
573  )
590 {
591  INTSTATUS status;
592  QWORD currentKern, currentUser;
593 
594  if (NULL == Process)
595  {
597  }
598 
600  {
602  }
603 
605  {
607  }
608 
609  if ((introGuestWindows != gGuest.OSType) ||
612  {
614  }
615 
616  status = IntPhysicalMemRead(SELF_MAP_ENTRY(Process->Cr3), sizeof(QWORD), &currentKern, NULL);
617  if (!INT_SUCCESS(status))
618  {
619  ERROR("[ERROR] IntPhysicalMemRead failed: 0x%08x\n", status);
620  goto _exit;
621  }
622 
623  // assume current self map entry value has U/S bit deactivated, as we should give a detection on integrity checking
624  Process->SelfMapEntryValue = (currentKern & (~PT_US));
625 
626  status = IntPhysicalMemRead(SELF_MAP_ENTRY(Process->UserCr3), sizeof(QWORD), &currentUser, NULL);
627  if (!INT_SUCCESS(status))
628  {
629  ERROR("[ERROR] IntPhysicalMemRead failed: 0x%08x\n", status);
630  goto _exit;
631  }
632 
633  // assume current self map entry value has U/S bit deactivated, as we should give a detection on integrity checking
634  Process->UserSelfMapEntryValue = (currentUser & (~PT_US));
635 
637  {
638  status = IntWinSelfMapCheckSelfMapEntry(Process, &currentKern, &currentUser);
639  }
640 
641 _exit:
642  return status;
643 }
644 
645 
646 INTSTATUS
648  void
649  )
660 {
661  LIST_ENTRY *pList = NULL;
662 
664  {
666  }
667 
669  {
671  }
672 
673  if ((introGuestWindows != gGuest.OSType) ||
676  {
678  }
679 
680  pList = gWinProcesses.Flink;
681  while (pList != &gWinProcesses)
682  {
683  WIN_PROCESS_OBJECT *pProcess = CONTAINING_RECORD(pList, WIN_PROCESS_OBJECT, Link);
684  INTSTATUS status;
685 
686  pList = pList->Flink;
687 
688  status = IntWinSelfMapUnprotectSelfMapIndex(pProcess);
689  if (!INT_SUCCESS(status))
690  {
691  ERROR("[ERROR] IntWinSelfMapUnprotectSelfMapIndex failed: 0x%08x\n", status);
692  continue;
693  }
694  }
695 
696  return INT_STATUS_SUCCESS;
697 }
698 
699 
700 INTSTATUS
702  _Inout_ WIN_PROCESS_OBJECT *Process
703  )
723 {
724 
725  INTSTATUS status = INT_STATUS_SUCCESS;
726  BOOLEAN bShouldProtect = FALSE;
727 
728  if (NULL == Process)
729  {
731  }
732 
733  if ((introGuestWindows != gGuest.OSType) ||
737  {
739  }
740 
741  // Force only integrity mechanism to kick-in: as we have seen, processes might be "swapped-out"
742  // (see MmSwapOutProcess) - when a process is then swapped in (see MmSwapInProcess), it verifies OutSwapped
743  // flag in EPROCESS.Flags, and if it is set, it copies the whole upper entries (>0x800) from the current process
744  // kernel PML4 into the upper entries of the swapped in process PML4, using memmove, case in which some MOVDQA
745  // instructions come on kernel page tables (because this is the only hook we put on kernel page tables on
746  // protected processes). So, until we find a better solution, keep only the integrity check.
747  bShouldProtect = Process->Pid == 4;
748 
749  TRACE("[INFO] Protecting self-mapping entry for process %s, pid %d with CR3: %llx, UserCR3: %llx with %s\n",
750  Process->Name, Process->Pid, Process->Cr3, Process->UserCr3, bShouldProtect ? "EPT" : "INTEGRITY");
751 
752  if (bShouldProtect)
753  {
754  if (Process->SelfMapHook == NULL)
755  {
756  status = IntHookGpaSetHook(SELF_MAP_ENTRY(Process->Cr3),
757  sizeof(QWORD),
760  Process,
761  NULL,
763  (PHOOK_GPA *)&Process->SelfMapHook);
764  if (!INT_SUCCESS(status))
765  {
766  ERROR("[ERROR] IntHookGpaSetHook failed: 0x%08x\n", status);
767  }
768  }
769 
770  // Avoid double hooking
771  if (Process->Cr3 != Process->UserCr3 && Process->UserSelfMapHook == NULL)
772  {
773  status = IntHookGpaSetHook(SELF_MAP_ENTRY(Process->UserCr3),
774  sizeof(QWORD),
777  Process,
778  NULL,
780  (PHOOK_GPA *)&Process->UserSelfMapHook);
781  if (!INT_SUCCESS(status))
782  {
783  ERROR("[ERROR] IntHookGpaSetHook failed: 0x%08x\n", status);
784  }
785  }
786  }
787 
788  return status;
789 }
790 
791 
792 INTSTATUS
794  _Inout_ WIN_PROCESS_OBJECT *Process
795  )
806 {
807  INTSTATUS status = INT_STATUS_SUCCESS;
808 
809  if (Process == NULL)
810  {
812  }
813 
814  TRACE("[INFO] Deactivating self-map index protection for %s (pid %d, cr3: kernel %016llx, user: %016llx)\n",
815  Process->Name, Process->Pid, Process->Cr3, Process->UserCr3);
816 
817  if (Process->SelfMapHook != NULL)
818  {
819  status = IntHookGpaRemoveHook((HOOK_GPA **)&Process->SelfMapHook, 0);
820  if (!INT_SUCCESS(status))
821  {
822  ERROR("[ERROR] IntHookGpaRemoveHook failed: 0x%08x\n", status);
823  }
824  }
825 
826  if (Process->UserSelfMapHook != NULL)
827  {
828  status = IntHookGpaRemoveHook((HOOK_GPA **)&Process->UserSelfMapHook, 0);
829  if (!INT_SUCCESS(status))
830  {
831  ERROR("[ERROR] IntHookGpaRemoveHook failed: 0x%08x\n", status);
832  }
833  }
834 
835  return status;
836 }
Measures kernel mode exceptions checks.
Definition: stats.h:51
#define _In_opt_
Definition: intro_sal.h:16
struct _EXCEPTION_KM_ORIGINATOR::@63 Original
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
INTRO_CODEBLOCKS CodeBlocks
Code blocks extracted for the alert.
Definition: intro_types.h:1145
_Bool BOOLEAN
Definition: intro_types.h:58
#define _Out_
Definition: intro_sal.h:22
#define CONTAINING_RECORD(List, Type, Member)
Definition: introlists.h:36
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
Definition: intro_types.h:818
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
Definition: alerts.c:366
DWORD Size
The size of the access.
Definition: intro_types.h:896
static INTSTATUS IntWinSelfMapHandleCr3SelfMapWrite(WIN_PROCESS_OBJECT *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Handles writes done to the self map entry inside a process page tables.
Definition: winselfmap.c:244
An internal error occurred (no memory, pages not present, etc.).
Definition: intro_types.h:195
INTSTATUS IntPhysicalMemRead(QWORD PhysicalAddress, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest physical memory range, but only for a single page.
Definition: introcore.c:721
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
Definition: introcore.c:2803
IG_ARCH_REGS Regs
The current state of the guest registers.
Definition: guests.h:95
#define _In_
Definition: intro_sal.h:21
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
Definition: intro_types.h:1088
INTSTATUS IntHookGpaRemoveHook(HOOK_GPA **Hook, DWORD Flags)
Remove a GPA hook.
Definition: hook_gpa.c:734
#define CLEAN_PHYS_ADDRESS64(x)
Definition: pgtable.h:119
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
BOOLEAN IntPolicyCoreTakeAction(QWORD Flag, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a core introspection option.
Definition: introcore.c:2693
QWORD NewValue[8]
The written value. Only the first Size bytes are valid.
Definition: intro_types.h:895
#define STATS_EXIT(id)
Definition: stats.h:148
struct _LIST_ENTRY * Flink
Definition: introlists.h:20
struct _EXCEPTION_VICTIM_ZONE::@57::@59 WriteInfo
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
Definition: intro_types.h:1087
BOOLEAN ProtectionActivated
Definition: guests.h:293
The action was not allowed because there was no reason to allow it.
Definition: intro_types.h:183
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
Definition: guests.h:299
#define PT_US
Definition: pgtable.h:85
INTRO_VIOLATION_HEADER Header
The alert header.
Definition: intro_types.h:1420
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
#define ERROR(fmt,...)
Definition: glue.h:62
#define ALERT_FLAG_ASYNC
If set, the alert was generated in an async manner.
Definition: intro_types.h:637
INTSTATUS IntWinSelfMapEnableSelfMapEntryProtection(void)
Enables the self map protection mechanism for the entire system.
Definition: winselfmap.c:508
int INTSTATUS
The status data type.
Definition: introstatus.h:24
TIMER_FRIENDLY INTSTATUS IntWinSelfMapValidateSelfMapEntries(void)
Validates the self map entries for every process in the system.
Definition: winselfmap.c:445
LIST_HEAD gWinProcesses
The list of all the processes inside the guest.
Definition: winprocesshp.c:11
QWORD VirtualAddress
The Virtual Address whose translation is being modified.
Definition: intro_types.h:1430
Event structure for illegal paging-structures modifications.
Definition: intro_types.h:1418
void * UserSelfMapHook
The user self mapping memory hook.
Definition: winprocess.h:254
Rootkit.
Definition: intro_types.h:1033
Describes a kernel-mode originator.
Definition: exceptions.h:897
EVENT_TRANSLATION_VIOLATION Translation
Definition: alerts.h:22
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:274
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
Definition: alerts.c:492
EVENT_EPT_VIOLATION Ept
Definition: alerts.h:16
INTSTATUS IntHookGpaSetHook(QWORD Gpa, DWORD Length, BYTE Type, PFUNC_EptViolationCallback Callback, void *Context, void *ParentHook, DWORD Flags, HOOK_GPA **Hook)
Places an EPT hook on the indicated memory range.
Definition: hook_gpa.c:189
#define LOG(fmt,...)
Definition: glue.h:61
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
Definition: alerts.c:327
#define INTRO_OPT_PROT_KM_SELF_MAP_ENTRY
Definition: intro_types.h:422
INTRO_VIOLATION_HEADER Header
The alert header.
Definition: intro_types.h:1106
BOOLEAN IntPolicyCoreIsOptionBeta(QWORD Flag)
Checks if one of the kernel protection options is in log-only mode.
Definition: introcore.c:2603
#define HOOK_FLG_HIGH_PRIORITY
If flag is set, the callback associated to this hook will have a higher priority than the others...
Definition: hook.h:54
TRANS_VIOLATION_TYPE ViolationType
Definition: intro_types.h:1440
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
Definition: intro_types.h:1084
#define HOOK_FLG_PAGING_STRUCTURE
If flag is set, the hook is set on paging structures.
Definition: hook.h:49
INTSTATUS IntAlertFillCodeBlocks(QWORD Rip, QWORD Cr3, BOOLEAN Execute, INTRO_CODEBLOCKS *CodeBlocks)
Fills the code blocks pattern for an alert.
Definition: alerts.c:71
QWORD Cr3
Process PDBR. Includes PCID.
Definition: winprocess.h:96
void IntAlertEptFillFromKmOriginator(const EXCEPTION_KM_ORIGINATOR *Originator, EVENT_EPT_VIOLATION *EptViolation)
Fills kernel mode originator information inside an EPT alert.
Definition: alerts.c:832
GENERIC_ALERT gAlert
Global alert buffer.
Definition: alerts.c:27
#define _Inout_
Definition: intro_sal.h:20
5-level paging
Definition: introcore.h:72
struct _EVENT_TRANSLATION_VIOLATION::@292 Originator
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
Definition: alerts.c:868
#define STATS_ENTER(id)
Definition: stats.h:141
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
Definition: intro_types.h:1085
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
Definition: glue.c:1042
QWORD New
The new, to be written, value of the page table entry.
Definition: guests.h:52
#define memzero(a, s)
Definition: introcrt.h:35
#define PT_P
Definition: pgtable.h:83
INTSTATUS IntExceptGetVictimEpt(void *Context, QWORD Gpa, QWORD Gva, INTRO_OBJECT_TYPE Type, DWORD ZoneFlags, EXCEPTION_VICTIM_ZONE *Victim)
Fills an EXCEPTION_VICTIM_ZONE with relevant information from an EPT violation.
Definition: exceptions.c:742
unsigned long long QWORD
Definition: intro_types.h:53
CHAR Name[IMAGE_BASE_NAME_LEN]
Process base name.
Definition: winprocess.h:106
QWORD Current
The currently used options.
Definition: guests.h:232
QWORD Old
The old, original, value of the written page table entry.
Definition: guests.h:51
QWORD UserCr3
Process user PDBR. Includes PCID.
Definition: winprocess.h:97
INTSTATUS IntWinSelfMapProtectSelfMapIndex(WIN_PROCESS_OBJECT *Process)
Protects the self map index of a process by placing an EPT write hook on it.
Definition: winselfmap.c:701
#define TRUE
Definition: intro_types.h:30
INTRO_WRITE_INFO WriteInfo
The original and new address to which VirtualAddress translates.
Definition: intro_types.h:1438
struct _EVENT_TRANSLATION_VIOLATION::@293 Victim
BOOLEAN GuestInitialized
True if the OS-specific portion has been initialized.
Definition: guests.h:289
#define TRACE(fmt,...)
Definition: glue.h:58
#define SELF_MAP_ENTRY(Cr3)
Computes the self map entry physical address based on a given Cr3.
Definition: winselfmap.h:21
INTSTATUS IntWinSelfMapUnprotectSelfMapIndex(WIN_PROCESS_OBJECT *Process)
Removes the EPT protection for the self map entry index of a process.
Definition: winselfmap.c:793
Sent for virtual address translation alerts. See EVENT_TRANSLATION_VIOLATION.
Definition: intro_types.h:94
#define TIMER_FRIENDLY
Definition: introdefs.h:83
#define SELF_MAP_ENTRY_IS_DETECTION(entry)
Decides if a self map entry value is malicious or not.
Definition: winselfmap.h:34
Kernel-mode exception.
Definition: exceptions.h:62
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
Definition: intro_types.h:1191
#define WARNING(fmt,...)
Definition: glue.h:60
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
Definition: intro_types.h:842
4-level paging
Definition: introcore.h:71
Sent when an EPT violation triggers an alert. See EVENT_EPT_VIOLATION.
Definition: intro_types.h:84
static INTSTATUS IntWinSelfMapHandleCr3SelfMapModification(QWORD NewValue, QWORD OldValue, WIN_PROCESS_OBJECT *Process, QWORD Cr3)
Handles self map entry modifications for a process.
Definition: winselfmap.c:41
Describes the modified zone.
Definition: exceptions.h:847
void * SelfMapHook
The self mapping memory hook.
Definition: winprocess.h:253
#define __forceinline
Definition: introtypes.h:61
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
Definition: intro_types.h:879
enum _INTRO_ACTION INTRO_ACTION
Event actions.
QWORD Rip
The RIP from where the call to the exported function came.
Definition: exceptions.h:904
QWORD OldValue[8]
The original value. Only the first Size bytes are valid.
Definition: intro_types.h:894
#define SELF_MAP_ENTRY_VA
Computes the virtual address at which the self map entry is mapped for this guest.
Definition: winselfmap.h:39
INTSTATUS IntWinSelfMapDisableSelfMapEntryProtection(void)
Disables the self map entry protection for all the processes on the system.
Definition: winselfmap.c:647
Measures the self map entry validation.
Definition: stats.h:65
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Definition: guests.h:370
#define ALERT_FLAG_SYSPROC
If set, the alert is on system process.
Definition: intro_types.h:635
Self mapping index in PDBR.
Definition: intro_types.h:251
INTRO_MODULE Module
The module that modified the translation.
Definition: intro_types.h:1424
DWORD SystemProcess
TRUE if this is a system process.
Definition: winprocess.h:134
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:48
void IntAlertFillWinProcessByCr3(QWORD ProcessCr3, INTRO_PROCESS *EventProcess)
Saves information about a Windows process inside an alert. The process is searched by its kernel CR3...
Definition: alerts.c:756
static void IntWinSelfMapSelfMapUpdate(QWORD ModifiedCr3, WIN_PROCESS_OBJECT *Process, QWORD NewValue)
Updates the self map entry value for a process.
Definition: winselfmap.c:13
INTRO_ACTION Action
The action that was taken as the result of this alert.
Definition: intro_types.h:1083
PAGING_MODE Mode
The paging mode used by the guest.
Definition: guests.h:217
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
Definition: glue.c:338
static INTSTATUS IntWinSelfMapCheckSelfMapEntry(WIN_PROCESS_OBJECT *Process, const QWORD *CurrentKernelValue, const QWORD *CurrentUserValue)
Checks the self map entry for a given process.
Definition: winselfmap.c:141
#define INT_STATUS_NOT_INITIALIZED_HINT
Definition: introstatus.h:320
INTSTATUS IntWinSelfMapGetAndCheckSelfMapEntry(WIN_PROCESS_OBJECT *Process)
Sets and validates the self map entry values for a process.
Definition: winselfmap.c:571
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
INTRO_PROCESS CurrentProcess
The current process.
Definition: intro_types.h:1086
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:57
The action was blocked because there was no exception for it.
Definition: intro_types.h:189
Holds register state.
Definition: glueiface.h:30
Event structure for EPT violations.
Definition: intro_types.h:1104
BOOLEAN Valid
True if the information in this structure is valid; False it it is not.
Definition: guests.h:53
PTEMU_BUFFER PtEmuBuffer
The page table write emulator buffer.
Definition: guests.h:169
Write-access hook.
Definition: glueiface.h:299
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
Definition: glue.c:396
INTSTATUS IntExceptKernelGetOriginator(EXCEPTION_KM_ORIGINATOR *Originator, DWORD Options)
This function is used to get the information about the kernel-mode originator.
INTSTATUS IntAlertFillExecContext(QWORD Cr3, INTRO_EXEC_CONTEXT *ExecContext)
Fills the current execution context.
Definition: alerts.c:31
#define ZONE_WRITE
Used for write violation.
Definition: exceptions.h:698
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:267
void IntExcept(EXCEPTION_VICTIM_ZONE *Victim, void *Originator, EXCEPTION_TYPE Type, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason, INTRO_EVENT_TYPE EventClass)
This function is the entry point for the exception mechanism.
Definition: exceptions.c:3317
#define FALSE
Definition: intro_types.h:34
This structure describes a running process inside the guest.
Definition: winprocess.h:81