Bitdefender Hypervisor Memory Introspection
winsud.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "winsud.h"
6 #include "hook.h"
7 #include "exceptions.h"
8 #include "alerts.h"
9 #include "winthread.h"
10 #include "winprocesshp.h"
11 #include "crc32.h"
12 #include "utils.h"
13 
14 
34 
35 
37 static HOOK_GVA *gSudExecHook = NULL;
38 
40 static BYTE *gSudBuffer = NULL;
41 
44 
47 {
48  char *FieldName;
70 
73 {
74  {
75  .FieldName = "ImageNumber",
76  .FieldOffset = 0x2c,
77  .FieldSize = 0x4,
78  .ShouldCheck = TRUE
79  },
80 
81  {
82  .FieldName = "CryptoExponent",
83  .FieldOffset = 0x23c,
84  .FieldSize = 0x4,
85  .ShouldCheck = TRUE
86  },
87 
88  {
89  .FieldName = "LargePageMinimum",
90  .FieldOffset = 0x244,
91  .FieldSize = 0x4,
92  .ShouldCheck = TRUE
93  },
94 
95  {
96  .FieldName = "AppCompatFlag",
97  .FieldOffset = 0x24c,
98  .FieldSize = 0x4,
99  .ShouldCheck = TRUE
100  },
101 
102  {
103  .FieldName = "NtBuildNumber",
104  .FieldOffset = 0x260,
105  .FieldSize = 0x4,
106  .ShouldCheck = TRUE
107  },
108 
109  {
110  .FieldName = "NtProductType",
111  .FieldOffset = 0x264,
112  .FieldSize = 0x4,
113  .ShouldCheck = TRUE
114  },
115 
116  {
117  .FieldName = "ProductTypeIsValid",
118  .FieldOffset = 0x268,
119  .FieldSize = 0x1,
120  .ShouldCheck = TRUE
121  },
122 
123  {
124  .FieldName = "NativeProcessorArchitecture",
125  .FieldOffset = 0x26a,
126  .FieldSize = 0x2,
127  .ShouldCheck = TRUE
128  },
129 
130  {
131  .FieldName = "NtMajorVersion",
132  .FieldOffset = 0x26c,
133  .FieldSize = 0x4,
134  .ShouldCheck = TRUE
135  },
136 
137  {
138  .FieldName = "NtMinorVersion",
139  .FieldOffset = 0x270,
140  .FieldSize = 0x4,
141  .ShouldCheck = TRUE
142  },
143 
144  {
145  .FieldName = "ProcessorFeatures1",
146  .FieldOffset = 0x274,
147  .FieldSize = 0x8,
148  .ShouldCheck = TRUE
149  },
150 
151  {
152  .FieldName = "ProcessorFeatures2",
153  .FieldOffset = 0x27c,
154  .FieldSize = 0x8,
155  .ShouldCheck = TRUE
156  },
157 
158  {
159  .FieldName = "ProcessorFeatures3",
160  .FieldOffset = 0x284,
161  .FieldSize = 0x8,
162  .ShouldCheck = TRUE
163  },
164 
165  {
166  .FieldName = "ProcessorFeatures4",
167  .FieldOffset = 0x28c,
168  .FieldSize = 0x8,
169  .ShouldCheck = TRUE
170  },
171 
172  {
173  .FieldName = "ProcessorFeatures5",
174  .FieldOffset = 0x294,
175  .FieldSize = 0x8,
176  .ShouldCheck = TRUE
177  },
178 
179  {
180  .FieldName = "ProcessorFeatures6",
181  .FieldOffset = 0x29c,
182  .FieldSize = 0x8,
183  .ShouldCheck = TRUE
184  },
185 
186  {
187  .FieldName = "ProcessorFeatures7",
188  .FieldOffset = 0x2a4,
189  .FieldSize = 0x8,
190  .ShouldCheck = TRUE
191  },
192 
193  {
194  .FieldName = "ProcessorFeatures8",
195  .FieldOffset = 0x2ac,
196  .FieldSize = 0x8,
197  .ShouldCheck = TRUE
198  },
199 
200  {
201  .FieldName = "KdDebuggerEnabled",
202  .FieldOffset = 0x2d4,
203  .FieldSize = 0x1,
204  .ShouldCheck = TRUE
205  },
206 
207  {
208  .FieldName = "MitigationPolicies",
209  .FieldOffset = 0x2d5,
210  .FieldSize = 0x1,
211  .ShouldCheck = TRUE
212  },
213 
214  {
215  .FieldName = "SafeBootMode",
216  .FieldOffset = 0x2ec,
217  .FieldSize = 0x1,
218  .ShouldCheck = TRUE
219  },
220 
221  {
222  .FieldName = "VirtualizationFlags",
223  .FieldOffset = 0x2ed,
224  .FieldSize = 0x1,
225  .ShouldCheck = TRUE
226  },
227 
228  {
229  .FieldName = "TestRetInstruction",
230  .FieldOffset = 0x2f8,
231  .FieldSize = 0x8,
232  .ShouldCheck = TRUE
233  },
234 
235  {
236  .FieldName = "SystemCall",
237  .FieldOffset = 0x308,
238  .FieldSize = 0x8,
239  .ShouldCheck = TRUE
240  },
241 
242  // Pads may be used to write a structure for example.
243  {
244  .FieldName = "SystemCallPad1",
245  .FieldOffset = 0x310,
246  .FieldSize = 0x8,
247  .ShouldCheck = TRUE
248  },
249 
250  {
251  .FieldName = "SystemCallPad2",
252  .FieldOffset = 0x318,
253  .FieldSize = 0x8,
254  .ShouldCheck = TRUE
255  },
256 
257  {
258  .FieldName = "EnclaveFeatureMask1",
259  .FieldOffset = 0x36c,
260  .FieldSize = 0x8,
261  .ShouldCheck = TRUE
262  },
263 
264  {
265  .FieldName = "EnclaveFeatureMask2",
266  .FieldOffset = 0x374,
267  .FieldSize = 0x8,
268  .ShouldCheck = TRUE
269  },
270 
271  {
272  .FieldName = "ImageFileExecutionOptions",
273  .FieldOffset = 0x3a0,
274  .FieldSize = 0x4,
275  .ShouldCheck = TRUE
276  },
277 
278  {
279  .FieldName = "ActiveProcessorCount",
280  .FieldOffset = 0x3c0,
281  .FieldSize = 0x4,
282  .ShouldCheck = TRUE
283  },
284 
285  // Note: this field will be adjusted IntWinSudProtectIntegrity so that it will begin exactly
286  // from the end of the KUSER_SHARED_DATA structure.
287  {
288  .FieldName = "AfterSudRegion",
289  .FieldOffset = 0x800,
290  .FieldSize = 0x800,
291  .ShouldBeZero = TRUE,
292  .ShouldCheck = TRUE
293  }
294 };
295 
296 
297 static void
299  _In_ void *Originator,
300  _In_ EXCEPTION_VICTIM_ZONE *Victim,
301  _In_ BOOLEAN IsKernel,
302  _In_ INTRO_ACTION Action,
304  )
316 {
317  EVENT_EPT_VIOLATION *pEpt = &gAlert.Ept;
318  INTSTATUS status;
319 
320  memzero(pEpt, sizeof(*pEpt));
321 
322  pEpt->Header.Action = Action;
323  pEpt->Header.Reason = Reason;
325 
326  IntAlertEptFillFromVictimZone(Victim, pEpt);
327 
329 
331 
333 
334  pEpt->ExecInfo.Rsp = gVcpu->Regs.Rsp;
335  pEpt->ExecInfo.Length = gVcpu->Instruction.Length;
336 
337  if (IsKernel)
338  {
339  EXCEPTION_KM_ORIGINATOR *originator = Originator;
340 
341  IntAlertEptFillFromKmOriginator(originator, pEpt);
342  }
343  else
344  {
345  EXCEPTION_UM_ORIGINATOR *originator = Originator;
346 
348  pEpt->ReturnRip = originator->Return.Rip;
349  }
350 
353 
355 
356  status = IntNotifyIntroEvent(introEventEptViolation, pEpt, sizeof(*pEpt));
357  if (!INT_SUCCESS(status))
358  {
359  WARNING("[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
360  }
361 }
362 
363 
364 static INTSTATUS
366  _In_ QWORD Address,
367  _Inout_ INTRO_ACTION *Action
368  )
381 {
382  EXCEPTION_VICTIM_ZONE victim = { 0 };
383  EXCEPTION_KM_ORIGINATOR originator = { 0 };
384  BOOLEAN exitAfterInformation = FALSE;
386  INTSTATUS status;
387 
389 
390  status = IntExceptKernelGetOriginator(&originator, 0);
391  if (status == INT_STATUS_EXCEPTION_BLOCK)
392  {
393  reason = introReasonNoException;
394  exitAfterInformation = TRUE;
395  }
396  else if (!INT_SUCCESS(status))
397  {
398  ERROR("[ERROR] IntExceptKernelGetOriginator failed: %08x\n", status);
399  reason = introReasonInternalError;
400  exitAfterInformation = TRUE;
401  }
402 
403  status = IntExceptGetVictimEpt(NULL,
404  Address,
405  gVcpu->Regs.Rip,
407  ZONE_EXECUTE,
408  &victim);
409  if (!INT_SUCCESS(status))
410  {
411  ERROR("[ERROR] IntExceptGetVictimEpt failed: %08x\n", status);
412  reason = introReasonInternalError;
413  exitAfterInformation = TRUE;
414  }
415 
416  if (exitAfterInformation)
417  {
418  IntExceptKernelLogInformation(&victim, &originator, *Action, reason);
419  }
420  else
421  {
422  IntExcept(&victim, &originator, exceptionTypeKm, Action, &reason, introEventEptViolation);
423  }
424 
426 
428  {
429  LOG("[SUD-EXEC] An execution on shared user data occured in kernel-mode!\n");
430 
431  IntDumpCodeAndRegs(gVcpu->Regs.Rip, Address, &gVcpu->Regs);
432 
433  IntWinSudSendSudExecAlert(&originator, &victim, TRUE, *Action, reason);
434  }
435 
437 
438  return status;
439 }
440 
441 
442 static INTSTATUS
444  _In_ QWORD Address,
445  _Inout_ INTRO_ACTION *Action
446  )
460 {
461  EXCEPTION_UM_ORIGINATOR originator = { 0 };
462  EXCEPTION_VICTIM_ZONE victim = { 0 };
463  WIN_PROCESS_OBJECT *pProc;
465  BOOLEAN exitAfterInformation = FALSE;
466  INTSTATUS status;
467 
469  if (NULL == pProc)
470  {
471  ERROR("[ERROR] No process found with cr3: 0x%016llx, but ring is 3! Will inject #UD!",
472  gVcpu->Regs.Cr3);
473  return INT_STATUS_NOT_FOUND;
474  }
475 
477 
478  status = IntExceptUserGetExecOriginator(pProc, &originator);
479  if (!INT_SUCCESS(status))
480  {
481  ERROR("[ERROR] Failed getting originator: 0x%08x\n", status);
482  exitAfterInformation = TRUE;
483  }
484 
485  status = IntExceptGetVictimEpt(pProc,
486  Address,
487  gVcpu->Regs.Rip,
489  ZONE_EXECUTE,
490  &victim);
491  if (!INT_SUCCESS(status))
492  {
493  ERROR("[ERROR] Failed getting modified zone: 0x%08x\n", status);
494  exitAfterInformation = TRUE;
495  }
496  if (exitAfterInformation)
497  {
498  IntExceptUserLogInformation(&victim, &originator, *Action, reason);
499  }
500  else
501  {
502  IntExcept(&victim, &originator, exceptionTypeUm, Action, &reason, introEventEptViolation);
503  }
504 
506 
508  {
509  LOG("[SUD-EXEC] An execution on shared user data occured in user-mode!\n");
510 
511  IntDumpCodeAndRegs(gVcpu->Regs.Rip, Address, &gVcpu->Regs);
512 
513  IntWinSudSendSudExecAlert(&originator, &victim, FALSE, *Action, reason);
514  }
515 
517 
518  return status;
519 }
520 
521 
522 static INTSTATUS
524  _In_ void *Context,
525  _In_ void *Hook,
526  _In_ QWORD Address,
527  _Out_ INTRO_ACTION *Action
528  )
548 {
549  INTSTATUS status;
550  DWORD ring;
551  INFO_UD_PENDING *pending = NULL;
552  QWORD currentThread = 0;
553 
554  UNREFERENCED_PARAMETER(Context);
556 
557  *Action = introGuestNotAllowed;
558 
559  status = IntGetCurrentRing(gVcpu->Index, &ring);
560  if (!INT_SUCCESS(status))
561  {
562  ERROR("[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
563  IntBugCheck();
564  }
565 
567 
568  if (ring == IG_CS_RING_0)
569  {
570  status = IntWinSudHandleKernelSudExec(Address, Action);
571  if (!INT_SUCCESS(status))
572  {
573  ERROR("[ERROR] IntWinSudHandleKernelSudExec failed: 0x%08x\n", status);
574  }
575  }
576  else
577  {
578  status = IntWinThrGetCurrentThread(gVcpu->Index, &currentThread);
579  if (!INT_SUCCESS(status))
580  {
581  ERROR("[ERROR] IntWinThrGetCurrentThread failed: 0x%08x\n", status);
582  return status;
583  }
584 
585  pending = IntUDGetEntry(gVcpu->Regs.Cr3, gVcpu->Regs.Rip, currentThread);
586  if (NULL != pending)
587  {
588  goto cleanup_and_take_action;
589  }
590 
591  status = IntWinSudHandleUserSudExec(Address, Action);
592  if (!INT_SUCCESS(status))
593  {
594  ERROR("[ERROR] IntWinSudHandleKernelSudExec failed: 0x%08x\n", status);
595  }
596  }
597 
598 cleanup_and_take_action:
599  if (*Action == introGuestNotAllowed)
600  {
601  if (ring == IG_CS_RING_0)
602  {
603  BYTE ret = 0xc3;
604 
605  status = IntPhysicalMemWrite(Address, sizeof(ret), &ret);
606  if (!INT_SUCCESS(status))
607  {
608  ERROR("[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
609  }
610 
611  // Force action to introGuestAllowed, in order to force emulation, otherwise we'll end up in an infinite
612  // cycle, depending on the hypervisor by forcing it to introGuestRetry. For example, this happens on xen.
613  *Action = introGuestAllowed;
614  }
615  else
616  {
617  // We are already waiting for the current #UD to get injected.
618  if (NULL != pending && gVcpu->CurrentUD == pending)
619  {
620  goto _skip_inject;
621  }
622 
624  if (!INT_SUCCESS(status))
625  {
626  ERROR("[ERROR] IntInjectExceptionInGuest failed: 0x%08x\n", status);
627  }
628  else
629  {
630  if (NULL == pending)
631  {
633  gVcpu->Regs.Rip,
634  currentThread,
635  &pending);
636  if (!INT_SUCCESS(status))
637  {
638  ERROR("[ERROR] IntUDAddToPendingList failed: 0x%08x\n", status);
639  return status;
640  }
641  }
642 
643  gVcpu->CurrentUD = pending;
644  }
645 
646  _skip_inject:
647  *Action = introGuestRetry;
648  }
649  }
650 
652 
653  // Even if the action has been set as allowed by the exceptions mechanism, we'll not remove the hook,
654  // as the hook needs to remain established.
655 
656  return INT_STATUS_SUCCESS;
657 }
658 
659 
660 INTSTATUS
662  void
663  )
670 {
671  INTSTATUS status;
672 
673  if (NULL != gSudExecHook)
674  {
676  }
677 
680  PAGE_SIZE,
683  NULL,
684  NULL,
685  0,
686  &gSudExecHook);
687  if (!INT_SUCCESS(status))
688  {
689  ERROR("[ERROR] IntHookGvaSetHook failed: 0x%08x\n", status);
690  }
691 
692  return status;
693 }
694 
695 
696 INTSTATUS
698  void
699  )
706 {
707  INTSTATUS status;
708 
709  if (NULL == gSudExecHook)
710  {
712  }
713 
714  status = IntHookGvaRemoveHook(&gSudExecHook, 0);
715  if (!INT_SUCCESS(status))
716  {
717  ERROR("[ERROR] IntHookGvaRemoveHook failed: 0x%08x\n", status);
718  }
719 
720  return status;
721 }
722 
723 
724 static BOOLEAN
727  _Inout_ QWORD *CurrentValue
728  )
739 {
740  QWORD currentValue;
741 
742  switch (Field->FieldSize)
743  {
744  case 1:
745  currentValue = gSudBuffer[Field->FieldOffset];
746  break;
747  case 2:
748  currentValue = *(WORD *)&gSudBuffer[Field->FieldOffset];
749  break;
750  case 4:
751  currentValue = *(DWORD *)&gSudBuffer[Field->FieldOffset];
752  break;
753  case 8:
754  currentValue = *(QWORD *)&gSudBuffer[Field->FieldOffset];
755  break;
756  default:
757  return FALSE;
758  }
759 
760  *CurrentValue = currentValue;
761 
762  return TRUE;
763 }
764 
765 
766 static void
768  _In_ EXCEPTION_VICTIM_ZONE *Victim,
770  _In_ INTRO_ACTION Action,
772  )
782 {
783  INTSTATUS status;
784  EVENT_INTEGRITY_VIOLATION *pIntViol;
785 
786  pIntViol = &gAlert.Integrity;
787  memzero(pIntViol, sizeof(*pIntViol));
788 
790 
791  // Force de-activation of ALERT_FLAG_NOT_RING0. We're always in ring0.
792  pIntViol->Header.Flags &= ~ALERT_FLAG_NOT_RING0;
793 
794  pIntViol->Header.Flags |= ALERT_FLAG_ASYNC;
795 
796  pIntViol->Header.Action = Action;
797  pIntViol->Header.Reason = Reason;
798  pIntViol->Header.MitreID = idRootkit;
799 
800  pIntViol->Victim.Type = Victim->Object.Type;
801 
802  IntAlertFillWinProcess(Victim->Object.Process, &pIntViol->Header.CurrentProcess);
803 
804  utf8toutf16(pIntViol->Victim.Name, Field->FieldName, sizeof(pIntViol->Victim.Name) / 2);
805 
807 
808  // We can't know from what CPU the write was, but we know where the integrity check failed
809  pIntViol->Header.CpuContext.Valid = FALSE;
810 
812  pIntViol->VirtualAddress = pIntViol->BaseAddress + Field->FieldOffset;
813  pIntViol->Size = Field->FieldSize;
814 
815  IntAlertFillVersionInfo(&pIntViol->Header);
816 
817  IntAlertFillWriteInfo(Victim, &pIntViol->WriteInfo);
818 
819  status = IntNotifyIntroEvent(introEventIntegrityViolation, pIntViol, sizeof(*pIntViol));
820  if (!INT_SUCCESS(status))
821  {
822  WARNING("[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
823  }
824 }
825 
826 
827 static INTSTATUS
830  _In_ QWORD NewValue
831  )
847 {
848  EXCEPTION_KM_ORIGINATOR originator = { 0 };
849  EXCEPTION_VICTIM_ZONE victim = { 0 };
850  INTRO_ACTION action;
851  INTRO_ACTION_REASON reason;
852  INTSTATUS status;
853 
855 
856  originator.Original.NameHash = INITIAL_CRC_VALUE;
857  originator.Return.NameHash = INITIAL_CRC_VALUE;
858 
860  victim.Object.NameHash = Crc32String(Field->FieldName, INITIAL_CRC_VALUE);
862 
863  // Used just for logging.
864  victim.Object.Name = Field->FieldName;
866  victim.Integrity.Offset = Field->FieldOffset;
867 
868  victim.ZoneFlags |= ZONE_WRITE | ZONE_INTEGRITY;
870 
871  victim.WriteInfo.OldValue[0] = Field->OldValue;
872 
873  if (Field->ShouldBeZero)
874  {
875  // Copy as much as we can (max 64 bytes) from the protected field which should be 0.
876  // It should be enough for analysis on the alert. Also we need to copy from the first
877  // byte that is non-zero, otherwise we'll most probably just copy some unmodified zero-es
878  // from the protected region.
879  DWORD startOffset = Field->FieldOffset;
880  DWORD copySize;
881 
882  for (DWORD i = Field->FieldOffset; i < (DWORD)Field->FieldOffset + Field->FieldSize; i++)
883  {
884  if (gSudBuffer[i] != 0)
885  {
886  startOffset = i;
887  break;
888  }
889  }
890 
891  copySize = MIN(sizeof(victim.WriteInfo.NewValue), (QWORD)Field->FieldOffset + Field->FieldSize - startOffset);
892 
893  memcpy(victim.WriteInfo.NewValue, &gSudBuffer[startOffset], copySize);
894  }
895  else
896  {
897  victim.WriteInfo.NewValue[0] = NewValue;
898  }
899 
900  victim.WriteInfo.AccessSize = Field->FieldSize;
901 
902  IntExcept(&victim, &originator, exceptionTypeKm, &action, &reason, introEventIntegrityViolation);
903 
905 
907  {
908  IntWinSudSendSudIntegrityAlert(&victim, Field, action, reason);
909  }
910 
912 
913  if (action == introGuestAllowed)
914  {
915  if (Field->ShouldBeZero)
916  {
917  // Not really much we can do, so disable this field so we won't send an alert every second, and re-enable
918  // it if at a further check we find the field filled again with zeroes...
919  Field->ReenableOnZero = TRUE;
920  }
921  else
922  {
923  // Overwrite the old value, so that we don't raise an alert every second for an allowed modification.
924  Field->OldValue = NewValue;
925  }
926  }
927  else if (action == introGuestNotAllowed)
928  {
929  if (Field->ShouldBeZero)
930  {
931  // The best option would be to just map the page and overwrite the zeroes.
932  BYTE *pPage = NULL;
933 
934  IntPauseVcpus();
935 
937  if (!INT_SUCCESS(status))
938  {
939  ERROR("[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
940 
941  IntResumeVcpus();
942 
943  return status;
944  }
945 
946  for (DWORD i = Field->FieldOffset; i < (DWORD)Field->FieldOffset + Field->FieldSize; i++)
947  {
948  pPage[i] = 0;
949  }
950 
951  IntResumeVcpus();
952 
953  IntVirtMemUnmap(&pPage);
954  }
955  else
956  {
957  IntPauseVcpus();
958 
959  status = IntKernVirtMemWrite(WIN_SHARED_USER_DATA_PTR + Field->FieldOffset,
960  Field->FieldSize,
961  &Field->OldValue);
962 
963  IntResumeVcpus();
964 
965  if (!INT_SUCCESS(status))
966  {
967  ERROR("[ERROR] IntKernVirtMemWrite failed for gva 0x%016llx: 0x%08x\n",
968  (QWORD)WIN_SHARED_USER_DATA_PTR + Field->FieldOffset, status);
969  return status;
970  }
971  }
972 
973  }
974 
975  return INT_STATUS_SUCCESS;
976 }
977 
978 
981  void
982  )
998 {
999  INTSTATUS status;
1000 
1002  {
1004  }
1005 
1007  {
1008  // Raise an error, this should not be true, gSudIntegrityInitialized should be always set to FALSE
1009  // if the flag is not given.
1011  }
1012 
1014 
1016  if (!INT_SUCCESS(status))
1017  {
1018  ERROR("[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1019  goto _cleanup_and_exit;
1020  }
1021 
1022  for (DWORD i = 0; i < ARRAYSIZE(gProtFields); i++)
1023  {
1024  BOOLEAN modified = FALSE;
1025  QWORD newValue = 0;
1026 
1027  if (!gProtFields[i].ShouldCheck)
1028  {
1029  continue;
1030  }
1031 
1032  if (gProtFields[i].ShouldBeZero)
1033  {
1034  BOOLEAN reenable = gProtFields[i].ReenableOnZero;
1035 
1036  if (!UtilIsBufferZero(&gSudBuffer[gProtFields[i].FieldOffset], gProtFields[i].FieldSize))
1037  {
1038  if (!gProtFields[i].ReenableOnZero)
1039  {
1040  modified = TRUE;
1041  }
1042  else
1043  {
1044  reenable = FALSE;
1045  }
1046  }
1047 
1048  // If we didn't find any non-zero values and the ReenableOnZero flag was previously set, then
1049  // unset it and from now on we will handle as detections the writes over this zone.
1050  if (reenable)
1051  {
1052  gProtFields[i].ReenableOnZero = FALSE;
1053  }
1054  }
1055  else
1056  {
1057  if (!IntWinSudFetchFieldCurrentValue(&gProtFields[i], &newValue))
1058  {
1059  continue;
1060  }
1061 
1062  if (gProtFields[i].OldValue != newValue)
1063  {
1064  WARNING("[WARNING] At field %s offset 0x%x, value should be 0x%llx but is 0x%llx\n",
1065  gProtFields[i].FieldName, gProtFields[i].FieldOffset, gProtFields[i].OldValue, newValue);
1066 
1067  modified = TRUE;
1068  }
1069  }
1070 
1071  if (modified)
1072  {
1073  status = IntWinSudHandleFieldModification(&gProtFields[i], newValue);
1074  if (!INT_SUCCESS(status))
1075  {
1076  WARNING("[WARNING] IntWinSudHandleFieldModification failed: 0x%08x\n", status);
1077  }
1078 
1079  gProtFields[i].ModifiedCount++;
1080  }
1081 
1082  // We keep a threshold as a safe guard, as some fields may get often modified and we should not send an alert per second
1083  // for every modification indefinitely.
1084  if (gProtFields[i].ModifiedCount > 1000)
1085  {
1086  WARNING("[WARNING] Field %s written more than the threshold, will disable!\n", gProtFields[i].FieldName);
1087  gProtFields[i].ShouldCheck = FALSE;
1088  }
1089  }
1090 
1091 _cleanup_and_exit:
1093 
1094  return status;
1095 }
1096 
1097 
1098 INTSTATUS
1100  void
1101  )
1113 {
1114  INTSTATUS status;
1115 
1117  {
1119  }
1120 
1122  if (NULL == gSudBuffer)
1123  {
1125  }
1126 
1128  if (!INT_SUCCESS(status))
1129  {
1130  ERROR("[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1131  goto _cleanup_and_exit;
1132  }
1133 
1134  for (DWORD i = 0; i < ARRAYSIZE(gProtFields); i++)
1135  {
1136  // As _KUSER_SHARED_DATA is variable in size due to increase in size for _XSTATE_CONFIGURATION, we need
1137  // to adjust the offset and the size of this specific field.
1138  if (memcmp(gProtFields[i].FieldName, "AfterSudRegion", sizeof("AfterSudRegion")) == 0)
1139  {
1140  gProtFields[i].FieldOffset = (WORD)WIN_KM_FIELD(Ungrouped, SharedUserDataSize);
1141  gProtFields[i].FieldSize = PAGE_SIZE - gProtFields[i].FieldOffset;
1142  }
1143 
1144  // No need to extract anything, we already know that this needs to be 0.
1145  if (gProtFields[i].ShouldBeZero)
1146  {
1147  continue;
1148  }
1149 
1150  if (gProtFields[i].FieldOffset + gProtFields[i].FieldSize > PAGE_SIZE || gProtFields[i].FieldSize == 0)
1151  {
1152  ERROR("[ERROR] Field %s is invalid, will disable!\n", gProtFields[i].FieldName);
1153  gProtFields[i].ShouldCheck = FALSE;
1154  continue;
1155  }
1156 
1157  if (!IntWinSudFetchFieldCurrentValue(&gProtFields[i], &gProtFields[i].OldValue))
1158  {
1159  ERROR("[ERROR] Field %s with size %d is invalid, will disable!\n",
1160  gProtFields[i].FieldName, gProtFields[i].FieldSize);
1161  gProtFields[i].ShouldCheck = FALSE;
1162  }
1163  }
1164 
1166 
1167 _cleanup_and_exit:
1168  if (!INT_SUCCESS(status))
1169  {
1171  }
1172 
1173  return status;
1174 }
1175 
1176 
1177 INTSTATUS
1179  void
1180  )
1193 {
1195  {
1197  }
1198 
1200 
1202 
1203  return INT_STATUS_SUCCESS;
1204 }
Measures kernel mode exceptions checks.
Definition: stats.h:51
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:1263
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
Definition: introcore.c:2234
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
Definition: alerts.c:366
An internal error occurred (no memory, pages not present, etc.).
Definition: intro_types.h:195
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
uint8_t BYTE
Definition: intro_types.h:47
struct _SHARED_USER_DATA_PROT_FIELD * PSHARED_USER_DATA_PROT_FIELD
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
Definition: introcore.c:699
QWORD ZoneFlags
The flags of the modified zone.
Definition: exceptions.h:898
struct _SHARED_USER_DATA_PROT_FIELD SHARED_USER_DATA_PROT_FIELD
Describes a field from KUSER_SHARED_DATA which is protected through integrity.
IG_ARCH_REGS Regs
The current state of the guest registers.
Definition: guests.h:95
DWORD Index
The VCPU number.
Definition: guests.h:172
#define _In_
Definition: intro_sal.h:21
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
Definition: intro_types.h:1199
QWORD SystemCr3
The Cr3 used to map the kernel.
Definition: guests.h:211
#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
Measures user mode exceptions checks.
Definition: stats.h:50
struct _EXCEPTION_UM_ORIGINATOR::@75 Return
uint16_t WORD
Definition: intro_types.h:48
QWORD ReturnRip
The RIP at which the code that triggered the alert returns.
Definition: intro_types.h:1282
#define STATS_EXIT(id)
Definition: stats.h:160
void IntAlertFillWinProcess(const WIN_PROCESS_OBJECT *Process, INTRO_PROCESS *EventProcess)
Saves information about a windows process inside an alert.
Definition: alerts.c:689
Event structure for integrity violations on monitored structures.
Definition: intro_types.h:1572
User-mode exception.
Definition: exceptions.h:60
#define VECTOR_UD
Definition: processor.h:109
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
INTSTATUS IntWinThrGetCurrentThread(DWORD CpuNumber, QWORD *EthreadAddress)
Get the ETHREAD structure address of the thread currently running on the given CPU.
Definition: winthread.c:26
char * FieldName
The name of the KUSER_SHARED_DATA field.
Definition: winsud.c:48
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
Definition: intro_types.h:1198
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
Definition: introcore.c:2355
INTRO_OBJECT_TYPE Type
Definition: intro_types.h:1589
#define ARRAYSIZE(A)
Definition: introdefs.h:101
struct _EVENT_INTEGRITY_VIOLATION::@304 Victim
SHARED_USER_DATA_PROT_FIELD gProtFields[]
Global array containing the descriptors used for protecting fields inside SharedUserData.
Definition: winsud.c:72
INFO_UD_PENDING * IntUDGetEntry(const QWORD Cr3, const QWORD Rip, const QWORD Thread)
Get a UD entry for the provided Cr3, Rip and Thread ID.
Definition: udlist.c:150
Measures the checks done on SharedUserData.
Definition: stats.h:104
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
#define ERROR(fmt,...)
Definition: glue.h:62
Describes a user-mode originator.
Definition: exceptions.h:994
#define ALERT_FLAG_ASYNC
If set, the alert was generated in an async manner.
Definition: intro_types.h:675
struct _EVENT_EPT_VIOLATION::@283 Originator
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
int INTSTATUS
The status data type.
Definition: introstatus.h:24
INTSTATUS IntWinSudUnprotectIntegrity(void)
Uninitializes the SharedUserData integrity protection.
Definition: winsud.c:1178
static BOOLEAN IntWinSudFetchFieldCurrentValue(SHARED_USER_DATA_PROT_FIELD *Field, QWORD *CurrentValue)
Fetches the value of the given described field from the global SharedUserData buffer.
Definition: winsud.c:725
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
DWORD Offset
The offset of the modification.
Definition: exceptions.h:803
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
Definition: introcore.c:2264
#define INTRO_OPT_PROT_KM_SUD_INTEGRITY
Enable integrity checks over various SharedUserData fields, as well as the zero-filled zone after the...
Definition: intro_types.h:528
Rootkit.
Definition: intro_types.h:1144
Integrity protection of SharedUserData region.
Definition: intro_types.h:273
Describes a kernel-mode originator.
Definition: exceptions.h:943
INTSTATUS IntPhysicalMemWrite(QWORD PhysicalAddress, DWORD Length, void *Buffer)
Writes data to a guest physical memory range, but only for a single page.
Definition: introcore.c:744
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
Definition: introcore.c:2320
INTSTATUS IntDumpCodeAndRegs(QWORD Gva, QWORD Gpa, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes) as well as the values of the reg...
Definition: dumper.c:692
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
Definition: alerts.c:492
Measures the execution handling on SharedUserData page.
Definition: stats.h:106
INSTRUX Instruction
The current instruction, pointed by the guest RIP.
Definition: guests.h:88
TIMER_FRIENDLY INTSTATUS IntWinSudCheckIntegrity(void)
This function checks the integrity of protected fields from SharedUserData, described in gProtFields...
Definition: winsud.c:980
#define MIN(a, b)
Definition: introdefs.h:146
struct _EXCEPTION_KM_ORIGINATOR::@63 Return
EVENT_EPT_VIOLATION Ept
Definition: alerts.h:16
#define WIN_SHARED_USER_DATA_PTR
The address where the SharedUserData is mapped in the Windows kernel.
Definition: winsud.h:11
static INTSTATUS IntWinSudHandleSudExec(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Ept callback which handles executions inside SharedUserData.
Definition: winsud.c:523
#define LOG(fmt,...)
Definition: glue.h:61
BOOLEAN UtilIsBufferZero(void *Buffer, size_t BufferSize)
Definition: utils.c:413
INTSTATUS IntHookGvaSetHook(QWORD Cr3, QWORD Gva, DWORD Length, BYTE Type, void *Callback, void *Context, void *ParentHook, DWORD Flags, HOOK_GVA **GvaHook)
Set a read, write, execute or swap hook on a guest virtual address.
Definition: hook_gva.c:345
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
Definition: alerts.c:327
INTRO_VIOLATION_HEADER Header
The alert header.
Definition: intro_types.h:1217
#define ZONE_INTEGRITY
Used for integrity zone.
Definition: exceptions.h:738
static HOOK_GVA * gSudExecHook
The hook object protecting against executions on SharedUserData.
Definition: winsud.c:37
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
Definition: intro_types.h:1195
EXCEPTION_VICTIM_OBJECT Object
The modified object.
Definition: exceptions.h:895
INTSTATUS IntAlertFillCodeBlocks(QWORD Rip, QWORD Cr3, BOOLEAN Execute, INTRO_CODEBLOCKS *CodeBlocks)
Fills the code blocks pattern for an alert.
Definition: alerts.c:71
Exposes the functions used to provide Windows Threads related support.
void * Library
The library that&#39;s modifying the memory (if that&#39;s the case).
Definition: exceptions.h:1013
BOOLEAN ShouldBeZero
Set to TRUE if the contents of the field should be always zero.
Definition: winsud.c:60
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
QWORD BaseAddress
Depending on INTRO_OBJECT_TYPE we have: CR3 for processes / ModuleBase for km drivers and um dll...
Definition: exceptions.h:863
#define _Inout_
Definition: intro_sal.h:20
void IntAlertFillWriteInfo(const EXCEPTION_VICTIM_ZONE *Victim, INTRO_WRITE_INFO *WriteInfo)
Fills the write information for an alert.
Definition: alerts.c:521
static BOOLEAN gSudIntegrityInitialized
Is set to true when integrity is initialized on SharedUserData signaling that checks can be performed...
Definition: winsud.c:43
#define INITIAL_CRC_VALUE
Definition: introdefs.h:221
#define INT_STATUS_EXCEPTION_BLOCK
Definition: introstatus.h:421
DWORD Size
The size of the modified memory area.
Definition: intro_types.h:1618
#define INT_STATUS_ALREADY_INITIALIZED
Definition: introstatus.h:263
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
Definition: alerts.c:868
#define INT_STATUS_NOT_INITIALIZED
Definition: introstatus.h:266
The modified object is inside an integrity hook.
Definition: exceptions.h:749
#define STATS_ENTER(id)
Definition: stats.h:153
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
Definition: intro_types.h:1196
__noreturn void IntBugCheck(void)
Definition: glue.c:917
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
Definition: glue.c:1042
#define IC_TAG_SUD_BUFFER
Used for keeping the SharedUserData buffer internally.
Definition: memtags.h:137
#define ZONE_EXECUTE
Used for execute violation.
Definition: exceptions.h:736
#define memzero(a, s)
Definition: introcrt.h:35
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
QWORD Current
The currently used options.
Definition: guests.h:236
void IntExceptUserLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_UM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a user-mode violation, dumps the code-blocks and the injection buffer...
static BYTE * gSudBuffer
Buffer for fast accessing the current contents of SharedUserData.
Definition: winsud.c:40
QWORD VirtualAddress
The guest virtual address which was modified.
Definition: intro_types.h:1616
#define TRUE
Definition: intro_types.h:30
INTRO_VIOLATION_HEADER Header
The alert header.
Definition: intro_types.h:1574
INTSTATUS IntWinSudProtectSudExec(void)
Protects SharedUserData against executions by establishing an EPT hook on it.
Definition: winsud.c:661
QWORD StartVirtualAddress
The start address of the integrity zone.
Definition: exceptions.h:802
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
INFO_UD_PENDING * CurrentUD
The currently pending #UD injection on this CPU.
Definition: guests.h:123
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3(QWORD Cr3)
Finds a process by its kernel CR3.
Definition: winprocesshp.c:195
#define INT_STATUS_INVALID_INTERNAL_STATE
Definition: introstatus.h:272
DWORD NameHash
The hash of the modified object.
Definition: exceptions.h:854
#define TIMER_FRIENDLY
Definition: introdefs.h:83
INTSTATUS IntWinSudUnprotectSudExec(void)
Removes the execution EPT hook on SharedUserData.
Definition: winsud.c:697
void IntExceptKernelLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a kernel-mode violation and dumps the code-blocks.
Kernel-mode exception.
Definition: exceptions.h:61
INTRO_OBJECT_TYPE Type
The type of the modified object.
Definition: exceptions.h:852
ZONE_TYPE ZoneType
The type of the modified zone.
Definition: exceptions.h:897
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
Definition: intro_types.h:1309
#define WARNING(fmt,...)
Definition: glue.h:60
WORD FieldSize
The size of the field. Note that this size can be 1, 2, 4, 8 for fields which are initialized...
Definition: winsud.c:54
INTSTATUS IntHookGvaRemoveHook(HOOK_GVA **Hook, DWORD Flags)
Remove a GVA hook.
Definition: hook_gva.c:507
Sent when an EPT violation triggers an alert. See EVENT_EPT_VIOLATION.
Definition: intro_types.h:84
#define ALERT_FLAG_NOT_RING0
If set, the alert was triggered in ring 1, 2 or 3.
Definition: intro_types.h:674
QWORD OldValue
The saved value for fields that don&#39;t have ShouldBeZero set to TRUE.
Definition: winsud.c:68
#define PAGE_SIZE
Definition: common.h:70
Describes the modified zone.
Definition: exceptions.h:893
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
struct _EXCEPTION_VICTIM_ZONE::@58::@60 WriteInfo
Executions inside the SharedUserData region.
Definition: intro_types.h:267
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
Definition: winguest.h:740
WCHAR Name[ALERT_PATH_MAX_LEN]
NULL-terminated string with a human readable description of the modified object.
Definition: intro_types.h:1591
uint32_t DWORD
Definition: intro_types.h:49
BOOLEAN ReenableOnZero
Set to TRUE after an allowed modification has been made on a field with ShouldBeZero set to TRUE...
Definition: winsud.c:67
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
Definition: intro_types.h:965
#define NO_ERRORCODE
Definition: processor.h:123
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTRO_WRITE_INFO WriteInfo
Definition: intro_types.h:1607
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
Definition: introcore.c:2134
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Definition: guests.h:374
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
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 INTSTATUS IntWinSudHandleUserSudExec(QWORD Address, INTRO_ACTION *Action)
Handles an user-mode execution inside SharedUserData.
Definition: winsud.c:443
EVENT_INTEGRITY_VIOLATION Integrity
Definition: alerts.h:23
QWORD Rsp
The value of the guest RSP register at the moment of execution.
Definition: intro_types.h:1001
struct _EXCEPTION_KM_ORIGINATOR::@64 Original
INTRO_ACTION Action
The action that was taken as the result of this alert.
Definition: intro_types.h:1194
char * Name
The modified process name.
Definition: exceptions.h:858
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
Definition: introcore.c:674
static void IntWinSudSendSudExecAlert(void *Originator, EXCEPTION_VICTIM_ZONE *Victim, BOOLEAN IsKernel, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Constructs and sends an EVENT_EPT_VIOLATION alert which occurred due to an execution in SharedUserDat...
Definition: winsud.c:298
INTSTATUS IntUDAddToPendingList(const QWORD Cr3, const QWORD Rip, const QWORD Thread, INFO_UD_PENDING **CurrentPendingUD)
Add a new UD to the list of pending injections.
Definition: udlist.c:30
static void IntWinSudSendSudIntegrityAlert(EXCEPTION_VICTIM_ZONE *Victim, SHARED_USER_DATA_PROT_FIELD *Field, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Completes and sends an alert for a detected SharedUserData modification on a monitored field...
Definition: winsud.c:767
QWORD BaseAddress
The guest virtual address at which the monitored integrity region starts.
Definition: intro_types.h:1614
INTSTATUS IntExceptUserGetExecOriginator(void *Process, EXCEPTION_UM_ORIGINATOR *Originator)
This function is used to get the originator for heap execution.
#define INT_STATUS_NOT_INITIALIZED_HINT
Definition: introstatus.h:320
INTRO_PROCESS CurrentProcess
The current process.
Definition: intro_types.h:1197
#define INTRO_OPT_PROT_KM_SUD_EXEC
Enable protection against executions on SharedUserData.
Definition: intro_types.h:515
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:59
The action was blocked because there was no exception for it.
Definition: intro_types.h:189
void IntAlertFillWinUmModule(const WIN_PROCESS_MODULE *Module, INTRO_MODULE *EventModule)
Fills information about a user mode module inside an alert.
Definition: alerts.c:653
Sent for integrity violation alerts. See EVENT_INTEGRITY_VIOLATION.
Definition: intro_types.h:92
DWORD Crc32String(const char *String, DWORD InitialCrc)
Computes the CRC for a NULL-terminated utf-8 string.
Definition: crc32.c:200
EXCEPTION_VICTIM_INTEGRITY Integrity
Valid if the modified zone is Integrity.
Definition: exceptions.h:908
INTRO_EXEC_INFO ExecInfo
Execution information. Valid only if Violation is IG_EPT_HOOK_EXECUTE.
Definition: intro_types.h:1260
Event structure for EPT violations.
Definition: intro_types.h:1215
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
Definition: introcpu.c:959
Execute-access hook.
Definition: glueiface.h:300
static INTSTATUS IntWinSudHandleFieldModification(SHARED_USER_DATA_PROT_FIELD *Field, QWORD NewValue)
This function is called when a modification has been detected on a given field in order to take a dec...
Definition: winsud.c:828
DWORD Length
The length of the instruction.
Definition: intro_types.h:1004
Exploitation of Remote Services.
Definition: intro_types.h:1159
DWORD ModifiedCount
The number of modifications on the field from the time the protection has been initialized up until n...
Definition: winsud.c:59
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:734
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:271
INTSTATUS IntWinSudProtectIntegrity(void)
Initializes the SharedUserData integrity protection.
Definition: winsud.c:1099
WCHAR * utf8toutf16(WCHAR *Destination, const char *Source, DWORD DestinationMaxLength)
Definition: introcrt.c:507
QWORD Rip
Where the write/exec came.
Definition: exceptions.h:1019
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:3357
Describes a field from KUSER_SHARED_DATA which is protected through integrity.
Definition: winsud.c:46
static INTSTATUS IntWinSudHandleKernelSudExec(QWORD Address, INTRO_ACTION *Action)
Handles a kernel mode execution inside SharedUserData.
Definition: winsud.c:365
INTRO_MODULE ReturnModule
The module to which the current code returns to.
Definition: intro_types.h:1222
DWORD NameHash
The namehash of the originator return driver.
Definition: exceptions.h:947
#define FALSE
Definition: intro_types.h:34
This structure describes a running process inside the guest.
Definition: winprocess.h:83
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281