Bitdefender Hypervisor Memory Introspection
update_exceptions.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
10 
11 #include "update_exceptions.h"
12 #include "alert_exceptions.h"
13 #include "guests.h"
14 #include "utils.h"
15 
17 #define UPDATE_VALIDATE_FILE_SIZE 0x1
18 #define UPDATE_VALIDATE_HEADER_SIZE 0x2
20 #define UPDATE_VALIDATE_ALL (UPDATE_VALIDATE_FILE_SIZE | UPDATE_VALIDATE_HEADER_SIZE)
22 
24 static EXCEPTION_SIGNATURE_ID gCurrentSignatureId = { .Field = { .Value = BIT(22) / 2, .Type = 0} };
25 
30 typedef struct _UPDATE_ITEM_SIZE
31 {
35 
36 
39  _Out_ WORD *MajorVersion,
40  _Out_ WORD *MinorVersion,
41  _Out_ DWORD *BuildNumber
42  )
56 {
57  if (NULL == MajorVersion)
58  {
60  }
61 
62  if (NULL == MinorVersion)
63  {
65  }
66 
67  if (NULL == BuildNumber)
68  {
70  }
71 
72  if (NULL == gGuest.Exceptions || !gGuest.Exceptions->Loaded)
73  {
75  }
76 
77  *MajorVersion = gGuest.Exceptions->Version.Major;
78  *MinorVersion = gGuest.Exceptions->Version.Minor;
79  *BuildNumber = gGuest.Exceptions->Version.Build;
80 
81  return INT_STATUS_SUCCESS;
82 }
83 
84 
88  )
96 {
97  gCurrentSignatureId.Field.Value++;
98  gCurrentSignatureId.Field.Type = Type;
99 
100  return gCurrentSignatureId;
101 }
102 
103 
104 static BOOLEAN
106  _In_ DWORD Size,
107  _In_ UPDATE_ITEM_SIZE *Item,
108  _In_ DWORD Flags
109  )
119 {
120  if (Flags & UPDATE_VALIDATE_HEADER_SIZE)
121  {
122  if (Size != Item->EntrySize)
123  {
124  ERROR("[ERROR] The exceptions file is corrupted. The size of the entry (%d) is different from the size "
125  "provided by the header (%d)\n", Size, Item->EntrySize);
126  return FALSE;
127  }
128  }
129 
130  if (Flags & UPDATE_VALIDATE_FILE_SIZE)
131  {
132  if (Size > Item->RemainingFileSize)
133  {
134  ERROR("[ERROR] The exceptions file is corrupted. The size of the entry (%d) exceed the remaining size "
135  "of the exceptions file (%d)\n", Size, Item->RemainingFileSize);
136  return FALSE;
137  }
138  }
139 
140  return TRUE;
141 }
142 
143 
144 static INTSTATUS
146  _In_ UPDATE_KM_EXCEPTION *UpdateException,
147  _In_ UPDATE_ITEM_SIZE *Item
148  )
165 {
166  DWORD extraSize;
167  KM_EXCEPTION *pException;
168  LIST_HEAD *head;
169 
170  if (!IntUpdateIsValidEntry(sizeof(*UpdateException), Item, UPDATE_VALIDATE_FILE_SIZE))
171  {
173  }
174 
175  extraSize = UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID);
176 
177  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + extraSize, Item, UPDATE_VALIDATE_ALL))
178  {
180  }
181 
182  if ((gGuest.OSType == introGuestWindows && (UpdateException->Flags & EXCEPTION_FLG_LINUX)) ||
183  (gGuest.OSType == introGuestLinux && !(UpdateException->Flags & EXCEPTION_FLG_LINUX)))
184  {
186  }
187 
188  if (UpdateException->Flags & EXCEPTION_FLG_IGNORE)
189  {
190  TRACE("[UPDATE] Dropped an ignored KM exception. No problem here!\n");
192  }
193 
194  // SigCount is a WORD, multiplied by sizeof(EXCEPTION_SIGNATURE_ID), so the size won't overflow.
195  pException = HpAllocWithTag(sizeof(*pException) + extraSize, IC_TAG_EXKM);
196  if (NULL == pException)
197  {
199  }
200 
201  pException->OriginatorNameHash = UpdateException->Originator.NameHash;
202  pException->VictimNameHash = UpdateException->VictimNameHash;
203  pException->Flags = UpdateException->Flags;
204  pException->Type = UpdateException->Type;
205  pException->SigCount = UpdateException->SigCount;
206 
207  // This is an old exceptions.bin, so add the write flag manually
208  if (0 == (pException->Flags & (EXCEPTION_FLG_READ | EXCEPTION_FLG_WRITE | EXCEPTION_FLG_EXECUTE)))
209  {
210  pException->Flags |= EXCEPTION_FLG_WRITE;
211  }
212 
213  // Only copy if we have signatures
214  if (UpdateException->SigCount > 0)
215  {
216  memcpy(&pException->Signatures[0], &UpdateException->SigIds[0],
217  UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID));
218  }
219 
220  //
221  // Now, let's find in which list this exception is
222  //
223  if (pException->OriginatorNameHash == kmExcNameAny)
224  {
225  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
226  {
228  }
229  else
230  {
232  }
233  }
234  else if (pException->OriginatorNameHash == kmExcNameNone)
235  {
236  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
237  {
239  }
240  else
241  {
243  }
244  }
245  else
246  {
247  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
248  {
250  }
251  else
252  {
253  DWORD id = EXCEPTION_TABLE_ID(pException->OriginatorNameHash);
254  head = &gGuest.Exceptions->KernelExceptions[id];
255  }
256  }
257 
258  InsertTailList(head, &pException->Link);
259 
260  return INT_STATUS_SUCCESS;
261 }
262 
263 
264 static INTSTATUS
266  _In_ UPDATE_KUM_EXCEPTION *UpdateException,
267  _In_ UPDATE_ITEM_SIZE *Item
268  )
285 {
286  DWORD extraSize;
287  KUM_EXCEPTION *pException;
288  LIST_HEAD *head;
289 
290  if (!IntUpdateIsValidEntry(sizeof(*UpdateException), Item, UPDATE_VALIDATE_FILE_SIZE))
291  {
293  }
294 
295  extraSize = UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID);
296 
297  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + extraSize, Item, UPDATE_VALIDATE_ALL))
298  {
300  }
301 
302  if ((gGuest.OSType == introGuestWindows && (UpdateException->Flags & EXCEPTION_FLG_LINUX)) ||
303  (gGuest.OSType == introGuestLinux && !(UpdateException->Flags & EXCEPTION_FLG_LINUX)))
304  {
306  }
307 
308  if (UpdateException->Flags & EXCEPTION_FLG_IGNORE)
309  {
310  TRACE("[UPDATE] Dropped an ignored KM exception. No problem here!\n");
312  }
313 
314  // SigCount is a WORD, multiplied by sizeof(EXCEPTION_SIGNATURE_ID), so the size won't overflow.
315  pException = HpAllocWithTag(sizeof(*pException) + extraSize, IC_TAG_EXKU);
316  if (NULL == pException)
317  {
319  }
320 
321  pException->Originator.NameHash = UpdateException->Originator.NameHash;
322  pException->Victim.NameHash = UpdateException->Victim.NameHash;
323  pException->Victim.ProcessHash = UpdateException->Victim.ProcessHash;
324  pException->Flags = UpdateException->Flags;
325  pException->Type = UpdateException->Type;
326  pException->SigCount = UpdateException->SigCount;
327 
328  // Only copy if we have signatures
329  if (UpdateException->SigCount > 0)
330  {
331  memcpy(&pException->Signatures[0], &UpdateException->SigIds[0],
332  UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID));
333  }
334 
335  //
336  // Now, let's find in which list this exception is
337  //
338  if (pException->Originator.NameHash == kumExcNameAny)
339  {
340  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
341  {
343  }
344  else
345  {
347  }
348  }
349  else if (pException->Originator.NameHash == kumExcNameNone)
350  {
351  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
352  {
354  }
355  else
356  {
358  }
359  }
360  else
361  {
362  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
363  {
365  }
366  else
367  {
368  DWORD id = EXCEPTION_TABLE_ID(pException->Originator.NameHash);
370  }
371  }
372 
373  InsertTailList(head, &pException->Link);
374 
375  return INT_STATUS_SUCCESS;
376 }
377 
378 
379 static INTSTATUS
381  _In_ UPDATE_UM_EXCEPTION *UpdateException,
382  _In_ UPDATE_ITEM_SIZE *Item
383  )
402 {
403  DWORD extraSize;
404  UM_EXCEPTION *pException;
405  LIST_HEAD *head;
406 
407  if (!IntUpdateIsValidEntry(sizeof(*UpdateException), Item, UPDATE_VALIDATE_FILE_SIZE))
408  {
410  }
411 
412  extraSize = UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID);
413 
414  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + extraSize, Item, UPDATE_VALIDATE_ALL))
415  {
417  }
418 
419  if ((gGuest.OSType == introGuestWindows && (UpdateException->Flags & EXCEPTION_FLG_LINUX)) ||
420  (gGuest.OSType == introGuestLinux && !(UpdateException->Flags & EXCEPTION_FLG_LINUX)))
421  {
423  }
424 
425  if (UpdateException->Flags & EXCEPTION_FLG_IGNORE)
426  {
427  TRACE("[UPDATE] Dropped an ignored UM exception. No problem here!\n");
429  }
430 
431  pException = HpAllocWithTag(sizeof(*pException) + extraSize, IC_TAG_EXUM);
432  if (NULL == pException)
433  {
435  }
436 
437  pException->OriginatorNameHash = UpdateException->OriginatorNameHash;
438  pException->Victim.NameHash = UpdateException->Victim.NameHash;
439  pException->Victim.ProcessHash = UpdateException->Victim.ProcessHash;
440  pException->Flags = UpdateException->Flags;
441  pException->Type = UpdateException->Type;
442  pException->SigCount = UpdateException->SigCount;
443 
444  // This is an old exceptions.bin, so add the write/exec flag manually
445  if (0 == (pException->Flags & (EXCEPTION_FLG_READ | EXCEPTION_FLG_WRITE | EXCEPTION_FLG_EXECUTE)))
446  {
447  if (pException->Type == umObjNxZone)
448  {
449  pException->Flags |= EXCEPTION_FLG_EXECUTE;
450  }
451  else
452  {
453  pException->Flags |= EXCEPTION_FLG_WRITE;
454  }
455  }
456 
457  if (UpdateException->SigCount > 0)
458  {
459  // We have calculated the size occupied by the exception, so it's safe to use memcpy for signatures
460  memcpy(pException->Signatures, UpdateException->SigIds,
461  UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID));
462  }
463 
464  // Now, let's find in which list this exception is
465  if (pException->Type == umObjProcessCreation)
466  {
467  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
468  {
470  }
471  else
472  {
474  }
475  }
476  else if (pException->OriginatorNameHash == umExcNameAny)
477  {
478  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
479  {
481  }
482  else
483  {
485  }
486  }
487  else if (pException->OriginatorNameHash == umExcNameNone)
488  {
489  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
490  {
492  }
493  else
494  {
496  }
497  }
498  else
499  {
500  if (UpdateException->Flags & EXCEPTION_FLG_FEEDBACK)
501  {
503  }
504  else
505  {
506  DWORD id = EXCEPTION_TABLE_ID(pException->OriginatorNameHash);
507  head = &gGuest.Exceptions->UserExceptions[id];
508  }
509  }
510 
511  InsertTailList(head, &pException->Link);
512 
513  return INT_STATUS_SUCCESS;
514 }
515 
516 
517 static INTSTATUS
519  _In_ UPDATE_UM_EXCEPTION_GLOB *UpdateException,
520  _In_ UPDATE_ITEM_SIZE *Item
521  )
535 {
536  DWORD extraSize = 0;
537  DWORD size = 0;
538  DWORD remainingSize = Item->RemainingFileSize;
539  char *pOriginatorName = NULL;
540  size_t originatorNameLen = 0;
541  char *pVictimName = NULL;
542  size_t victimNameLen = 0;
543  char *pProcName = NULL;
544  size_t procNameLen = 0;
545  UM_EXCEPTION_GLOB *pException;
546 
547  if (!IntUpdateIsValidEntry(sizeof(*UpdateException), Item, UPDATE_VALIDATE_FILE_SIZE))
548  {
550  }
551 
552  size = sizeof(UpdateException->Flags) + sizeof(UpdateException->Type) + sizeof(UpdateException->_Reserved)
553  + sizeof(UpdateException->SigCount);
554  remainingSize -= size;
555 
556  if (UpdateException->Flags & EXCEPTION_FLG_IGNORE)
557  {
558  TRACE("[UPDATE] Dropped an ignored UM exception. No problem here!\n");
560  }
561 
562  pOriginatorName = UpdateException->OriginatorNameGlob;
563  originatorNameLen = strlen_s(pOriginatorName, MIN((DWORD)EXCEPTION_UM_GLOB_LENGTH, remainingSize)) + 1;
564  size += (DWORD)originatorNameLen;
565  remainingSize -= (DWORD)originatorNameLen;
566 
567  if (originatorNameLen <= 1)
568  {
569  ERROR("[ERROR] The originator name length is invalid (%zu)\n", originatorNameLen);
571  }
572 
573  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + size, Item, UPDATE_VALIDATE_FILE_SIZE))
574  {
576  }
577 
578  if (originatorNameLen > EXCEPTION_UM_GLOB_LENGTH)
579  {
580  ERROR("[ERROR] Originator Name length is longer than the supported one (%d)\n", EXCEPTION_UM_GLOB_LENGTH);
582  }
583 
584  pVictimName = pOriginatorName + originatorNameLen;
585  victimNameLen = strlen_s(pVictimName, MIN((DWORD)EXCEPTION_UM_GLOB_LENGTH, remainingSize)) + 1;
586  size += (DWORD)victimNameLen;
587  remainingSize -= (DWORD)victimNameLen;
588 
589  if (victimNameLen <= 1)
590  {
591  ERROR("[ERROR] The victim name length is invalid (%zu)\n", victimNameLen);
593  }
594 
595  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + size, Item, UPDATE_VALIDATE_FILE_SIZE))
596  {
598  }
599 
600  if (victimNameLen > EXCEPTION_UM_GLOB_LENGTH)
601  {
602  ERROR("[ERROR] Victim Name length is longer than the supported one (%d)\n", EXCEPTION_UM_GLOB_LENGTH);
604  }
605 
606  pProcName = pVictimName + victimNameLen;
607  procNameLen = strlen_s(pProcName, MIN((DWORD)EXCEPTION_UM_GLOB_LENGTH, remainingSize)) + 1;
608  size += (DWORD)procNameLen;
609 
610  if (procNameLen <= 1)
611  {
612  ERROR("[ERROR] The process name length is invalid (%zu)\n", procNameLen);
614  }
615 
616 
617  if (!IntUpdateIsValidEntry(sizeof(*UpdateException) + size, Item, UPDATE_VALIDATE_FILE_SIZE))
618  {
620  }
621 
622  if (procNameLen > EXCEPTION_UM_GLOB_LENGTH)
623  {
624  ERROR("[ERROR] Victim Process length is longer than the supported one (%d)\n", EXCEPTION_UM_GLOB_LENGTH);
626  }
627 
628  extraSize = UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID);
629  size += extraSize;
630 
631  if (!IntUpdateIsValidEntry(size, Item, UPDATE_VALIDATE_ALL))
632  {
634  }
635 
636  if ((gGuest.OSType == introGuestWindows && (UpdateException->Flags & EXCEPTION_FLG_LINUX)) ||
637  (gGuest.OSType == introGuestLinux && !(UpdateException->Flags & EXCEPTION_FLG_LINUX)))
638  {
640  }
641 
642  pException = HpAllocWithTag(sizeof(*pException) + extraSize, IC_TAG_EXUM);
643  if (NULL == pException)
644  {
646  }
647 
648  pException->Flags = UpdateException->Flags;
649  pException->Type = UpdateException->Type;
650  pException->SigCount = UpdateException->SigCount;
651 
652  if (originatorNameLen > 1)
653  {
654  strlcpy(pException->OriginatorNameGlob, pOriginatorName, sizeof(pException->OriginatorNameGlob));
655  }
656 
657  if (victimNameLen > 1)
658  {
659  strlcpy(pException->Victim.NameGlob, pVictimName, sizeof(pException->Victim.NameGlob));
660  }
661 
662  if (procNameLen > 1)
663  {
664  strlcpy(pException->Victim.ProcessGlob, pProcName, sizeof(pException->Victim.ProcessGlob));
665  }
666 
667  if (UpdateException->SigCount > 0)
668  {
669  // We have calculated the size occupied by the exception, so it's safe to use memcpy for signatures
670  void *pSigStart = pProcName + procNameLen;
671  memcpy(pException->Signatures, pSigStart, UpdateException->SigCount * sizeof(EXCEPTION_SIGNATURE_ID));
672  }
673 
675 
676  return INT_STATUS_SUCCESS;
677 }
678 
679 
680 static INTSTATUS
682  _In_ UPDATE_CB_SIGNATURE *UpdateSignature,
683  _In_ UPDATE_ITEM_SIZE *Item
684  )
695 {
696  DWORD extraSize = 0;
697  DWORD size = 0;
698  UPDATE_CB_HASH *pHashList;
699  SIG_CODEBLOCKS *pSignature;
700  SIG_CODEBLOCK_HASH *pSigHash;
701 
702  // Now see how many hashes we have in each signature
703  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + sizeof(UPDATE_CB_HASH), Item, UPDATE_VALIDATE_FILE_SIZE))
704  {
706  }
707 
708  pHashList = (PUPDATE_CB_HASH)UpdateSignature->HashesList;
709  for (DWORD i = 0; i < UpdateSignature->ListsCount; i++)
710  {
711  DWORD updateHashSize;
712  DWORD hashSize;
713 
714  // Make sure that we can actually use pHashList
715  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size + sizeof(*pHashList),
717  {
719  }
720 
721  // The sizes are not the same due to alignment
722  updateHashSize = sizeof(UPDATE_CB_HASH) + pHashList->Count * sizeof(DWORD);
723  hashSize = sizeof(SIG_CODEBLOCK_HASH) + pHashList->Count * sizeof(DWORD);
724 
725  extraSize += hashSize;
726  size += updateHashSize;
727 
728  // This will check that the hashes up to this point (size) + the size of the signature structure don't spill
729  // outside the file
730  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size, Item, UPDATE_VALIDATE_FILE_SIZE))
731  {
733  }
734 
735  // advance to the next hash list
736  pHashList = (UPDATE_CB_HASH *)((BYTE *)pHashList + updateHashSize);
737  }
738 
739  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size, Item, UPDATE_VALIDATE_ALL))
740  {
742  }
743 
744  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
745  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
746  {
748  }
749 
750  pSignature = HpAllocWithTag(sizeof(*pSignature) + extraSize, IC_TAG_ESIG);
751  if (NULL == pSignature)
752  {
754  }
755 
756  pSignature->Id.Value = UpdateSignature->Id;
757  pSignature->Flags = UpdateSignature->Flags;
758  pSignature->Score = UpdateSignature->Score;
759  pSignature->ListsCount = UpdateSignature->ListsCount;
760  pSignature->AlertSignature = FALSE;
761 
762  // Now copy the hashes lists
763  pHashList = (UPDATE_CB_HASH *)UpdateSignature->HashesList;
764  pSigHash = (SIG_CODEBLOCK_HASH *)pSignature->Object;
765  for (DWORD i = 0; i < UpdateSignature->ListsCount; i++)
766  {
767  // The sizes are not the same due to alignment
768  DWORD updateHashSize = sizeof(*pHashList) + pHashList->Count * sizeof(DWORD);
769  DWORD hashSize = sizeof(*pSigHash) + pHashList->Count * sizeof(DWORD);
770 
771  pSigHash->Count = pHashList->Count;
772  for (DWORD j = 0; j < pHashList->Count; j++)
773  {
774  pSigHash->Hashes[j] = pHashList->Hashes[j];
775  }
776 
777  // advance to the next hash list
778  pHashList = (UPDATE_CB_HASH *)((BYTE *)pHashList + updateHashSize);
779  pSigHash = (SIG_CODEBLOCK_HASH *)((BYTE *)pSigHash + hashSize);
780  }
781 
783 
784  return INT_STATUS_SUCCESS;
785 }
786 
787 
788 static INTSTATUS
790  _In_ UPDATE_VALUE_SIGNATURE *UpdateSignature,
791  _In_ UPDATE_ITEM_SIZE *Item
792  )
803 {
804  DWORD size;
805  DWORD extraSize;
806  SIG_VALUE *pSignature;
807  UPDATE_VALUE_HASH *pHashList;
808  SIG_VALUE_HASH *pSigHash;
809 
810  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_FILE_SIZE))
811  {
813  }
814 
815  size = UpdateSignature->ListsCount * sizeof(UPDATE_VALUE_HASH);
816  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size, Item, UPDATE_VALIDATE_ALL))
817  {
819  }
820 
821  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
822  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
823  {
825  }
826 
827  extraSize = UpdateSignature->ListsCount * sizeof(SIG_VALUE_HASH);
828 
829  pSignature = HpAllocWithTag(sizeof(*pSignature) + extraSize, IC_TAG_ESIG);
830  if (NULL == pSignature)
831  {
833  }
834 
835  pSignature->Id.Value = UpdateSignature->Id;
836  pSignature->Flags = UpdateSignature->Flags;
837  pSignature->Score = UpdateSignature->Score;
838  pSignature->ListsCount = UpdateSignature->ListsCount;
839  pSignature->AlertSignature = FALSE;
840 
841  // Now copy the hashes lists
842  pHashList = (UPDATE_VALUE_HASH *)UpdateSignature->HashesList;
843  pSigHash = (SIG_VALUE_HASH *)pSignature->Object;
844 
845  for (DWORD i = 0; i < UpdateSignature->ListsCount; i++)
846  {
847  pSigHash[i].Offset = pHashList[i].Offset;
848  pSigHash[i].Size = pHashList[i].Size;
849  pSigHash[i].Hash = pHashList[i].Hash;
850  }
851 
853 
854  return INT_STATUS_SUCCESS;
855 }
856 
857 
858 static INTSTATUS
860  _In_ UPDATE_IDT_SIGNATURE *UpdateSignature,
861  _In_ UPDATE_ITEM_SIZE *Item
862  )
873 {
874  SIG_IDT *pSignature;
875 
876  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_ALL))
877  {
879  }
880 
881  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
882  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
883  {
885  }
886 
887  pSignature = HpAllocWithTag(sizeof(*pSignature), IC_TAG_ESIG);
888  if (NULL == pSignature)
889  {
891  }
892 
893  pSignature->Id.Value = UpdateSignature->Id;
894  pSignature->Flags = UpdateSignature->Flags;
895  pSignature->Entry = UpdateSignature->Entry;
896  pSignature->AlertSignature = FALSE;
897 
899 
900  return INT_STATUS_SUCCESS;
901 }
902 
903 
904 static INTSTATUS
906  _In_ UPDATE_VALUE_CODE_SIGNATURE *UpdateSignature,
907  _In_ UPDATE_ITEM_SIZE *Item
908  )
919 {
920  DWORD size;
921  SIG_VALUE_CODE *pSignature;
922  WORD *pUpdatePattern;
923  WORD *pExceptionPattern;
924 
925  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_FILE_SIZE))
926  {
928  }
929 
930  size = UpdateSignature->Length * sizeof(WORD);
931 
932  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size, Item, UPDATE_VALIDATE_ALL))
933  {
935  }
936 
937  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
938  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
939  {
941  }
942 
943  pSignature = HpAllocWithTag(sizeof(*pSignature) + size, IC_TAG_ESIG);
944  if (NULL == pSignature)
945  {
947  }
948 
949  pSignature->Id.Value = UpdateSignature->Id;
950  pSignature->Offset = UpdateSignature->Offset;
951  pSignature->Flags = UpdateSignature->Flags;
952  pSignature->Length = UpdateSignature->Length;
953  pSignature->AlertSignature = FALSE;
954 
955  pUpdatePattern = &UpdateSignature->Pattern[0];
956  pExceptionPattern = &pSignature->Object[0];
957 
958  // We have only one pattern for each signature
959  for (DWORD i = 0; i < UpdateSignature->Length; i++)
960  {
961  pExceptionPattern[i] = pUpdatePattern[i];
962  }
963 
965 
966  return INT_STATUS_SUCCESS;
967 }
968 
969 
970 static INTSTATUS
972  _In_ UPDATE_VERSION_OS_SIGNATURE *UpdateSignature,
973  _In_ UPDATE_ITEM_SIZE *Item
974  )
985 {
986  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_ALL))
987  {
989  }
990 
991  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
992  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
993  {
995  }
996 
997  SIG_VERSION_OS *pSignature = HpAllocWithTag(sizeof(*pSignature), IC_TAG_ESIG);
998  if (pSignature == NULL)
999  {
1001  }
1002 
1003  pSignature->Id.Value = UpdateSignature->Id;
1004  pSignature->Flags = UpdateSignature->Flags;
1005  pSignature->AlertSignature = FALSE;
1006  pSignature->Minimum.Value = UpdateSignature->Minimum.Value;
1007  pSignature->Maximum.Value = UpdateSignature->Maximum.Value;
1008 
1010 
1011  return INT_STATUS_SUCCESS;
1012 }
1013 
1014 
1015 static INTSTATUS
1017  _In_ UPDATE_VERSION_INTRO_SIGNATURE *UpdateSignature,
1018  _In_ UPDATE_ITEM_SIZE *Item
1019  )
1030 {
1031  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_ALL))
1032  {
1034  }
1035 
1036  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
1037  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
1038  {
1040  }
1041 
1042  SIG_VERSION_INTRO *pSignature = HpAllocWithTag(sizeof(*pSignature), IC_TAG_ESIG);
1043  if (pSignature == NULL)
1044  {
1046  }
1047 
1048  pSignature->Id.Value = UpdateSignature->Id;
1049  pSignature->Flags = UpdateSignature->Flags;
1050  pSignature->AlertSignature = FALSE;
1051  pSignature->Minimum.Raw = UpdateSignature->Minimum.Raw;
1052  pSignature->Maximum.Raw = UpdateSignature->Maximum.Raw;
1053 
1055 
1056  return INT_STATUS_SUCCESS;
1057 }
1058 
1059 
1060 static INTSTATUS
1062  _In_ UPDATE_EXPORT_SIGNATURE *UpdateSignature,
1063  _In_ UPDATE_ITEM_SIZE *Item
1064  )
1075 {
1076  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_FILE_SIZE))
1077  {
1079  }
1080 
1081  DWORD size = UpdateSignature->ListsCount * sizeof(UPDATE_EXPORT_HASH);
1082  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature) + size, Item, UPDATE_VALIDATE_ALL))
1083  {
1085  }
1086 
1087  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
1088  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
1089  {
1091  }
1092 
1093  DWORD extraSize = UpdateSignature->ListsCount * sizeof(SIG_EXPORT_HASH);
1094 
1095  SIG_EXPORT *pSignature = HpAllocWithTag(sizeof(*pSignature) + extraSize, IC_TAG_ESIG);
1096  if (NULL == pSignature)
1097  {
1099  }
1100 
1101  pSignature->Id.Value = UpdateSignature->Id;
1102  pSignature->Flags = UpdateSignature->Flags;
1103  pSignature->LibraryNameHash = UpdateSignature->LibraryName;
1104  pSignature->ListsCount = UpdateSignature->ListsCount;
1105  pSignature->AlertSignature = FALSE;
1106 
1107  // Now copy the hashes lists
1108  UPDATE_EXPORT_HASH *pHashList = (UPDATE_EXPORT_HASH *)UpdateSignature->HashesList;
1109  SIG_EXPORT_HASH *pSigHash = (SIG_EXPORT_HASH *)pSignature->Object;
1110 
1111  for (DWORD i = 0; i < UpdateSignature->ListsCount; i++)
1112  {
1113  pSigHash[i].Hash = pHashList[i].Hash;
1114  pSigHash[i].Delta = pHashList[i].Delta;
1115  }
1116 
1118 
1119  return INT_STATUS_SUCCESS;
1120 }
1121 
1122 
1123 static INTSTATUS
1125  _In_ UPDATE_PROCESS_CREATION_SIGNATURE *UpdateSignature,
1126  _In_ UPDATE_ITEM_SIZE *Item
1127  )
1138 {
1139  if (!IntUpdateIsValidEntry(sizeof(*UpdateSignature), Item, UPDATE_VALIDATE_ALL))
1140  {
1142  }
1143 
1144  if ((gGuest.OSType == introGuestWindows && (UpdateSignature->Flags & SIGNATURE_FLG_LINUX)) ||
1145  (gGuest.OSType == introGuestLinux && !(UpdateSignature->Flags & SIGNATURE_FLG_LINUX)))
1146  {
1148  }
1149 
1150  SIG_PROCESS_CREATION *pSignature = HpAllocWithTag(sizeof(*pSignature), IC_TAG_ESIG);
1151  if (pSignature == NULL)
1152  {
1154  }
1155 
1156  pSignature->Id.Value = UpdateSignature->Id;
1157  pSignature->Flags = UpdateSignature->Flags;
1158  pSignature->AlertSignature = FALSE;
1159  pSignature->CreateMask = UpdateSignature->CreateMask;
1160 
1162 
1163  return INT_STATUS_SUCCESS;
1164 }
1165 
1166 
1167 static void
1169  _In_ EXCEPTION_SIGNATURE_ID *Signatures,
1170  _In_ DWORD Count
1171  )
1181 {
1182  for (DWORD i = 0; i < Count; i++)
1183  {
1184  switch (Signatures[i].Field.Type)
1185  {
1186  case signatureTypeExport :
1187  {
1189  {
1190  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
1191  {
1192  pSignature->Id = IntUpdateGetUniqueSigId(pSignature->Id.Field.Type);
1193  Signatures[i] = pSignature->Id;
1194 
1195  break;
1196  }
1197  }
1198 
1199  break;
1200  }
1201 
1203  {
1205  {
1206  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
1207  {
1208  pSignature->Id = IntUpdateGetUniqueSigId(pSignature->Id.Field.Type);
1209  Signatures[i] = pSignature->Id;
1210 
1211  break;
1212  }
1213  }
1214 
1215  break;
1216  }
1217 
1218  case signatureTypeIdt:
1219  {
1221  {
1222  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
1223  {
1224  pSignature->Id = IntUpdateGetUniqueSigId(pSignature->Id.Field.Type);
1225  Signatures[i] = pSignature->Id;
1226 
1227  break;
1228  }
1229  }
1230 
1231  break;
1232  }
1233 
1234  default:
1235  {
1236  ERROR("[ERROR] Should not reach here. Type is '%d'n", Signatures[i].Field.Type);
1237  return;
1238  }
1239  }
1240  }
1241 }
1242 
1243 
1244 void
1246  void
1247  )
1251 {
1253  {
1254  IntUpdateSetIdForException(pException->Signatures, pException->SigCount);
1255  }
1256 
1258  {
1259  IntUpdateSetIdForException(pException->Signatures, pException->SigCount);
1260  }
1261 
1263  {
1264  IntUpdateSetIdForException(pException->Signatures, pException->SigCount);
1265  }
1266 }
1267 
1268 
1269 INTSTATUS
1271  _In_ void *Buffer,
1272  _In_ DWORD Length,
1273  _In_ DWORD Flags
1274  )
1289 {
1290  INTSTATUS status;
1291  BYTE *address;
1292  UPDATE_FILE_HEADER *fileHeader;
1293 
1294  UNREFERENCED_PARAMETER(Flags);
1295 
1296  if (NULL == Buffer)
1297  {
1299  }
1300 
1301  if (Length <= sizeof(UPDATE_FILE_HEADER))
1302  {
1304  }
1305 
1306  address = Buffer;
1307  fileHeader = Buffer;
1308 
1309  LOG("[UPDATE] Requested to update the intro exceptions...\n");
1310 
1311  if (fileHeader->Magic != UPDATE_MAGIC_WORD)
1312  {
1313  ERROR("[ERROR] Exception file header doesn't have the right magic word (%c%c%c%c)\n",
1314  (fileHeader->Magic & 0xff000000) >> 24, (fileHeader->Magic & 0xff0000) >> 16,
1315  (fileHeader->Magic & 0xff00) >> 8, fileHeader->Magic & 0xff);
1316 
1318  }
1319 
1320  if (fileHeader->Version.Major != UPDATE_EXCEPTIONS_MIN_VER_MAJOR)
1321  {
1322  ERROR("[ERROR] Update's file major (%d.%d) version is different form ours (%d.%d)\n",
1323  fileHeader->Version.Major, fileHeader->Version.Minor, UPDATE_EXCEPTIONS_MIN_VER_MAJOR,
1325 
1326  return INT_STATUS_NOT_SUPPORTED;
1327  }
1328 
1329  if (fileHeader->Version.Minor > UPDATE_EXCEPTIONS_MIN_VER_MINOR)
1330  {
1331  WARNING("[WARNING] Update's file minor (%d.%d) version is newer than ours (%d.%d). "
1332  "Not all features will be available!\n", fileHeader->Version.Major, fileHeader->Version.Minor,
1334  }
1335  else if (fileHeader->Version.Minor < UPDATE_EXCEPTIONS_MIN_VER_MINOR)
1336  {
1337  ERROR("[ERROR] Update's file minor (%d.%d) version is older than ours (%d.%d). "
1338  "Will not update the exceptions.\n", fileHeader->Version.Major, fileHeader->Version.Minor,
1340 
1341  return INT_STATUS_NOT_SUPPORTED;
1342  }
1343 
1344  if (fileHeader->KernelExceptionsCount == 0 &&
1345  fileHeader->UserExceptionsCount == 0 &&
1346  fileHeader->KernelUserExceptionsCount == 0 &&
1347  fileHeader->UserExceptionsGlobCount == 0)
1348  {
1349  WARNING("[WARNING] Requested update with 0 kernel exceptions and 0 user exceptions. We cannot do that...\n");
1350 
1352  }
1353 
1354  if (NULL == gGuest.Exceptions)
1355  {
1357  }
1358 
1359  status = IntExceptRemove();
1360  if (!INT_SUCCESS(status))
1361  {
1362  ERROR("[ERROR] IntExceptRemove failed: 0x%08x\n", status);
1363  return status;
1364  }
1365 
1366  // Reset the last signature ID (will be updated again when adding signatures)
1367  gCurrentSignatureId.Field.Value = BIT(22) / 2;
1368 
1369  // skip over the file header
1370  address += sizeof(UPDATE_FILE_HEADER);
1371 
1372  while (address < (PBYTE)(size_t)Buffer + Length)
1373  {
1374  if ((QWORD)(address + sizeof(UPDATE_HEADER)) > ((QWORD)Buffer + Length))
1375  {
1376  ERROR("[ERROR] The address of 'UPDATE_HEADER' structure exceeds the exception buffer "
1377  "(0x%016llx/0x%016llx)\n", (QWORD)(address + sizeof(UPDATE_HEADER)), ((QWORD)Buffer + Length));
1379  }
1380 
1381  UPDATE_HEADER *header = (UPDATE_HEADER *)address;
1382  PBYTE structure = address + sizeof(UPDATE_HEADER);
1383  UPDATE_ITEM_SIZE item = { 0 };
1384 
1385  item.EntrySize = header->Size;
1386  item.RemainingFileSize = (DWORD)((QWORD)((QWORD)(Buffer) + Length) - (QWORD)structure);
1387 
1388  address += sizeof(UPDATE_HEADER) + header->Size;
1389 
1390  switch (header->Type)
1391  {
1393  status = IntUpdateAddKernelException((UPDATE_KM_EXCEPTION *)structure, &item);
1394  break;
1395 
1397  status = IntUpdateAddUserException((UPDATE_UM_EXCEPTION *)structure, &item);
1398  break;
1399 
1401  status = IntUpdateAddUserExceptionGlob((UPDATE_UM_EXCEPTION_GLOB *)structure, &item);
1402  break;
1403 
1405  status = IntUpdateAddCbSignature((UPDATE_CB_SIGNATURE *)structure, &item);
1406  break;
1407 
1409  status = IntUpdateAddExportSignature((UPDATE_EXPORT_SIGNATURE *)structure, &item);
1410  break;
1411 
1413  status = IntUpdateAddValueSignature((UPDATE_VALUE_SIGNATURE *)structure, &item);
1414  break;
1415 
1417  status = IntUpdateAddValueCodeSignature((UPDATE_VALUE_CODE_SIGNATURE *)structure, &item);
1418  break;
1419 
1421  status = IntUpdateAddIdtSignature((UPDATE_IDT_SIGNATURE *)structure, &item);
1422  break;
1423 
1425  status = IntUpdateAddVersionOsSignature((UPDATE_VERSION_OS_SIGNATURE *)structure, &item);
1426  break;
1427 
1430  break;
1431 
1433  status = IntUpdateAddUserException((UPDATE_UM_EXCEPTION *)structure, &item);
1434  break;
1435 
1438  break;
1439 
1441  status = IntUpdateAddKernelUserException((UPDATE_KUM_EXCEPTION *)structure, &item);
1442  break;
1443 
1444  default:
1445  // For future versions: ignore unknown types
1446  WARNING("[WARNING] Unknown exception/signature type '%d'. Will ignore ...\n", header->Type);
1447  status = INT_STATUS_NOT_NEEDED_HINT;
1448  break;
1449  }
1450 
1451  if (!INT_SUCCESS(status))
1452  {
1453  ERROR("[ERROR] Failed adding exception/signature. Will abort the update. Reason=0x%08x\n", status);
1454  return status;
1455  }
1456  }
1457 
1459 
1460  gGuest.Exceptions->Version.Build = fileHeader->BuildNumber;
1461  gGuest.Exceptions->Version.Major = fileHeader->Version.Major;
1462  gGuest.Exceptions->Version.Minor = fileHeader->Version.Minor;
1463 
1465 
1466  LOG("[UPDATE] Updated exceptions to version %d.%d.%d\n",
1467  fileHeader->Version.Major, fileHeader->Version.Minor, fileHeader->BuildNumber);
1468 
1469  return INT_STATUS_SUCCESS;
1470 }
1471 
1472 
1473 static void
1475  _In_ UM_EXCEPTION *Exception
1476  )
1485 {
1486  LIST_HEAD *head;
1487 
1488  TRACE("[UPDATE] Add exception %08x -> %08x, %08x, %d, %08x\n",
1489  Exception->OriginatorNameHash, Exception->Victim.ProcessHash, Exception->Victim.NameHash,
1490  Exception->Type, Exception->Flags);
1491 
1492  if (Exception->SigCount == 1)
1493  {
1494  TRACE("[UPDATE] sig: 0x%08x\n", Exception->Signatures[0].Value);
1495  }
1496  else if (Exception->SigCount > 0)
1497  {
1498  TRACE("[UPDATE] sig: %d signatures\n", Exception->SigCount);
1499  }
1500 
1501  if (Exception->Type == umObjProcessCreation)
1502  {
1504  }
1505  else
1506  {
1508  }
1509 
1510  for_each_um_exception((*head), pEx)
1511  {
1512  // Every list is ordered, so break when we got to a hash bigger than ours
1513  if (pEx->OriginatorNameHash > Exception->OriginatorNameHash)
1514  {
1515  pEx = CONTAINING_RECORD(pEx->Link.Blink, UM_EXCEPTION, Link);
1516 
1517  InsertAfterList(&pEx->Link, &Exception->Link);
1518 
1519  return;
1520  }
1521  }
1522 
1523  // We didn't found an exception that has a hash bigger than ours. Insert at the end of the list!
1524  InsertTailList(head, &Exception->Link);
1525 }
1526 
1527 
1528 static void
1530  _In_ KM_EXCEPTION *Exception
1531  )
1539 {
1540  TRACE("[UPDATE] Add exception %08x -> %08x, %d, %08x\n",
1541  Exception->OriginatorNameHash, Exception->VictimNameHash,
1542  Exception->Type, Exception->Flags);
1543 
1544  if (Exception->SigCount == 1)
1545  {
1546  TRACE("[UPDATE] sig: %d\n", Exception->Signatures[0].Value);
1547  }
1548  else if (Exception->SigCount > 0)
1549  {
1550  TRACE("[UPDATE] sig: %d signatures\n", Exception->SigCount);
1551  }
1552 
1554  {
1555  // Every list is ordered, so break when we got to a hash bigger than ours
1556  if (pEx->OriginatorNameHash > Exception->OriginatorNameHash)
1557  {
1558  pEx = CONTAINING_RECORD(pEx->Link.Blink, KM_EXCEPTION, Link);
1559 
1560  InsertAfterList(&pEx->Link, &Exception->Link);
1561 
1562  return;
1563  }
1564  }
1565 
1566  // We didn't found an exception that has a hash bigger than ours. Insert at the end of the list!
1568 }
1569 
1570 
1571 static void
1573  _In_ KUM_EXCEPTION *Exception
1574  )
1582 {
1583  TRACE("[UPDATE] Add exception %08x -> %08x %08x, %d, %08x\n",
1584  Exception->Originator.NameHash, Exception->Victim.NameHash, Exception->Victim.ProcessHash,
1585  Exception->Type, Exception->Flags);
1586 
1587  TRACE("[UPDATE] Signatures = %d \n", Exception->SigCount);
1588 
1590  {
1591  // Every list is ordered, so break when we got to a hash bigger than ours
1592  if (pEx->Originator.NameHash > Exception->Originator.NameHash)
1593  {
1594  pEx = CONTAINING_RECORD(pEx->Link.Blink, KUM_EXCEPTION, Link);
1595 
1596  InsertAfterList(&pEx->Link, &Exception->Link);
1597 
1598  return;
1599  }
1600  }
1601 
1602  // We didn't found an exception that has a hash bigger than ours. Insert at the end of the list!
1604 }
1605 
1606 
1607 static INTSTATUS
1609  _In_ const ALERT_EXPORT_SIGNATURE *AlertSig,
1610  _Out_ SIG_EXPORT **Signature
1611  )
1622 {
1623  if (AlertSig->Header.Version != ALERT_EXPORT_SIGNATURE_VERSION)
1624  {
1625  ERROR("[ERROR] Unsupported export signature version: %d. We have %d\n",
1626  AlertSig->Header.Version, ALERT_EXPORT_SIGNATURE_VERSION);
1628  }
1629 
1630  SIG_EXPORT *pSig = HpAllocWithTag(sizeof(*pSig) + sizeof(SIG_EXPORT_HASH), IC_TAG_ESIG);
1631  if (NULL == pSig)
1632  {
1634  }
1635 
1637  pSig->LibraryNameHash = AlertSig->Library;
1638  pSig->Flags = AlertSig->Flags;
1639  pSig->ListsCount = 1;
1640  pSig->AlertSignature = TRUE;
1641 
1642  SIG_EXPORT_HASH *pSigHash = (SIG_EXPORT_HASH *)pSig->Object;
1643 
1644  pSigHash->Hash = AlertSig->Function;
1645  pSigHash->Delta = (WORD)(AlertSig->Delta + AlertSig->WriteSize);
1646 
1647  TRACE("[INFO] Add Export signature on 0x%08x (0x%08x) with delta %d\n",
1648  AlertSig->Function, AlertSig->Library, pSigHash->Delta);
1649 
1650  *Signature = pSig;
1651 
1652  return INT_STATUS_SUCCESS;
1653 }
1654 
1655 
1656 static INTSTATUS
1658  _In_ const ALERT_IDT_SIGNATURE *AlertSig,
1659  _Out_ SIG_IDT **Signature
1660  )
1671 
1672 {
1673  if (AlertSig->Header.Version != ALERT_IDT_SIGNATURE_VERSION)
1674  {
1675  ERROR("[ERROR] Unsupported idt signature version: %d. We have %d\n",
1676  AlertSig->Header.Version, ALERT_IDT_SIGNATURE_VERSION);
1678  }
1679 
1680  SIG_IDT *pSignature = HpAllocWithTag(sizeof(*pSignature), IC_TAG_ESIG);
1681  if (NULL == pSignature)
1682  {
1684  }
1685 
1687  pSignature->Entry = AlertSig->Entry;
1688  pSignature->Flags = AlertSig->Flags;
1689  pSignature->AlertSignature = TRUE;
1690 
1691  TRACE("[INFO] Add Idt Signature on %d entry.", pSignature->Entry);
1692 
1693  *Signature = pSignature;
1694 
1695  return INT_STATUS_SUCCESS;
1696 }
1697 
1698 
1699 static INTSTATUS
1701  _In_ const ALERT_CB_SIGNATURE *AlertSig,
1702  _Out_ SIG_CODEBLOCKS **Signature
1703  )
1714 
1715 {
1716  if (AlertSig->Header.Version != ALERT_CB_SIGNATURE_VERSION)
1717  {
1718  WARNING("[WARNING] Unsupported cb signature version: %d. We have %d\n",
1719  AlertSig->Header.Version, ALERT_CB_SIGNATURE_VERSION);
1721  }
1722 
1723  if (AlertSig->Count > ALERT_HASH_COUNT)
1724  {
1726  }
1727 
1728  SIG_CODEBLOCKS *pSignature;
1729  SIG_CODEBLOCK_HASH *pSigHash;
1730 
1731  DWORD totalSize = sizeof(*pSignature) + sizeof(*pSigHash) + AlertSig->Count * sizeof(DWORD);
1732 
1733  pSignature = HpAllocWithTag(totalSize, IC_TAG_ESIG);
1734  if (NULL == pSignature)
1735  {
1737  }
1738 
1740 
1741  pSignature->Score = AlertSig->Score;
1742  pSignature->ListsCount = 1;
1743  pSignature->AlertSignature = TRUE;
1744  pSignature->Flags = AlertSig->Flags;
1745 
1746  pSigHash = (SIG_CODEBLOCK_HASH *)pSignature->Object;
1747 
1748  pSigHash->Count = AlertSig->Count;
1749  for (DWORD i = 0; i < pSigHash->Count; i++)
1750  {
1751  pSigHash->Hashes[i] = AlertSig->CodeBlocks[i];
1752  }
1753 
1754  // The code blocks are already sorted (see IntAlertCreateCbSignature), but considering that the exception buffer is
1755  // an external data, we should sort them again.
1756  UtilQuickSort(pSigHash->Hashes, pSigHash->Count, sizeof(pSigHash->Hashes[0]));
1757 
1758  *Signature = pSignature;
1759 
1760  return INT_STATUS_SUCCESS;
1761 }
1762 
1763 
1764 static INTSTATUS
1766  _In_ const ALERT_PROCESS_CREATION_SIGNATURE *AlertSig,
1767  _Out_ SIG_PROCESS_CREATION **Signature
1768  )
1779 {
1780  if (AlertSig->Header.Version != ALERT_PROCESS_CREATION_SIGNATURE_VERSION)
1781  {
1782  ERROR("[ERROR] Unsupported process-creation signature version: %d. We have %d\n",
1783  AlertSig->Header.Version, ALERT_PROCESS_CREATION_SIGNATURE_VERSION);
1785  }
1786 
1787  SIG_PROCESS_CREATION *pSignature;
1788 
1789  pSignature = HpAllocWithTag(sizeof(SIG_PROCESS_CREATION), IC_TAG_ESIG);
1790  if (NULL == pSignature)
1791  {
1793  }
1794 
1796 
1797  pSignature->AlertSignature = TRUE;
1798  pSignature->Flags = AlertSig->Flags;
1799  pSignature->CreateMask = AlertSig->CreateMask;
1800 
1801  *Signature = pSignature;
1802 
1803  return INT_STATUS_SUCCESS;
1804 }
1805 
1806 
1807 __nonnull() static BOOLEAN
1809  _In_ const ALERT_CB_SIGNATURE *Signature,
1810  _In_ const EXCEPTION_SIGNATURE_ID *SigIds,
1811  _In_ DWORD SigCount
1812  )
1822 {
1823  if (!Signature->Valid)
1824  {
1825  return FALSE;
1826  }
1827 
1829  {
1830  DWORD sigSize = 0;
1831 
1832  for (DWORD i = 0; i < SigCount; i++)
1833  {
1834  if (pSig->Id.Value != SigIds[i].Value)
1835  {
1836  continue;
1837  }
1838 
1839  for (DWORD j = 0; j < pSig->ListsCount; j++)
1840  {
1841  const SIG_CODEBLOCK_HASH *pHash = (const SIG_CODEBLOCK_HASH *)(pSig->Object + sigSize);
1842  sigSize += pHash->Count * sizeof(DWORD) + sizeof(*pHash);
1843 
1844  if (pHash->Count != Signature->Count)
1845  {
1846  continue;
1847  }
1848 
1849  if (0 == memcmp(pHash->Hashes, Signature->CodeBlocks, sizeof(DWORD) * pHash->Count))
1850  {
1851  return TRUE;
1852  }
1853  }
1854  }
1855  }
1856 
1857  return FALSE;
1858 }
1859 
1860 
1861 static BOOLEAN
1863  _In_ const ALERT_IDT_SIGNATURE *Signature,
1864  _In_ const EXCEPTION_SIGNATURE_ID *SigIds,
1865  _In_ DWORD SigCount
1866  )
1876 {
1877  if (!Signature->Valid)
1878  {
1879  return FALSE;
1880  }
1881 
1883  {
1884  for (DWORD iSig = 0; iSig < SigCount; iSig++)
1885  {
1886  if (pSignature->Id.Value != SigIds[iSig].Value)
1887  {
1888  continue;
1889  }
1890 
1891  if (Signature->Entry == pSignature->Entry)
1892  {
1893  return TRUE;
1894  }
1895  }
1896  }
1897 
1898  return FALSE;
1899 }
1900 
1901 
1902 static BOOLEAN
1904  _In_ const ALERT_EXPORT_SIGNATURE *Signature,
1905  _In_ const EXCEPTION_SIGNATURE_ID *SigIds,
1906  _In_ DWORD SigCount
1907  )
1917 {
1918  if (!Signature->Valid)
1919  {
1920  return FALSE;
1921  }
1922 
1923  for (DWORD i = 0; i < SigCount; i++)
1924  {
1926  {
1927  SIG_EXPORT_HASH *pSigHash = (SIG_EXPORT_HASH *)pSig->Object;
1928 
1929  if (pSig->Id.Value != SigIds[i].Value)
1930  {
1931  continue;
1932  }
1933 
1934  if (pSig->LibraryNameHash != Signature->Library)
1935  {
1936  continue;
1937  }
1938 
1939  for (DWORD j = 0; j < pSig->ListsCount; j++)
1940  {
1941  if (pSigHash[j].Hash == Signature->Function && pSigHash[j].Delta >= Signature->Delta)
1942  {
1943  return TRUE;
1944  }
1945  }
1946  }
1947  }
1948 
1949  return FALSE;
1950 }
1951 
1952 
1953 static BOOLEAN
1955  _In_ const ALERT_KM_EXCEPTION *Exception
1956  )
1966 {
1968  {
1969  if (Exception->Originator == pEx->OriginatorNameHash &&
1970  Exception->Victim == pEx->VictimNameHash &&
1971  Exception->Flags == pEx->Flags &&
1972  Exception->Type == pEx->Type)
1973  {
1974  if (pEx->SigCount != 0)
1975  {
1976  BOOLEAN isCbDuplicate = FALSE;
1977  BOOLEAN isIdtDuplicate = FALSE;
1978 
1979  if (IntUpdateIsDuplicateCbSignature(&Exception->CodeBlocks, pEx->Signatures, pEx->SigCount))
1980  {
1981  isCbDuplicate = TRUE;
1982  }
1983 
1984  if (IntUpdateIsDuplicateIdtSignature(&Exception->Idt, pEx->Signatures, pEx->SigCount))
1985  {
1986  isIdtDuplicate = TRUE;
1987  }
1988 
1989  if ((isIdtDuplicate && isCbDuplicate) ||
1990  (isCbDuplicate && !Exception->Idt.Valid) ||
1991  (isIdtDuplicate && !Exception->CodeBlocks.Valid))
1992  {
1993  TRACE("[UPDATE] Ignoring duplicate exception with signature: %08x -> %08x, %d, %08x\n",
1994  pEx->OriginatorNameHash, pEx->VictimNameHash, pEx->Type, pEx->Flags);
1995 
1996  return TRUE;
1997  }
1998  }
1999  else if (!Exception->CodeBlocks.Valid && !Exception->Idt.Valid)
2000  {
2001  // We didn't give a signature, nor we have one in the current exception
2002  TRACE("[UPDATE] Ignoring duplicate exception: %08x -> %08x, %d, %08x\n",
2003  pEx->OriginatorNameHash, pEx->VictimNameHash, pEx->Type, pEx->Flags);
2004 
2005  return TRUE;
2006  }
2007  }
2008 
2009  // Every list is ordered, so break when we got to a hash bigger than ours
2010  if (pEx->OriginatorNameHash > Exception->Originator)
2011  {
2012  break;
2013  }
2014  }
2015 
2016  return FALSE;
2017 }
2018 
2019 static BOOLEAN
2021  _In_ const ALERT_KUM_EXCEPTION *Exception
2022  )
2032 {
2034  {
2035  if (Exception->Originator == pEx->Originator.NameHash &&
2036  Exception->Victim == pEx->Victim.NameHash &&
2037  Exception->Process == pEx->Victim.ProcessHash &&
2038  Exception->Flags == pEx->Flags &&
2039  Exception->Type == pEx->Type)
2040  {
2041  if (pEx->SigCount != 0)
2042  {
2043  if (IntUpdateIsDuplicateCbSignature(&Exception->CodeBlocks, pEx->Signatures, pEx->SigCount))
2044  {
2045  TRACE("[UPDATE] Ignoring duplicate exception with signature: %08x -> %08x - %08x, %d, %08x\n",
2046  pEx->Originator.NameHash, pEx->Victim.NameHash, pEx->Victim.ProcessHash, pEx->Type, pEx->Flags);
2047 
2048  return TRUE;
2049  }
2050  }
2051  else if (!Exception->CodeBlocks.Valid)
2052  {
2053  // We didn't give a signature, nor we have one in the current exception
2054  TRACE("[UPDATE] Ignoring duplicate exception: %08x -> %08x %08x, %d, %08x\n",
2055  pEx->Originator.NameHash, pEx->Victim.NameHash, pEx->Victim.ProcessHash, pEx->Type, pEx->Flags);
2056  return TRUE;
2057  }
2058  }
2059 
2060  // Every list is ordered, so break when we got to a hash bigger than ours
2061  if (pEx->Originator.NameHash > Exception->Originator)
2062  {
2063  break;
2064  }
2065  }
2066 
2067  return FALSE;
2068 }
2069 
2070 
2071 static BOOLEAN
2073  _In_ const ALERT_UM_EXCEPTION *Exception
2074  )
2084 {
2085  LIST_HEAD *head;
2086 
2087  if (Exception->Type == umObjProcessCreation)
2088  {
2090  }
2091  else
2092  {
2094  }
2095 
2096  for_each_um_exception((*head), pEx)
2097  {
2098  if (Exception->Originator == pEx->OriginatorNameHash &&
2099  Exception->Victim == pEx->Victim.NameHash &&
2100  Exception->Process == pEx->Victim.ProcessHash &&
2101  Exception->Type == pEx->Type)
2102  {
2103  if (pEx->SigCount != 0)
2104  {
2105  BOOLEAN isCbDuplicate = FALSE;
2106  BOOLEAN isExportDuplicate = FALSE;
2107 
2108  if (IntUpdateIsDuplicateCbSignature(&Exception->CodeBlocks, pEx->Signatures, pEx->SigCount))
2109  {
2110  isCbDuplicate = TRUE;
2111  }
2112 
2113  if (IntUpdateIsDuplicateExportSignature(&Exception->Export, pEx->Signatures, pEx->SigCount))
2114  {
2115  isExportDuplicate = TRUE;
2116  }
2117 
2118  if ((isExportDuplicate && isCbDuplicate) ||
2119  (isCbDuplicate && !Exception->Export.Valid) ||
2120  (isExportDuplicate && !Exception->CodeBlocks.Valid))
2121  {
2122  TRACE("[UPDATE] Ignoring duplicate exception with signature: %08x -> %08x, %08x, %d, %08x\n",
2123  pEx->OriginatorNameHash, pEx->Victim.ProcessHash,
2124  pEx->Victim.NameHash, pEx->Type, pEx->Flags);
2125 
2126  return TRUE;
2127  }
2128  }
2129  else if (!Exception->CodeBlocks.Valid && !Exception->Export.Valid)
2130  {
2131  // We didn't give a signature, nor we have one in the current exception
2132  TRACE("[UPDATE] Ignoring duplicate exception: %08x -> %08x, %08x, %d, %08x\n",
2133  pEx->OriginatorNameHash, pEx->Victim.ProcessHash, pEx->Victim.NameHash,
2134  pEx->Type, pEx->Flags);
2135 
2136  return TRUE;
2137  }
2138  }
2139 
2140  // Every list is ordered, so break when we got to a hash bigger than ours
2141  if (pEx->OriginatorNameHash > Exception->Originator)
2142  {
2143  break;
2144  }
2145  }
2146 
2147  return FALSE;
2148 }
2149 
2150 
2151 static INTSTATUS
2153  _In_ const ALERT_UM_EXCEPTION *Exception,
2154  _In_ QWORD Context
2155  )
2171 {
2172  INTSTATUS status;
2173  DWORD sigCount = (Exception->CodeBlocks.Valid != 0) +
2174  (Exception->Export.Valid != 0) + (Exception->ProcessCreation.Valid);
2175  SIG_EXPORT *pExpSignature = NULL;
2176  SIG_CODEBLOCKS *pCbSignature = NULL;
2177  SIG_PROCESS_CREATION *pProcessCreationSignature = NULL;
2178 
2179  if (Exception->Header.Version != ALERT_UM_EXCEPTION_VERSION)
2180  {
2181  ERROR("[ERROR] Unsupported um exception version: %d. We have %d\n",
2182  Exception->Header.Version, ALERT_UM_EXCEPTION_VERSION);
2184  }
2185 
2186  if (IntUpdateIsDuplicateUserException(Exception))
2187  {
2189  }
2190 
2191  UM_EXCEPTION *pUmException = HpAllocWithTag(sizeof(*pUmException) + sigCount * sizeof(DWORD), IC_TAG_EXUM);
2192  if (NULL == pUmException)
2193  {
2195  }
2196 
2197  pUmException->Context = Context;
2198 
2199  pUmException->OriginatorNameHash = Exception->Originator;
2200  pUmException->Victim.NameHash = Exception->Victim;
2201  pUmException->Victim.ProcessHash = Exception->Process;
2202  pUmException->Flags = Exception->Flags;
2203  pUmException->Type = Exception->Type;
2204 
2205  if (Exception->CodeBlocks.Valid)
2206  {
2207  status = IntUpdateCreateCbSignatureFromAlert(&Exception->CodeBlocks, &pCbSignature);
2208  if (!INT_SUCCESS(status))
2209  {
2210  ERROR("[ERROR] IntUpdateCreateCbSignatureFromAlert failed with status: 0x%08x\n", status);
2211  goto _exit;
2212  }
2213  else
2214  {
2215  pUmException->Signatures[pUmException->SigCount] = pCbSignature->Id;
2216  pUmException->SigCount++;
2217 
2218  InsertTailList(&gGuest.Exceptions->CbSignatures, &pCbSignature->Link);
2219  }
2220  }
2221 
2222  if (Exception->Export.Valid)
2223  {
2224  status = IntUpdateCreateExportSignatureFromAlert(&Exception->Export, &pExpSignature);
2225  if (!INT_SUCCESS(status))
2226  {
2227  WARNING("[WARNING] IntUpdateCreateExportSignatureFromAlert failed with status: 0x%08x.\n", status);
2228  goto _exit;
2229  }
2230  else
2231  {
2232  pUmException->Signatures[pUmException->SigCount] = pExpSignature->Id;
2233  pUmException->SigCount++;
2234 
2236  }
2237  }
2238 
2239  if (Exception->ProcessCreation.Valid)
2240  {
2241  status = IntUpdateCreateProcessCreationSignatureFromAlert(&Exception->ProcessCreation,
2242  &pProcessCreationSignature);
2243  if (!INT_SUCCESS(status))
2244  {
2245  ERROR("[ERROR] IntUpdateCreateProcessCreationSignatureFromAlert failed with status: 0x%08x.\n", status);
2246  goto _exit;
2247  }
2248  else
2249  {
2250  pUmException->Signatures[pUmException->SigCount] = pProcessCreationSignature->Id;
2251  pUmException->SigCount++;
2252 
2253  InsertTailList(&gGuest.Exceptions->ProcessCreationSignatures, &pProcessCreationSignature->Link);
2254  }
2255  }
2256 
2257  IntUpdateAddUserExceptionInOrder(pUmException);
2258 
2259  return INT_STATUS_SUCCESS;
2260 
2261 _exit:
2262  if (pCbSignature != NULL)
2263  {
2264  IntExceptErase(pCbSignature, IC_TAG_ESIG);
2265  }
2266 
2267  if (pProcessCreationSignature != NULL)
2268  {
2269  IntExceptErase(pProcessCreationSignature, IC_TAG_ESIG);
2270  }
2271 
2272  if (pExpSignature != NULL)
2273  {
2274  IntExceptErase(pExpSignature, IC_TAG_ESIG);
2275  }
2276 
2277  HpFreeAndNullWithTag(&pUmException, IC_TAG_EXUM);
2278 
2279  return status;
2280 }
2281 
2282 
2283 static INTSTATUS
2285  _In_ const ALERT_KM_EXCEPTION *Exception,
2286  _In_ QWORD Context
2287  )
2303 {
2304  INTSTATUS status;
2305 
2306  DWORD sigCount = (Exception->Idt.Valid != 0) + (Exception->CodeBlocks.Valid != 0);
2307  SIG_CODEBLOCKS *pCbSignature = NULL;
2308  SIG_IDT *pIdtSignature = NULL;
2309 
2310  if (Exception->Header.Version != ALERT_KM_EXCEPTION_VERSION)
2311  {
2312  ERROR("[ERROR] Unsupported km exception version: %d. We have %d\n",
2313  Exception->Header.Version, ALERT_KM_EXCEPTION_VERSION);
2315  }
2316 
2317  if (IntUpdateIsDuplicateKernelException(Exception))
2318  {
2320  }
2321 
2322  KM_EXCEPTION *pKmException = HpAllocWithTag(sizeof(*pKmException) + sigCount * sizeof(DWORD), IC_TAG_EXKM);
2323  if (NULL == pKmException)
2324  {
2326  }
2327 
2328  pKmException->Context = Context;
2329  pKmException->OriginatorNameHash = Exception->Originator;
2330  pKmException->VictimNameHash = Exception->Victim;
2331  pKmException->Flags = Exception->Flags;
2332  pKmException->Type = Exception->Type;
2333 
2334  if (Exception->Idt.Valid)
2335  {
2336  status = IntUpdateCreateIdtSignatureFromAlert(&Exception->Idt, &pIdtSignature);
2337  if (!INT_SUCCESS(status))
2338  {
2339  ERROR("[ERROR] IntUpdateCreateIdtSignatureFromAlert failed with status: 0x%08x.\n", status);
2340  goto _exit;
2341  }
2342  else
2343  {
2344  pKmException->Signatures[pKmException->SigCount] = pIdtSignature->Id;
2345  pKmException->SigCount++;
2346 
2347  InsertTailList(&gGuest.Exceptions->IdtSignatures, &pIdtSignature->Link);
2348  }
2349  }
2350 
2351  if (Exception->CodeBlocks.Valid)
2352  {
2353  status = IntUpdateCreateCbSignatureFromAlert(&Exception->CodeBlocks, &pCbSignature);
2354  if (!INT_SUCCESS(status))
2355  {
2356  ERROR("[ERROR] IntUpdateCreateCbSignatureFromAlert failed with status: 0x%08x.\n", status);
2357  goto _exit;
2358  }
2359  else
2360  {
2361  pKmException->Signatures[pKmException->SigCount] = pCbSignature->Id;
2362  pKmException->SigCount++;
2363 
2364  InsertTailList(&gGuest.Exceptions->CbSignatures, &pCbSignature->Link);
2365  }
2366  }
2367 
2368  IntUpdateAddKernelExceptionInOrder(pKmException);
2369 
2370  return INT_STATUS_SUCCESS;
2371 
2372 _exit:
2373  if (pCbSignature != NULL)
2374  {
2375  IntExceptErase(pCbSignature, IC_TAG_ESIG);
2376  }
2377 
2378  if (pIdtSignature != NULL)
2379  {
2380  IntExceptErase(pIdtSignature, IC_TAG_ESIG);
2381  }
2382 
2383  HpFreeAndNullWithTag(&pKmException, IC_TAG_EXKM);
2384 
2385  return status;
2386 }
2387 
2388 
2389 static INTSTATUS
2391  _In_ const ALERT_KUM_EXCEPTION *Exception,
2392  _In_ QWORD Context
2393  )
2409 {
2410  INTSTATUS status;
2411  DWORD sigCount = (Exception->CodeBlocks.Valid != 0);
2412  SIG_CODEBLOCKS *pCbSignature = NULL;
2413 
2414  if (Exception->Header.Version != ALERT_KM_EXCEPTION_VERSION)
2415  {
2416  ERROR("[ERROR] Unsupported km exception version: %d. We have %d\n",
2417  Exception->Header.Version, ALERT_KM_EXCEPTION_VERSION);
2419  }
2420 
2422  {
2424  }
2425 
2426  KUM_EXCEPTION *pException = HpAllocWithTag(sizeof(*pException) + sigCount * sizeof(DWORD), IC_TAG_EXKU);
2427  if (NULL == pException)
2428  {
2430  }
2431 
2432  pException->Context = Context;
2433  pException->Originator.NameHash = Exception->Originator;
2434  pException->Victim.NameHash = Exception->Victim;
2435  pException->Victim.ProcessHash = Exception->Process;
2436  pException->Flags = Exception->Flags;
2437  pException->Type = Exception->Type;
2438 
2439  if (Exception->CodeBlocks.Valid)
2440  {
2441  status = IntUpdateCreateCbSignatureFromAlert(&Exception->CodeBlocks, &pCbSignature);
2442  if (!INT_SUCCESS(status))
2443  {
2444  ERROR("[ERROR] IntUpdateCreateCbSignatureFromAlert failed with status: 0x%08x.\n", status);
2445  goto _exit;
2446  }
2447  else
2448  {
2449  pException->Signatures[pException->SigCount] = pCbSignature->Id;
2450  pException->SigCount++;
2451 
2452  InsertTailList(&gGuest.Exceptions->CbSignatures, &pCbSignature->Link);
2453  }
2454  }
2455 
2457 
2458  return INT_STATUS_SUCCESS;
2459 
2460 _exit:
2461  if (pCbSignature != NULL)
2462  {
2463  IntExceptErase(pCbSignature, IC_TAG_ESIG);
2464  }
2465 
2466  HpFreeAndNullWithTag(&pException, IC_TAG_EXKU);
2467 
2468  return status;
2469 }
2470 
2471 
2472 INTSTATUS
2474  _In_ const void *Event,
2475  _In_ INTRO_EVENT_TYPE Type,
2476  _In_ BOOLEAN Exception,
2477  _In_ QWORD Context
2478  )
2499 {
2500  INTSTATUS status;
2501  const void *pException;
2502  QWORD violationFlags;
2503  BYTE pBuff[ALERT_EXCEPTION_SIZE] = { 0 };
2504 
2505  if (NULL == Event)
2506  {
2508  }
2509 
2510  if (!IntAlertIsEventTypeViolation(Type))
2511  {
2512  ERROR("[ERROR] Failed to add exception of type %d!\n", Type);
2513  return INT_STATUS_NOT_SUPPORTED;
2514  }
2515 
2516  if (Exception)
2517  {
2518  const INTRO_ALERT_EXCEPTION_HEADER *header = Event;
2519 
2520  pException = Event;
2521  violationFlags = header->ViolationFlags;
2522 
2523  if (!header->Valid)
2524  {
2525  ERROR("[ERROR] Exception of type %d is invalid!\n", Type);
2527  }
2528  }
2529  else
2530  {
2531  const INTRO_VIOLATION_HEADER *header = Event;
2532 
2533  violationFlags = header->Flags;
2534 
2535  status = IntAlertCreateException(Event, Type, TRUE, pBuff);
2536  if (!INT_SUCCESS(status))
2537  {
2538  ERROR("[ERROR] IntAlertCreateException failed: %08x\n", status);
2539  return status;
2540  }
2541 
2542  pException = (const void *)pBuff;
2543  }
2544 
2545  if (NULL == gGuest.Exceptions)
2546  {
2547  status = IntExceptInit();
2548  if (!INT_SUCCESS(status))
2549  {
2550  ERROR("[ERROR] IntExceptInit failed: 0x%08x\n", status);
2551  return status;
2552  }
2553  }
2554 
2555  if (Type == introEventEptViolation)
2556  {
2557  if (violationFlags & ALERT_FLAG_KM_UM)
2558  {
2559  status = IntUpdateAddKmUmException(pException, Context);
2560  }
2561  else if (violationFlags & ALERT_FLAG_NOT_RING0)
2562  {
2563  status = IntUpdateAddUmException(pException, Context);
2564  }
2565  else
2566  {
2567  status = IntUpdateAddKmException(pException, Context);
2568  }
2569  }
2570  else if (introEventMsrViolation == Type ||
2571  introEventCrViolation == Type ||
2572  introEventDtrViolation == Type ||
2574  {
2575  status = IntUpdateAddKmException(pException, Context);
2576  }
2577  else if (introEventInjectionViolation == Type ||
2580  {
2581  status = IntUpdateAddUmException(pException, Context);
2582  }
2583  else
2584  {
2585  status = INT_STATUS_NOT_SUPPORTED;
2586  }
2587 
2588  if (!INT_SUCCESS(status))
2589  {
2590  ERROR("[ERROR] Failed to add exception of type %d: 0x%08x\n", Type, status);
2591  }
2592 
2593  return status;
2594 }
2595 
2596 
2597 static void
2599  _In_ EXCEPTION_SIGNATURE_ID *Signatures,
2600  _In_ DWORD Count
2601  )
2608 {
2609  for (DWORD i = 0; i < Count; i++)
2610  {
2611  switch (Signatures[i].Field.Type)
2612  {
2613  case signatureTypeExport :
2614  {
2616  {
2617  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
2618  {
2619  IntExceptErase(pSignature, IC_TAG_ESIG);
2620  break;
2621  }
2622  }
2623 
2624  break;
2625  }
2626 
2628  {
2630  {
2631  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
2632  {
2633  IntExceptErase(pSignature, IC_TAG_ESIG);
2634  break;
2635  }
2636  }
2637 
2638  break;
2639  }
2640 
2641  case signatureTypeIdt :
2642  {
2644  {
2645  if (pSignature->AlertSignature && pSignature->Id.Value == Signatures[i].Value)
2646  {
2647  IntExceptErase(pSignature, IC_TAG_ESIG);
2648  break;
2649  }
2650  }
2651 
2652  break;
2653  }
2654 
2655  default:
2656  {
2657  ERROR("[ERROR] Should not reach here. Type is %d\n", Signatures[i].Field.Type);
2658  return;
2659  }
2660  }
2661  }
2662 }
2663 
2664 
2665 INTSTATUS
2667  _In_opt_ QWORD Context
2668  )
2680 {
2681  if (NULL == gGuest.Exceptions)
2682  {
2684  }
2685 
2687  {
2688  if (pException->Context == Context)
2689  {
2690  IntUpdateRemoveSignaturesForException(pException->Signatures, pException->SigCount);
2691  IntExceptErase(pException, IC_TAG_EXUM);
2692  return INT_STATUS_SUCCESS;
2693  }
2694  }
2695 
2697  {
2698  if (pException->Context == Context)
2699  {
2700  IntUpdateRemoveSignaturesForException(pException->Signatures, pException->SigCount);
2701  IntExceptErase(pException, IC_TAG_EXUM);
2702  return INT_STATUS_SUCCESS;
2703  }
2704  }
2705 
2707  {
2708  if (pException->Context == Context)
2709  {
2710  IntUpdateRemoveSignaturesForException(pException->Signatures, pException->SigCount);
2711  IntExceptErase(pException, IC_TAG_EXUM);
2712  return INT_STATUS_SUCCESS;
2713  }
2714  }
2715 
2716  return INT_STATUS_NOT_FOUND;
2717 }
2718 
2719 
2720 INTSTATUS
2722  void
2723  )
2730 {
2731  INTSTATUS status;
2732 
2733  if (NULL == gGuest.Exceptions)
2734  {
2736  }
2737 
2738  TRACE("[INFO] Requesting to flush alert exceptions!\n");
2739 
2740  status = IntExceptAlertRemove();
2741  if (!INT_SUCCESS(status))
2742  {
2743  return status;
2744  }
2745 
2746  return INT_STATUS_SUCCESS;
2747 }
2748 
2749 
2750 BOOLEAN
2752  void
2753  )
2759 {
2761 }
QWORD ViolationFlags
A combination of Alert flags values describing the alert.
Definition: intro_types.h:1175
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
Definition: intro_types.h:1176
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:419
#define _In_opt_
Definition: intro_sal.h:16
WORD SigCount
Contains the number of signatures.
Definition: exceptions.h:267
QWORD Context
Contains the context given by the integrator.
Definition: exceptions.h:326
The header of an exception or a signature.
_Bool BOOLEAN
Definition: intro_types.h:58
#define _Out_
Definition: intro_sal.h:22
#define CONTAINING_RECORD(List, Type, Member)
Definition: introlists.h:36
static INTSTATUS IntUpdateCreateCbSignatureFromAlert(const ALERT_CB_SIGNATURE *AlertSig, SIG_CODEBLOCKS **Signature)
Creates a new code-blocks signature from an /ref ALERT_CB_SIGNATURE.
Sent for unauthorized process creation alerts. See EVENT_PROCESS_CREATION_VIOLATION.
Definition: intro_types.h:115
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:406
static void IntUpdateRemoveSignaturesForException(EXCEPTION_SIGNATURE_ID *Signatures, DWORD Count)
This function removes and frees all signature from the provided array.
#define UPDATE_TYPE_KUM_EXCEPTION
DWORD RemainingFileSize
The remaining bytes for the exceptions file.
The exception ID. The layout consists of the exception type and the unique identifier of the exceptio...
Definition: exceptions.h:238
uint8_t BYTE
Definition: intro_types.h:47
static INTSTATUS IntUpdateAddIdtSignature(UPDATE_IDT_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new IDT signature and adds it to our internal list.
Describe a export signature hash.
Definition: exceptions.h:387
#define UPDATE_TYPE_EXPORT_SIGNATURE
Describes a process-creation signature.
Definition: exceptions.h:574
LIST_HEAD KernelUserExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for kernel-user mode exceptions.
Definition: exceptions.h:108
DWORD EntrySize
The size of the current exception/signature.
LIST_HEAD ValueCodeSignatures
Linked list used for value-code signatures.
Definition: exceptions.h:133
#define _In_
Definition: intro_sal.h:21
Describe a kernel-user mode exception.
Definition: exceptions.h:275
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
static INTSTATUS IntUpdateAddVersionIntroSignature(UPDATE_VERSION_INTRO_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new introspection version signature and adds it to our internal list.
#define ALERT_IDT_SIGNATURE_VERSION
BYTE Score
The number of (minimum) hashes from a list that need to match.
Definition: exceptions.h:404
#define BIT(x)
Definition: common.h:68
QWORD Context
Contains the context given by the integrator.
Definition: exceptions.h:297
static EXCEPTION_SIGNATURE_ID gCurrentSignatureId
The current signature ID. Changes every time a new ID is generated.
WORD Offset
The displacement from the beginning of the modified zone.
Definition: exceptions.h:378
LIST_HEAD NoNameKernelExceptions
Linked list used for kernel-mode exceptions that don&#39;t have a valid originator (-).
Definition: exceptions.h:97
The name can be any string.
Definition: exceptions.h:640
#define UPDATE_TYPE_APC_UM_EXCEPTION
uint16_t WORD
Definition: intro_types.h:48
Describes a value signature.
Definition: exceptions.h:415
Describe a code-blocks hash in binary format.
WORD Delta
The number of bytes that are modified.
Definition: exceptions.h:389
Describes a kernel-mode alert-exception.
Describe a kernel-mode exception in binary format.
#define UPDATE_EXCEPTIONS_MIN_VER_MAJOR
DWORD Build
Definition: exceptions.h:141
#define UPDATE_TYPE_IDT_SIGNATURE
#define UPDATE_VALIDATE_FILE_SIZE
Validate that an object fits inside the exception buffer.
Sent when a DTR violation triggers an alert. See EVENT_DTR_VIOLATION.
Definition: intro_types.h:98
LIST_HEAD GenericUserExceptions
Linked list used for user-mode exceptions that have a generic originator(*).
Definition: exceptions.h:91
INTSTATUS IntUpdateFlushAlertExceptions(void)
This function removes all exceptions that were added from alerts.
char OriginatorNameGlob[EXCEPTION_UM_GLOB_LENGTH]
Contains the name (a string that can contain glob items) of the originator.
Definition: exceptions.h:341
INTSTATUS IntUpdateLoadExceptions(void *Buffer, DWORD Length, DWORD Flags)
Handles the exceptions coming from the integrator.
QWORD Context
Contains the context given by the integrator.
Definition: exceptions.h:265
LIST_HEAD ExportSignatures
Linked list used for export signatures.
Definition: exceptions.h:131
union _EXCEPTION_SIGNATURE_ID EXCEPTION_SIGNATURE_ID
The exception ID. The layout consists of the exception type and the unique identifier of the exceptio...
LIST_HEAD ProcessCreationAlertExceptions
Linked list used for process-creation exceptions that are added from alert.
Definition: exceptions.h:122
WORD Object[]
Contains list of opcodes.
Definition: exceptions.h:426
#define UPDATE_TYPE_UM_EXCEPTION_GLOB_MATCH
The exception sends a feedback alert.
Definition: exceptions.h:595
struct _SIG_CODEBLOCK_HASH SIG_CODEBLOCK_HASH
Describe a codeblocks signature hash.
static INTSTATUS IntUpdateAddUserExceptionGlob(UPDATE_UM_EXCEPTION_GLOB *UpdateException, UPDATE_ITEM_SIZE *Item)
Creates a new glob user-exception and adds it to our internal list.
KM_EXCEPTION_OBJECT Type
Contains the type of the exception (KM_EXCEPTION_OBJECT).
Definition: exceptions.h:263
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
Describe a export hash in binary format.
Sent when a CR violation triggers an alert. See EVENT_CR_VIOLATION.
Definition: intro_types.h:88
EXCEPTION_SIGNATURE_ID Id
An unique id (_EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:401
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
Definition: intro_types.h:1198
DWORD OriginatorNameHash
Contains the originator name-hash.
Definition: exceptions.h:257
Describe a version OS signature in binary format.
#define UPDATE_MAGIC_WORD
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:578
Describe a process-creation signature in binary format.
LIST_HEAD VersionIntroSignatures
Linked list used for introspection version signatures.
Definition: exceptions.h:136
Describe a user-mode glob exception.
Definition: exceptions.h:336
LIST_HEAD ProcessCreationSignatures
Linked list used for process-creation signatures.
Definition: exceptions.h:137
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:442
The exception is valid only for read violation.
Definition: exceptions.h:605
static BOOLEAN IntUpdateIsDuplicateUserException(const ALERT_UM_EXCEPTION *Exception)
Checks if the provided user-mode exception already exists in out list.
struct _UPDATE_VALUE_HASH UPDATE_VALUE_HASH
Describe a value hash in binary format.
LIST_HEAD IdtSignatures
Linked list used for IDT signatures.
Definition: exceptions.h:134
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:461
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:437
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
BOOLEAN IntAlertIsEventTypeViolation(INTRO_EVENT_TYPE Type)
#define IntExceptErase(Ptr, Tag)
Frees an exception or a signature buffer and removes it from the list it is currently in...
Definition: exceptions.h:1384
#define ERROR(fmt,...)
Definition: glue.h:62
BYTE Entry
The number of the IDT entry.
Definition: exceptions.h:477
LIST_HEAD UserAlertExceptions
Linked list used for user-mode exceptions that are added from alert.
Definition: exceptions.h:124
LIST_ENTRY Link
Definition: exceptions.h:435
#define for_each_um_exception(_ex_head, _var_name)
Definition: exceptions.h:1070
struct _SIG_VALUE_HASH SIG_VALUE_HASH
Describe a value signature hash.
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
static BOOLEAN IntUpdateIsValidEntry(DWORD Size, UPDATE_ITEM_SIZE *Item, DWORD Flags)
Checks if the provided Size can be read from the exceptions file without exceeding its size...
The name can be any string.
Definition: exceptions.h:687
The range-identifier used for idt signature.
Definition: exceptions.h:77
LIST_HEAD UserExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for user-mode exceptions.
Definition: exceptions.h:109
int INTSTATUS
The status data type.
Definition: introstatus.h:24
BOOLEAN Loaded
True if the exceptions are loaded.
Definition: exceptions.h:146
WORD Minor
The minor version of the exceptions binary file.
Contains the information about the sizes of an entry (exception/signature) and about the size of the ...
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
KUM_EXCEPTION_OBJECT Type
Contains the type of the exception (KM_EXCEPTION_OBJECT).
Definition: exceptions.h:295
The exception is valid only for Linux.
Definition: exceptions.h:603
INTSTATUS IntExceptAlertRemove(void)
This function removes and frees all exceptions and signatures that have been added from alert...
Definition: exceptions.c:382
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:456
INTSTATUS IntUpdateRemoveException(QWORD Context)
This function removes an exception for a given context.
DWORD NameHash
Definition: exceptions.h:316
LIST_HEAD KernelAlertExceptions
Linked list used for kernel-mode exceptions that are added from alert.
Definition: exceptions.h:126
The name is missing.
Definition: exceptions.h:644
union _SIG_VERSION_INTRO::@38 Minimum
Sent for code/data injection alerts. See EVENT_MEMCOPY_VIOLATION.
Definition: intro_types.h:96
WORD Size
The size of of the modified zone.
Definition: exceptions.h:379
#define IC_TAG_ESIG
Exception signatures structures.
Definition: memtags.h:26
#define for_each_idt_signature(_ex_head, _var_name)
Definition: exceptions.h:1082
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:278
#define ALERT_EXPORT_SIGNATURE_VERSION
static BOOLEAN IntUpdateIsDuplicateKernelException(const ALERT_KM_EXCEPTION *Exception)
Checks if the provided kernel-mode exception already exists in out list.
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:538
Describe a value hash in binary format.
The exception is valid only for write violation.
Definition: exceptions.h:606
The range-identifier used for process creation signature.
Definition: exceptions.h:74
Describe an IDT signature in binary format.
#define MIN(a, b)
Definition: introdefs.h:146
DWORD Flags
Contains any flags from EXCEPTION_FLG.
Definition: exceptions.h:261
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:460
Describe a value-code signature in binary format.
static INTSTATUS IntUpdateCreateProcessCreationSignatureFromAlert(const ALERT_PROCESS_CREATION_SIGNATURE *AlertSig, SIG_PROCESS_CREATION **Signature)
Creates a new process-creation signature from an /ref ALERT_PROCESS_CREATION_SIGNATURE.
WORD Size
The size of the exception/signature.
static INTSTATUS IntUpdateAddValueSignature(UPDATE_VALUE_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new value signature and adds it to our internal list.
#define UPDATE_TYPE_PROCESS_CREATION_SIGNATURE
#define LOG(fmt,...)
Definition: glue.h:61
The name is missing.
Definition: exceptions.h:692
Describes a value signature.
Definition: exceptions.h:452
#define ALERT_FLAG_KM_UM
If set, the alert was generated by a kernel to user mode violation.
Definition: intro_types.h:687
union _KUM_EXCEPTION::@28 Originator
Describes a user-mode alert-exception.
static INTSTATUS IntUpdateAddKernelUserException(UPDATE_KUM_EXCEPTION *UpdateException, UPDATE_ITEM_SIZE *Item)
Creates a new kernel-user mode exception and adds it to our internal list.
DWORD BuildNumber
The build number of the exceptions binary file.
struct _UM_EXCEPTION::@30 Victim
DWORD ProcessHash
Contains the originator process name-hash.
Definition: exceptions.h:283
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:579
static INTSTATUS IntUpdateAddKernelException(UPDATE_KM_EXCEPTION *UpdateException, UPDATE_ITEM_SIZE *Item)
Creates a new kernel-exception and adds it to our internal list.
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:424
static BOOLEAN IntUpdateIsDuplicateExportSignature(const ALERT_EXPORT_SIGNATURE *Signature, const EXCEPTION_SIGNATURE_ID *SigIds, DWORD SigCount)
Checks if the provided export alert-signature already exists in our list.
LIST_HEAD CbSignatures
Linked list used for codeblocks signatures.
Definition: exceptions.h:130
static INTSTATUS IntUpdateCreateIdtSignatureFromAlert(const ALERT_IDT_SIGNATURE *AlertSig, SIG_IDT **Signature)
Creates a new IDT signature from an /ref ALERT_IDT_SIGNATURE.
void IntUpdateAssignAlertSignatureIds(void)
Generates IDs for exceptions that were added from alert.
#define EXCEPTION_UM_GLOB_LENGTH
Definition: exceptions.h:36
The range-identifier used for export signature.
Definition: exceptions.h:75
DWORD Flags
Contains any flags from EXCEPTION_FLG.
Definition: exceptions.h:352
static INTSTATUS IntUpdateAddUserException(UPDATE_UM_EXCEPTION *UpdateException, UPDATE_ITEM_SIZE *Item)
Creates a new user-exception and adds it to our internal list.
BOOLEAN IntUpdateAreExceptionsLoaded(void)
Checks if the exceptions are loaded.
struct _UPDATE_ITEM_SIZE UPDATE_ITEM_SIZE
Contains the information about the sizes of an entry (exception/signature) and about the size of the ...
LIST_HEAD KernelUserAlertExceptions
Linked list used for kernel-user mode exceptions that are added from alert.
Definition: exceptions.h:128
Describe a process-creation alert-signature.
EXCEPTIONS * Exceptions
The exceptions that are currently loaded.
Definition: guests.h:392
#define INT_STATUS_NOT_INITIALIZED
Definition: introstatus.h:266
struct _UPDATE_FILE_HEADER UPDATE_FILE_HEADER
The header of the exceptions binary file.
static EXCEPTION_SIGNATURE_ID IntUpdateGetUniqueSigId(EXCEPTION_SIGNATURE_TYPE Type)
Get an unique signature ID for a given type.
#define UPDATE_VALIDATE_HEADER_SIZE
Validate the size of the exception header.
EXCEPTION_SIGNATURE_ID Signatures[]
Contains a array of signatures ID.
Definition: exceptions.h:300
DWORD LibraryNameHash
The name-hash of the modified library.
Definition: exceptions.h:440
static INTSTATUS IntUpdateAddValueCodeSignature(UPDATE_VALUE_CODE_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new value-code signature and adds it to our internal list.
DWORD Hash
The hash of the modified zone.
Definition: exceptions.h:380
uint8_t * PBYTE
Definition: intro_types.h:47
DWORD Flags
Contains any flags from _EXCEPTION_FLG.
Definition: exceptions.h:322
WORD SigCount
Contains the number of signatures.
Definition: exceptions.h:299
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:475
LIST_HEAD KernelFeedbackExceptions
Linked list used for kernel-mode exceptions that have the feedback flag.
Definition: exceptions.h:115
#define IC_TAG_EXKM
Kernel exceptions structures.
Definition: memtags.h:23
LIST_ENTRY Link
Definition: exceptions.h:310
The exception is valid only for execute violation.
Definition: exceptions.h:607
DWORD Hash
The hash of the modified zone.
DWORD VictimNameHash
Contains the victim name-hash.
Definition: exceptions.h:259
CHAR Object[]
Contains lists of (SIG_EXPORT_HASH).
Definition: exceptions.h:445
unsigned long long QWORD
Definition: intro_types.h:53
The common header used by exception information.
Definition: intro_types.h:1172
Describes an idt alert-signature.
CHAR NameGlob[EXCEPTION_UM_GLOB_LENGTH]
Contains the name (a string that can contain glob items) of the modified process. ...
Definition: exceptions.h:346
Describes a kernel-mode alert-exception.
static void IntUpdateAddKernelExceptionInOrder(KM_EXCEPTION *Exception)
Adds a kernel-mode exceptions from alert in the sorted list.
The header of the exceptions binary file.
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:474
static void IntUpdateAddUserExceptionInOrder(UM_EXCEPTION *Exception)
Adds a user-mode exceptions from alert in the sorted list.
CHAR ProcessGlob[EXCEPTION_UM_GLOB_LENGTH]
Contains the name of the process(a string that can contain glob items) in which the modification take...
Definition: exceptions.h:349
static INTSTATUS IntUpdateAddCbSignature(UPDATE_CB_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new code-blocks signature and adds it to our internal list.
Sent for suspicious module loads alerts. See EVENT_MODULE_LOAD_VIOLATION.
Definition: intro_types.h:117
#define TRUE
Definition: intro_types.h:30
LIST_ENTRY Link
Definition: exceptions.h:277
Describe a value signature hash.
Definition: exceptions.h:376
Describes a introspection version signature.
Definition: exceptions.h:531
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:493
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
#define TRACE(fmt,...)
Definition: glue.h:58
#define INT_STATUS_INVALID_DATA_STATE
Definition: introstatus.h:183
#define INT_STATUS_INVALID_INTERNAL_STATE
Definition: introstatus.h:272
struct _EXCEPTIONS::@26 Version
Loaded exceptions binary version.
BYTE Type
The type of the exception/signature.
#define for_each_kum_exception(_ex_head, _var_name)
Definition: exceptions.h:1068
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:438
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:490
static void InsertAfterList(LIST_ENTRY *Pivot, LIST_ENTRY *Item)
Definition: introlists.h:169
static INTSTATUS IntUpdateAddVersionOsSignature(UPDATE_VERSION_OS_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new operating system version signature and adds it to our internal list.
LIST_ENTRY Link
Definition: exceptions.h:472
Describe a value signature in binary format.
LIST_ENTRY Link
Definition: exceptions.h:255
static INTSTATUS IntUpdateAddKmException(const ALERT_KM_EXCEPTION *Exception, QWORD Context)
Creates a new kernel-mode exception from an alert-exception structure ALERT_UM_EXCEPTION and adds it ...
#define UPDATE_TYPE_VERSION_INTRO_SIGNATURE
Describes a export signature.
Definition: exceptions.h:433
DWORD NameHash
Contains the originator name-hash.
Definition: exceptions.h:281
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:135
INTSTATUS IntExceptInit(void)
This function allocates the exceptions data and initialize the exception lists and the signature list...
Definition: exceptions.c:441
LIST_HEAD KernelUserFeedbackExceptions
Linked list used for kernel-user mode exceptions that have the feedback flag.
Definition: exceptions.h:117
Describe a kernel-user mode exception in binary format.
size_t strlcpy(char *dst, const char *src, size_t dest_size)
Definition: introcrt.c:1093
#define UPDATE_TYPE_CB_SIGNATURE
static INTSTATUS IntUpdateCreateExportSignatureFromAlert(const ALERT_EXPORT_SIGNATURE *AlertSig, SIG_EXPORT **Signature)
Creates a new export signature from an ALERT_EXPORT_SIGNATURE.
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:420
#define WARNING(fmt,...)
Definition: glue.h:60
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
DWORD Flags
Contains any flags from EXCEPTION_FLG.
Definition: exceptions.h:293
struct _UPDATE_FILE_HEADER::@141 Version
#define IC_TAG_EXUM
User exceptions structures.
Definition: memtags.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
This exception will be ignored.
Definition: exceptions.h:609
The name can be any string.
Definition: exceptions.h:666
#define ALERT_CB_SIGNATURE_VERSION
INTSTATUS IntAlertCreateException(const void *Event, INTRO_EVENT_TYPE Type, BOOLEAN LogErrors, void *Exception)
This function will dispatch the exception creation to the appropriate function, depending on the even...
Describe a kernel-mode exception.
Definition: exceptions.h:253
#define for_each_km_exception(_ex_head, _var_name)
Definition: exceptions.h:1066
union _SIG_VERSION_INTRO::@39 Maximum
DWORD Magic
The magic value; must be UPDATE_MAGIC_WORD.
#define __forceinline
Definition: introtypes.h:61
Describe a user-mode exception.
Definition: exceptions.h:308
struct _UPDATE_HEADER UPDATE_HEADER
The header of an exception or a signature.
DWORD UserExceptionsCount
The number of the user-mode exceptions.
#define UPDATE_TYPE_VALUE_CODE_SIGNATURE
uint32_t DWORD
Definition: intro_types.h:49
#define ALERT_KM_EXCEPTION_VERSION
BYTE Count
The number of hashes from the list.
Common violation header.
Definition: intro_types.h:1189
DWORD Hashes[]
The list of hashes.
Definition: exceptions.h:369
static INTSTATUS IntUpdateAddKmUmException(const ALERT_KUM_EXCEPTION *Exception, QWORD Context)
Creates a new kernel-user mode exception from an alert-exception structure ALERT_KUM_EXCEPTION and ad...
#define strlen_s(s, n)
Definition: introcrt.h:34
The name is missing.
Definition: exceptions.h:670
LIST_ENTRY Link
Definition: exceptions.h:533
LIST_HEAD GlobUserExceptions
Linked list used for user-mode exceptions that contains glob content.
Definition: exceptions.h:105
#define UPDATE_EXCEPTIONS_MIN_VER_MINOR
DWORD Hash
The hash of the modified function name.
Definition: exceptions.h:390
BYTE Count
The number of hashes from the list.
Definition: exceptions.h:368
#define ALERT_HASH_COUNT
LIST_HEAD ProcessCreationExceptions
Linked list used for process creations exceptions.
Definition: exceptions.h:110
#define INT_STATUS_INVALID_OBJECT_TYPE
Definition: introstatus.h:145
LIST_HEAD GenericKernelExceptions
Linked list used for kernel-mode exceptions that have a generic originator (*).
Definition: exceptions.h:89
UM_EXCEPTION_OBJECT Type
Contains the type of the exception (UM_EXCEPTION_OBJECT).
Definition: exceptions.h:324
UM_EXCEPTION_OBJECT Type
Contains the type of the exception (UM_EXCEPTION_OBJECT).
Definition: exceptions.h:354
LIST_HEAD ValueSignatures
Linked list used for value signatures.
Definition: exceptions.h:132
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:457
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:491
static INTSTATUS IntUpdateAddProcessCreationSignature(UPDATE_PROCESS_CREATION_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new process-creation signature and adds it to our internal list.
#define ALERT_EXCEPTION_SIZE
Definition: intro_types.h:707
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
DWORD OriginatorNameHash
Contains the originator name-hash.
Definition: exceptions.h:312
DWORD UserExceptionsGlobCount
The number of the user-mode exceptions that contains glob items.
The signature is valid only on Linux.
Definition: exceptions.h:713
LIST_ENTRY Link
Definition: exceptions.h:417
Describe a version introspection signature in binary format.
WORD SigCount
Contains the number of signatures.
Definition: exceptions.h:358
DWORD KernelExceptionsCount
The number of the kernel-mode exceptions.
Describe an export signature in binary format.
WORD Offset
The displacement from the beginning of the modified zone.
#define for_each_cb_signature(_ex_head, _var_name)
Definition: exceptions.h:1074
struct _UM_EXCEPTION_GLOB::@31 Victim
DWORD Type
Contains a type of signature (EXCEPTION_SIGNATURE_TYPE).
Definition: exceptions.h:243
LIST_HEAD ProcessCreationFeedbackExceptions
Linked list used for process-creation exceptions that have the feedback flag.
Definition: exceptions.h:119
#define EXCEPTION_TABLE_ID(H)
Definition: exceptions.h:50
#define INT_STATUS_UNSUPPORTED_DATA_VALUE
Definition: introstatus.h:225
#define ALERT_PROCESS_CREATION_SIGNATURE_VERSION
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:581
BYTE Score
The number of (minimum) hashes from a list that need to match.
Definition: exceptions.h:459
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:536
LIST_HEAD UserFeedbackExceptions
Linked list used for user-mode exceptions that have the feedback flag.
Definition: exceptions.h:113
Describe a code-blocks signature in binary format.
DWORD ProcessHash
Contains the name-hash of the process in which the modification takes place (missing for injections)...
Definition: exceptions.h:319
WORD Length
The length of the opcode pattern.
Definition: exceptions.h:423
static BOOLEAN IntUpdateIsDuplicateIdtSignature(const ALERT_IDT_SIGNATURE *Signature, const EXCEPTION_SIGNATURE_ID *SigIds, DWORD SigCount)
Checks if the provided IDT alert-signature already exists in our list.
LIST_HEAD KernelExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for kernel-mode exceptions.
Definition: exceptions.h:107
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:405
static INTSTATUS IntUpdateAddUmException(const ALERT_UM_EXCEPTION *Exception, QWORD Context)
Creates a new user-mode exception from an alert-exception structure ALERT_UM_EXCEPTION and adds it to...
struct _EXCEPTION_SIGNATURE_ID::@27 Field
#define IC_TAG_EXKU
Kernel-User mode exceptions structures.
Definition: memtags.h:24
#define UPDATE_TYPE_VERSION_OS_SIGNATURE
#define UPDATE_TYPE_VALUE_SIGNATURE
EXCEPTION_SIGNATURE_ID Signatures[]
Contains an array of signatures ID.
Definition: exceptions.h:359
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:479
static void IntUpdateAddKernelUserExceptionInOrder(KUM_EXCEPTION *Exception)
Adds a kernel-user mode exceptions from alert in the sorted list.
INTSTATUS IntUpdateGetVersion(WORD *MajorVersion, WORD *MinorVersion, DWORD *BuildNumber)
Get the version of the loaded exceptions binary file.
QWORD Value
Contains the minimum build number of the operating system (used for windows).
Definition: exceptions.h:507
DWORD Hashes[]
The hashes list.
The range-identifier used for codeblocks signature.
Definition: exceptions.h:79
LIST_HEAD GenericKernelUserExceptions
Linked list used for kernel-user mode exceptions that have a generic originator(*).
Definition: exceptions.h:94
Describes a idt signature.
Definition: exceptions.h:470
struct _UPDATE_CB_HASH * PUPDATE_CB_HASH
DWORD Value
Contains an unique value.
Definition: exceptions.h:242
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
#define INT_STATUS_NOT_SUPPORTED
Definition: introstatus.h:287
#define ALERT_UM_EXCEPTION_VERSION
EXCEPTION_SIGNATURE_ID Signatures[]
Contains a array of signatures ID.
Definition: exceptions.h:268
Describe a user-mode-glob exception in binary format.
#define UPDATE_TYPE_UM_EXCEPTION
WORD Major
The major version of the exceptions binary file.
enum _INTRO_EVENT_TYPE INTRO_EVENT_TYPE
Event classes.
Sent for integrity violation alerts. See EVENT_INTEGRITY_VIOLATION.
Definition: intro_types.h:92
DWORD CreateMask
Contains the DPI mask.
Definition: exceptions.h:583
LIST_ENTRY Link
Definition: exceptions.h:454
static BOOLEAN IntUpdateIsDuplicateCbSignature(const ALERT_CB_SIGNATURE *Signature, const EXCEPTION_SIGNATURE_ID *SigIds, DWORD SigCount)
Checks if the provided code-blocks alert-signature already exists in our list.
DWORD Hash
The hash of the modified function name.
WORD SigCount
Contains the number of signatures.
Definition: exceptions.h:328
struct _UPDATE_EXPORT_HASH UPDATE_EXPORT_HASH
Describe a export hash in binary format.
INT16 Offset
The displacement from the beginning of the modified zone.
Definition: exceptions.h:422
#define UPDATE_VALIDATE_ALL
All exception validation options.
Sent when a MSR violation triggers an alert.See EVENT_MSR_VIOLATION.
Definition: intro_types.h:86
CHAR Object[]
Contains list of (SIG_CODEBLOCK_HASH).
Definition: exceptions.h:408
static void IntUpdateSetIdForException(EXCEPTION_SIGNATURE_ID *Signatures, DWORD Count)
Generate a new ID for each signature.
struct _UPDATE_ITEM_SIZE * PUPDATE_ITEM_SIZE
union _SIG_VERSION_OS::@33 Maximum
struct _UPDATE_CB_HASH UPDATE_CB_HASH
Describe a code-blocks hash in binary format.
static INTSTATUS IntUpdateAddExportSignature(UPDATE_EXPORT_SIGNATURE *UpdateSignature, UPDATE_ITEM_SIZE *Item)
Creates a new export signature and adds it to our internal list.
WORD Size
The size of of the modified zone.
static BOOLEAN IntUpdateIsDuplicateKernelUserException(const ALERT_KUM_EXCEPTION *Exception)
Checks if the provided kernel-user mode exception already exists in out list.
CHAR Object[]
Contains lists of (SIG_VALUE_HASH).
Definition: exceptions.h:463
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:535
EXCEPTION_SIGNATURE_ID Signatures[]
Contains an array of signatures ID.
Definition: exceptions.h:329
Describes a codeblocks signature.
Definition: exceptions.h:397
DWORD Flags
Contains any flags from _SIGNATURE_FLG.
Definition: exceptions.h:402
LIST_ENTRY Link
Definition: exceptions.h:338
DWORD KernelUserExceptionsCount
The number of the kernel-user mode exceptions.
Describe a user-mode exception in binary format.
#define UPDATE_TYPE_KM_EXCEPTION
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
BOOLEAN AlertSignature
True if the signature is added from alert.
Definition: exceptions.h:443
union _SIG_VERSION_OS::@32 Minimum
LIST_HEAD NoNameUserExceptions
Linked list used for user-mode exceptions that don&#39;t have a valid originator (-). ...
Definition: exceptions.h:99
Describe a codeblocks signature hash.
Definition: exceptions.h:366
void UtilQuickSort(void *Array, const DWORD NumberOfElements, const BYTE ElementSize)
Definition: utils.c:267
Describes a operating system version signature.
Definition: exceptions.h:486
WORD Delta
The number of bytes that are modified.
The object that has a NX zone is executed.
Definition: exceptions.h:212
INTSTATUS IntUpdateAddExceptionFromAlert(const void *Event, INTRO_EVENT_TYPE Type, BOOLEAN Exception, QWORD Context)
Handles all types of supported exceptions that can be added from alerts.
#define INT_STATUS_INVALID_DATA_SIZE
Definition: introstatus.h:142
INTSTATUS IntExceptRemove(void)
This function removes and frees all exceptions and signatures that have been added from exception bin...
Definition: exceptions.c:257
LIST_ENTRY Link
Definition: exceptions.h:488
#define for_each_export_signature(_ex_head, _var_name)
Definition: exceptions.h:1076
struct _SIG_EXPORT_HASH SIG_EXPORT_HASH
Describe a export signature hash.
#define FALSE
Definition: intro_types.h:34
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281
enum _EXCEPTION_SIGNATURE_TYPE EXCEPTION_SIGNATURE_TYPE
The identifier that describes a range of signatures.
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68
LIST_HEAD VersionOsSignatures
Linked list used for operating system version signatures.
Definition: exceptions.h:135
struct _KUM_EXCEPTION::@29 Victim