Bitdefender Hypervisor Memory Introspection
update_guests.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_guests.h"
12 #include "winapi.h"
13 #include "guests.h"
14 #include "winprocess.h"
15 #include "lixprocess.h"
16 
18 static CAMI_VERSION gCamiVersion = { 0 };
19 
21 static const BYTE *gUpdateBuffer = NULL;
22 
25 
28 
31 
34 
37 
40 
41 
43 #define IS_CAMI_FILEOFFSET_OK(FileOffset) __likely((FileOffset) < gUpdateBufferSize)
44 
46 #define IS_CAMI_FILEPOINTER_OK(FilePointer) __likely((const BYTE*)(FilePointer) >= (const BYTE*)gUpdateBuffer) && \
47  ((const BYTE*)(FilePointer) < (const BYTE*)gUpdateBuffer + \
48  gUpdateBufferSize)
49 
51 #define IS_CAMI_STRUCTURE_OK(FilePointer) __likely(IS_CAMI_FILEPOINTER_OK(FilePointer) && \
52  IS_CAMI_FILEPOINTER_OK(((const BYTE*)((FilePointer) + 1) - 1)))
53 
55 #define IS_CAMI_ARRAY_OK(StartPointer, Count) __likely(IS_CAMI_FILEPOINTER_OK(StartPointer) && \
56  ((Count) < CAMI_MAX_ENTRY_COUNT) && \
57  (((DWORD)(Count) == 0) || \
58  (IS_CAMI_FILEPOINTER_OK((const BYTE*)((StartPointer) + \
59  (DWORD)(Count)) - 1))))
60 
67 #define GET_CAMI_STRUCT(Type, Offset) ((Type)(const void *)((const BYTE*)gUpdateBuffer + (DWORD)(Offset)))
68 
70 typedef struct _CAMI_STRUCTURE
71 {
77 
83  size_t Offset;
84 
88 
91 {
92  struct
93  {
94  union
95  {
96  WCHAR Name16[32];
97  CHAR Name8[64];
98  };
99 
101  } Name;
102 
105 
108 {
112 
113 
116 
119 {
121  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Info),
122  .MembersCount = lixFieldInfoEnd},
123 
124  {.StructureTag = lixStructureModule,
125  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Module),
126  .MembersCount = lixFieldModuleEnd},
127 
128  {.StructureTag = lixStructureBinprm,
129  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Binprm),
130  .MembersCount = lixFieldBinprmEnd},
131 
132  {.StructureTag = lixStructureVma,
133  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Vma),
134  .MembersCount = lixFieldVmaEnd},
135 
136  {.StructureTag = lixStructureDentry,
137  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Dentry),
138  .MembersCount = lixFieldDentryEnd},
139 
140  {.StructureTag = lixStructureMmStruct,
141  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.MmStruct),
142  .MembersCount = lixFieldMmStructEnd},
143 
144  {.StructureTag = lixStructureTaskStruct,
145  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.TaskStruct),
146  .MembersCount = lixFieldTaskStructEnd},
147 
148  {.StructureTag = lixStructureFs,
149  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Fs),
150  .MembersCount = lixFieldFsEnd},
151 
152  {.StructureTag = lixStructureFdTable,
153  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.FdTable),
154  .MembersCount = lixFieldFdTableEnd},
155 
156  {.StructureTag = lixStructureFiles,
157  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Files),
158  .MembersCount = lixFieldFilesEnd},
159 
160  {.StructureTag = lixStructureInode,
161  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Inode),
162  .MembersCount = lixFieldInodeEnd},
163 
164  {.StructureTag = lixStructureSocket,
165  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Socket),
166  .MembersCount = lixFieldSocketEnd},
167 
168  {.StructureTag = lixStructureSock,
169  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Sock),
170  .MembersCount = lixFieldSockEnd},
171 
172  {.StructureTag = lixStructureCred,
173  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Cred),
174  .MembersCount = lixFieldCredEnd},
175 
176  {.StructureTag = lixStructureNsProxy,
177  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.NsProxy),
178  .MembersCount = lixFieldNsProxyEnd},
179 
180  {.StructureTag = lixStructureUngrouped,
181  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Ungrouped),
182  .MembersCount = lixFieldUngroupedEnd},
183 };
184 
187 {
189  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Process),
190  .MembersCount = winKmFieldProcessEnd},
191 
192  {.StructureTag = winKmStructureThread,
193  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Thread),
194  .MembersCount = winKmFieldThreadEnd},
195 
196  {.StructureTag = winKmStructureDrvObj,
197  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.DrvObj),
198  .MembersCount = winKmFieldDrvObjEnd},
199 
200  {.StructureTag = winKmStructurePcr,
201  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Pcr),
202  .MembersCount = winKmFieldPcrEnd},
203 
204  {.StructureTag = winKmStructurePoolDescriptor,
205  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.PoolDescriptor),
206  .MembersCount = winKmFieldPoolDescriptorEnd},
207 
208  {.StructureTag = winKmStructureMmpfn,
209  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Mmpfn),
210  .MembersCount = winKmFieldMmpfnEnd},
211 
212  {.StructureTag = winKmStructureToken,
213  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Token),
214  .MembersCount = winKmFieldTokenEnd},
215 
216  {.StructureTag = winKmStructureUngrouped,
217  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Ungrouped),
218  .MembersCount = winKmFieldUngroupedEnd},
219 
220  {.StructureTag = winKmStructureEprocessFlags,
221  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.EprocessFlags),
222  .MembersCount = winKmFieldEprocessFlagsEnd},
223 
224  {.StructureTag = winKmStructureVadShort,
225  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadShort),
226  .MembersCount = winKmFieldVadShortEnd},
227 
228  {.StructureTag = winKmStructureVadLong,
229  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadLong),
230  .MembersCount = winKmFieldVadLongEnd},
231 
232  {.StructureTag = winKmStructureVadFlags,
233  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadFlags),
234  .MembersCount = winKmFieldVadFlagsEnd},
235 
236  {.StructureTag = winKmStructureSyscallNumbers,
237  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.SyscallNumbers),
238  .MembersCount = winKmFieldSyscallNumbersEnd},
239 
240  {.StructureTag = winKmStructureFileObject,
241  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.FileObject),
242  .MembersCount = winKmFieldFileObjectEnd},
243 };
244 
247 {
249  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Dll),
250  .MembersCount = winUmFieldDllEnd },
251 
252  {.StructureTag = winUmStructurePeb,
253  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Peb),
254  .MembersCount = winUmFieldPebEnd },
255 
256  {.StructureTag = winUmStructureTeb,
257  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Teb),
258  .MembersCount = winUmFieldTebEnd },
259 };
260 
261 
262 static BOOLEAN
264  _In_ QWORD MinIntroVersion,
265  _In_ QWORD MaxIntroVersion
266  )
272 {
273  INT_VERSION_INFO minVer, maxVer;
274 
275  minVer.Raw = MinIntroVersion;
276  maxVer.Raw = MaxIntroVersion;
277 
278  // Make sure we don't compare build numbers.
279  minVer.VersionInfo.Build = 0;
280  maxVer.VersionInfo.Build = WORD_MAX;
281 
282  return IntHviVersion.Raw >= minVer.Raw && IntHviVersion.Raw <= maxVer.Raw;
283 }
284 
285 
286 static const CAMI_SECTION_HEADER *
288  _In_ const CAMI_HEADER *CamiHeader,
289  _In_ DWORD SectionHint
290  )
300 {
301  const CAMI_SECTION_HEADER *pHeaders;
302 
303  pHeaders = GET_CAMI_STRUCT(const CAMI_SECTION_HEADER *, CamiHeader->PointerToSectionsHeaders);
304  if (!IS_CAMI_ARRAY_OK(pHeaders, CamiHeader->NumberOfSections))
305  {
306  ERROR("[ERROR] Sections table entries are outside the update buffer!\n");
307  return NULL;
308  }
309 
310  for (DWORD i = 0; i < CamiHeader->NumberOfSections; i++)
311  {
312  if ((pHeaders[i].Hint & SectionHint) == SectionHint)
313  {
314  return (pHeaders + i);
315  }
316  }
317 
318  return NULL;
319 }
320 
321 
322 static INTSTATUS
324  _In_ const CAMI_OPAQUE_STRUCTURE *CamiStructures,
325  _In_ const CAMI_STRUCTURE *ToLoad,
326  _In_ DWORD Count,
327  _In_ INTRO_GUEST_TYPE OsType
328  )
343 {
344  char *pBasePtr = NULL;
345 
346  switch (OsType)
347  {
348  case introGuestLinux:
349  pBasePtr = (char *)gLixGuest;
350  break;
351 
352  case introGuestWindows:
353  pBasePtr = (char *)gWinGuest;
354  break;
355 
356  default:
358  }
359 
360  for (DWORD iStruct = 0; iStruct < Count; iStruct++)
361  {
362  const DWORD *pFields;
363 
364  if (CamiStructures->MembersCount < ToLoad->MembersCount)
365  {
366  ERROR("[ERROR] For structure %d we need at least %d fields, got only %d\n",
367  iStruct, ToLoad->MembersCount, CamiStructures->MembersCount);
369  }
370 
371  pFields = GET_CAMI_STRUCT(const DWORD *, CamiStructures->Members);
372  if (!IS_CAMI_ARRAY_OK(pFields, CamiStructures->MembersCount))
373  {
374  ERROR("[ERROR] Members for structure %d are outside the update buffer!\n", iStruct);
376  }
377 
378  memcpy(pBasePtr + ToLoad->Offset, pFields, sizeof(DWORD) * ToLoad->MembersCount);
379 
380  CamiStructures++;
381  ToLoad++;
382  }
383 
384  return INT_STATUS_SUCCESS;
385 
386 }
387 
388 
389 static INTSTATUS
391  _In_ const CAMI_SECTION_HEADER *SectionHeader,
392  _Out_ PATTERN_SIGNATURE **PatternSignatures,
393  _Out_ DWORD *PatternSignaturesCount
394  )
404 {
405  const CAMI_PATTERN_SIGNATURE *pCamiSignatures;
406 
407  pCamiSignatures = GET_CAMI_STRUCT(const CAMI_PATTERN_SIGNATURE *, SectionHeader->DescriptorTable);
408  if (!IS_CAMI_ARRAY_OK(pCamiSignatures, SectionHeader->EntryCount))
409  {
410  LOG("[ERROR] Pattern signature descriptors are outside the update buffer!");
412  }
413 
414  if (SectionHeader->EntryCount == 0)
415  {
416  ERROR("[ERROR] Invalid entry count for the pattern signature array: %u\n", SectionHeader->EntryCount);
418  }
419 
420  *PatternSignatures = HpAllocWithTag(sizeof(PATTERN_SIGNATURE) * SectionHeader->EntryCount, IC_TAG_CAMI);
421  if (NULL == *PatternSignatures)
422  {
424  }
425 
426  *PatternSignaturesCount = 0;
427 
428  for (DWORD i = 0; i < SectionHeader->EntryCount; i++)
429  {
430  const CAMI_PATTERN_SIGNATURE *pCamiPat;
431  PPATTERN_SIGNATURE pPat;
432  const WORD *pPatternHash;
433 
434  pCamiPat = pCamiSignatures + i;
435  pPat = *PatternSignatures + i;
436 
437  pPatternHash = GET_CAMI_STRUCT(const WORD *, pCamiPat->PatternOffset);
438  if (!IS_CAMI_ARRAY_OK(pPatternHash, pCamiPat->PatternLength))
439  {
440  ERROR("[ERROR] Hash for signature %d is outside the update buffer!\n", i);
441 
442  HpFreeAndNullWithTag(PatternSignatures, IC_TAG_CAMI);
444  }
445 
446  pPat->SignatureId = pCamiPat->SignatureId;
447  pPat->Offset = pCamiPat->Offset;
448  pPat->Length = MIN(pCamiPat->PatternLength, ARRAYSIZE(pPat->Pattern));
449 
450  memcpy(pPat->Pattern, pPatternHash, pPat->Length * sizeof(pPat->Pattern[0]));
451  }
452 
453  *PatternSignaturesCount = SectionHeader->EntryCount;
454 
455  return INT_STATUS_SUCCESS;
456 }
457 
458 
459 static INTSTATUS
461  _In_ const CAMI_HEADER *CamiHeader
462  )
470 {
471  const CAMI_SECTION_HEADER *pSec;
472 
474  if (NULL == pSec)
475  {
476  ERROR("[ERROR] Failed to find syscalls section header\n");
477  return INT_STATUS_NOT_FOUND;
478  }
479 
480  return IntCamiLoadPatternSignatures(pSec, &gSysenterSignatures, &gSysenterSignaturesCount);
481 }
482 
483 
484 static INTSTATUS
486  _In_ const CAMI_HEADER *CamiHeader
487  )
495 {
496  const CAMI_SECTION_HEADER *pSec;
497 
499  if (NULL == pSec)
500  {
501  ERROR("[ERROR] Failed to find syscalls section header\n");
502  return INT_STATUS_NOT_FOUND;
503  }
504 
505  return IntCamiLoadPatternSignatures(pSec, &gLinuxDistSigs, &gLinuxDistSigsCount);
506 }
507 
508 
509 static void
511  _In_ const CAMI_PROT_OPTIONS *Src,
513  )
520 {
521  if (Dst->ForceOff != Src->ForceOff)
522  {
523  LOG("[CAMI] New force off options: 0x%016llx\n", Src->ForceOff);
524  }
525 
526  Dst->ForceOff = Src->ForceOff;
527 
528  if (Dst->Beta != Src->ForceBeta)
529  {
530  LOG("[CAMI] New force beta options: 0x%016llx\n", Src->ForceBeta);
531  }
532 
533  Dst->Beta = Src->ForceBeta;
534 
535  if (Dst->Feedback != Src->ForceFeedback)
536  {
537  LOG("[CAMI] New force feedback options: 0x%016llx\n", Src->ForceFeedback);
538  }
539 
540  Dst->Feedback = Src->ForceFeedback;
541 }
542 
543 
544 static INTSTATUS
546  _In_ const CAMI_PROT_OPTIONS *Options
547  )
555 {
556  LOG("[CAMI] Will set new core options!\n");
557 
559 
561 
562  return INT_STATUS_SUCCESS;
563 }
564 
565 
566 static INTSTATUS
568  _In_ const CAMI_PROT_OPTIONS *Options
569  )
577 {
578  LOG("[CAMI] Will set new shemu options!\n");
579 
581 
583 
584  return INT_STATUS_SUCCESS;
585 }
586 
587 
588 static INTSTATUS
590  _In_ LIX_PROTECTED_PROCESS *ProtectedProcess
591  )
599 {
600  for (DWORD index = 0; index < gCamiProcessProtectionData.Count; index++)
601  {
602  BOOLEAN match = FALSE;
603  if (gCamiProcessProtectionData.Items[index].Name.Encoding != CAMI_STRING_ENCODING_UTF8)
604  {
605  WARNING("[WARNING] Unsupported process name encoding: %d. Will skip...\n",
606  gCamiProcessProtectionData.Items[index].Name.Encoding);
607  }
608  else
609  {
610  if (IntMatchPatternUtf8(gCamiProcessProtectionData.Items[index].Name.Name8,
611  ProtectedProcess->CommPattern,
612  0))
613  {
614  match = TRUE;
615  }
616  }
617 
618  if (match)
619  {
620  ProtectedProcess->Protection.Current =
621  ProtectedProcess->Protection.Original & ~(gCamiProcessProtectionData.Items[index].Options.ForceOff);
622  ProtectedProcess->Protection.Beta = gCamiProcessProtectionData.Items[index].Options.ForceBeta;
623  ProtectedProcess->Protection.Feedback = gCamiProcessProtectionData.Items[index].Options.ForceFeedback;
624 
625  TRACE("[CAMI] Protection options for '%s': %llx %llx %llx", ProtectedProcess->CommPattern,
626  ProtectedProcess->Protection.Current, ProtectedProcess->Protection.Beta,
627  ProtectedProcess->Protection.Feedback);
628  }
629  }
630 
631  return INT_STATUS_SUCCESS;
632 }
633 
634 
635 static INTSTATUS
637  _In_ PROTECTED_PROCESS_INFO *ProtectedProcess
638  )
646 {
647  for (DWORD index = 0; index < gCamiProcessProtectionData.Count; index++)
648  {
649  BOOLEAN match = FALSE;
650  switch (gCamiProcessProtectionData.Items[index].Name.Encoding)
651  {
653  {
654  if (IntMatchPatternUtf16(gCamiProcessProtectionData.Items[index].Name.Name16,
655  ProtectedProcess->FullNamePattern,
656  0))
657  {
658  match = TRUE;
659  }
660  break;
661  }
663  {
664  if (IntMatchPatternUtf8(gCamiProcessProtectionData.Items[index].Name.Name8,
665  ProtectedProcess->ImageBaseNamePattern,
666  0))
667  {
668  match = TRUE;
669  }
670  break;
671  }
672  default:
673  {
674  WARNING("[WARNING] Unsupported process name encoding: %d. Will skip...\n",
675  gCamiProcessProtectionData.Items[index].Name.Encoding);
676  }
677  }
678 
679  if (match)
680  {
681  ProtectedProcess->Protection.Current =
682  ProtectedProcess->Protection.Original & ~(gCamiProcessProtectionData.Items[index].Options.ForceOff);
683  ProtectedProcess->Protection.Beta = gCamiProcessProtectionData.Items[index].Options.ForceBeta;
684  ProtectedProcess->Protection.Feedback = gCamiProcessProtectionData.Items[index].Options.ForceFeedback;
685 
686  TRACE("[CAMI] Protection options for '%s': %x %llx %llx", ProtectedProcess->ImageBaseNamePattern,
687  ProtectedProcess->Protection.Current, ProtectedProcess->Protection.Beta,
688  ProtectedProcess->Protection.Feedback);
689 
690  }
691  }
692 
693  return INT_STATUS_SUCCESS;
694 }
695 
696 
697 INTSTATUS
699  _In_ void *ProtectedProcess
700  )
710 {
712  {
713  return IntCamiUpdateProcessProtectionInfoWin(ProtectedProcess);
714  }
715  else if (gGuest.OSType == introGuestLinux)
716  {
717  return IntCamiUpdateProcessProtectionInfoLix(ProtectedProcess);
718  }
719 
721 }
722 
723 
724 void
726  _In_ void *Name,
727  _In_ CAMI_STRING_ENCODING Encoding,
728  _In_ CAMI_PROT_OPTIONS *Options
729  )
737 {
739  {
740  IntWinProcUpdateProtectedProcess(Name, Encoding, Options);
741  }
742  else if (gGuest.OSType == introGuestLinux)
743  {
744  IntLixProcUpdateProtectedProcess(Name, Encoding, Options);
745  }
746 }
747 
748 
749 static INTSTATUS
751  _In_ const CAMI_PROC_PROT_OPTIONS *Table,
752  _In_ DWORD TableCount
753  )
762 {
763  for (DWORD index = 0; index < TableCount; index++)
764  {
765  const CAMI_PROT_OPTIONS *pOptions = GET_CAMI_STRUCT(const CAMI_PROT_OPTIONS *, Table[index].OptionsOffset);
766  if (!IS_CAMI_STRUCTURE_OK(pOptions))
767  {
768  ERROR("[ERROR] CAMI_PROT_OPTIONS struct is invalid! (%p)", pOptions);
770  }
771 
772  memcpy(gCamiProcessProtectionData.Items[index].Name.Name8, Table[index].Name8, 64);
773  gCamiProcessProtectionData.Items[index].Name.Encoding = Table[index].Encoding;
774  gCamiProcessProtectionData.Items[index].Options = *pOptions;
775 
776  TRACE("[CAMI] NameHash : %s -> ForceOff : 0x%llx, ForceBeta: 0x%llx, ForceFeedback: 0x%llx",
777  Table[index].Name8, pOptions->ForceOff, pOptions->ForceBeta, pOptions->ForceFeedback);
778 
779  IntCamiUpdateProcessProtectionItems(gCamiProcessProtectionData.Items[index].Name.Name8,
780  gCamiProcessProtectionData.Items[index].Name.Encoding,
781  &gCamiProcessProtectionData.Items[index].Options);
782  }
783 
785  {
787  }
788  else if (gGuest.OSType == introGuestLinux)
789  {
791  }
792  else
793  {
795  }
796 
797  return INT_STATUS_SUCCESS;
798 }
799 
800 
801 static INTSTATUS
803  void
804  )
810 {
811  const CAMI_PROT_OPTIONS defaultOpts = {0};
812 
813  return IntCamiSetCoreOptions(&defaultOpts);
814 }
815 
816 
817 static INTSTATUS
819  void
820  )
826 {
827  const CAMI_PROT_OPTIONS defaultOpts = {0};
828 
829  return IntCamiSetShemuOptions(&defaultOpts);
830 }
831 
832 
833 static INTSTATUS
835  _In_ DWORD OptionsFileOffset
836  )
844 {
845  INTSTATUS status;
846  const CAMI_CUSTOM_OS_PROTECTION *pOsProt;
847 
848  if (0 == OptionsFileOffset)
849  {
852 
853  return INT_STATUS_SUCCESS;
854  }
855 
856  if (!IS_CAMI_FILEOFFSET_OK(OptionsFileOffset))
857  {
858  ERROR("[ERROR] Invalid file offset: %d / %d\n", OptionsFileOffset, gUpdateBufferSize);
860  }
861 
862  pOsProt = GET_CAMI_STRUCT(const CAMI_CUSTOM_OS_PROTECTION *, OptionsFileOffset);
863 
865  {
866  ERROR("[ERROR] Invalid CoreOptionsOffset: 0x%x / %08x\n", pOsProt->CoreOptionsOffset, gUpdateBufferSize);
868  }
869 
871  {
872  ERROR("[ERROR] Invalid ShemuOptionsOffset: 0x%x / %08x\n", pOsProt->ShemuOptionsOffset, gUpdateBufferSize);
874  }
875 
876  if (pOsProt->ProcOptionsCount > 0)
877  {
879  pOsProt->ProcOptionsTable);
880  if (!IS_CAMI_ARRAY_OK(pProcProt, pOsProt->ProcOptionsCount))
881  {
882  ERROR("[ERROR] Invalid ProcOptionsTable : 0x%0x / %08x.\n", pOsProt->ProcOptionsTable, gUpdateBufferSize);
884  }
885 
887 
889  if (!INT_SUCCESS(status))
890  {
891  ERROR("[ERROR] IntCamiProtectedProcessAllocate failed with status: 0x%08x.", status);
892  return status;
893  }
894 
895  status = IntCamiSetProcProtOptions(pProcProt, pOsProt->ProcOptionsCount);
896  if (!INT_SUCCESS(status))
897  {
898  ERROR("[ERROR] IntCamiSetProcProtOptions failed with status: 0x%08x.\n", status);
899  return status;
900  }
901  }
902 
904  if (!INT_SUCCESS(status))
905  {
906  ERROR("[ERROR] IntCamiSetCoreOptions failed with status: 0x%08x.\n", status);
907  return status;
908  }
909 
911  if (!INT_SUCCESS(status))
912  {
913  ERROR("[ERROR] IntCamiSetShemuOptions failed with status: 0x%08x.\n", status);
914  return status;
915  }
916 
917  return INT_STATUS_SUCCESS;
918 }
919 
920 
921 static INTSTATUS
923  _In_ const CAMI_HEADER *CamiHeader
924  )
938 {
939  const CAMI_SECTION_HEADER *pSec;
940  const CAMI_LIX_DESCRIPTOR *pLixOsList;
941  INTSTATUS status;
942 
944  if (NULL == pSec)
945  {
946  ERROR("[ERROR] Failed to find Linux section header\n");
947  return INT_STATUS_NOT_FOUND;
948  }
949 
950  pLixOsList = GET_CAMI_STRUCT(const CAMI_LIX_DESCRIPTOR *, pSec->DescriptorTable);
951  if (!IS_CAMI_ARRAY_OK(pLixOsList, pSec->EntryCount))
952  {
953  ERROR("[ERROR] Linux supported OS descriptors are outside the update buffer!");
955  }
956 
957  for (DWORD i = 0; i < pSec->EntryCount; i++)
958  {
959  const CAMI_LIX_DESCRIPTOR *pLix;
960  const CAMI_LIX_HOOK *pHooks;
961  const CAMI_OPAQUE_STRUCTURE *pStructures;
962 
963  pLix = pLixOsList + i;
964 
966  {
967  continue;
968  }
969 
971  {
972  LOG("[WARNING] This OS is no longer supported by introcore!\n");
973  continue;
974  }
975 
976  if (lixStructureEnd > pLix->StructuresCount)
977  {
978  ERROR("[ERROR] Expected %d fields, got %d.", lixStructureEnd, pLix->StructuresCount);
980  }
981 
982  if (pLix->HooksCount > LIX_MAX_HOOKED_FN_COUNT || pLix->HooksCount == 0)
983  {
984  ERROR("[ERROR] Unsupported number of hooks! Got %d, expected a max of %d!\n",
987  }
988 
989  pStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pLix->StructuresTable);
990  if (!IS_CAMI_ARRAY_OK(pStructures, pLix->StructuresCount))
991  {
992  ERROR("[ERROR] Fields for OS %s are outside the update buffer.", pLix->VersionString);
994  }
995 
996  pHooks = GET_CAMI_STRUCT(const CAMI_LIX_HOOK *, pLix->HooksTable);
997  if (!IS_CAMI_ARRAY_OK(pHooks, pLix->HooksCount))
998  {
999  ERROR("[ERROR] Hooks for OS %s are outside the update buffer.", pLix->VersionString);
1001  }
1002 
1004  if (!INT_SUCCESS(status))
1005  {
1006  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1007  // Shall we bail out?
1008  }
1009 
1010  status = IntCamiLoadOpaqueFields(pStructures, gLinuxStructures, lixStructureEnd, introGuestLinux);
1011  if (!INT_SUCCESS(status))
1012  {
1013  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for linux fields. Status: 0x%08x\n", status);
1014  return status;
1015  }
1016 
1018 
1021 
1022  if (NULL == gLixGuest->OsSpecificFields.Functions)
1023  {
1025  }
1026 
1027  for (DWORD j = 0; j < pLix->HooksCount; j++)
1028  {
1030 
1031  pFun->NameHash = pHooks[j].NameHash;
1032  pFun->SkipOnBoot = pHooks[j].SkipOnBoot;
1033  pFun->HookHandler = pHooks[j].HookHandler;
1034  }
1035 
1037 
1038  return INT_STATUS_SUCCESS;
1039  }
1040 
1041  return INT_STATUS_NOT_SUPPORTED;
1042 }
1043 
1044 
1045 static INTSTATUS
1047  _In_ const CAMI_HEADER *CamiHeader
1048  )
1063 {
1064  const CAMI_SECTION_HEADER *pSec;
1065  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1066  INTSTATUS status;
1067 
1069  if (NULL == pSec)
1070  {
1071  ERROR("[ERROR] Failed to find Windows section header\n");
1072  return INT_STATUS_NOT_FOUND;
1073  }
1074 
1075  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1076  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1077  {
1078  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1080  }
1081 
1082  for (DWORD i = 0; i < pSec->EntryCount; i++)
1083  {
1084  const CAMI_WIN_DESCRIPTOR *pWin;
1085  const CAMI_OPAQUE_STRUCTURE *pKmStructures, *pUmStructures;
1086  const CAMI_WIN_FUNCTION *pFunTable;
1087  const CAMI_WIN_VERSION_STRING *pCamiVersionString;
1088 
1089  pWin = pWinOsList + i;
1090 
1091  if (gGuest.OSVersion != pWin->BuildNumber ||
1092  gGuest.Guest64 != pWin->Is64 ||
1093  gGuest.KptiInstalled != pWin->Kpti)
1094  {
1095  continue;
1096  }
1097 
1099  {
1100  LOG("[WARNING] This OS is no longer supported by introcore!\n");
1101  continue;
1102  }
1103 
1104  pFunTable = GET_CAMI_STRUCT(const CAMI_WIN_FUNCTION *, pWin->FunctionTable);
1105  if (!IS_CAMI_ARRAY_OK(pFunTable, pWin->FunctionCount))
1106  {
1107  ERROR("[ERROR] Functions for OS %d KPTI %d is64 %d are outside the update buffer. ",
1108  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1110  }
1111 
1112  pKmStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pWin->KmStructuresTable);
1113  if (!IS_CAMI_ARRAY_OK(pKmStructures, pWin->KmStructuresCount))
1114  {
1115  ERROR("[ERROR] Km Structures for OS %d KPTI %d is64 %d are outside the update buffer. \n",
1116  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1118  }
1119 
1120  pCamiVersionString = GET_CAMI_STRUCT(const CAMI_WIN_VERSION_STRING *, pWin->VersionStringOffset);
1121  if (!IS_CAMI_STRUCTURE_OK(pCamiVersionString))
1122  {
1123  ERROR("[ERROR] CAMI_WIN_VERSION_STRING struct is invalid! (%p)", pCamiVersionString);
1125  }
1126 
1127  if (pCamiVersionString->VersionStringSize > MAX_VERSION_STRING_SIZE ||
1128  pCamiVersionString->VersionStringSize == 0)
1129  {
1130  ERROR("[ERROR] VersionString size is too big (%llx)\n", pCamiVersionString->VersionStringSize);
1132  }
1133 
1135  if (NULL == gWinGuest->VersionString)
1136  {
1138  }
1139 
1140  strlcpy(gWinGuest->VersionString, pCamiVersionString->VersionString, pCamiVersionString->VersionStringSize);
1141 
1142  if (pCamiVersionString->ServerVersionStringSize > MAX_VERSION_STRING_SIZE ||
1143  pCamiVersionString->ServerVersionStringSize == 0)
1144  {
1145  ERROR("[ERROR] VersionString size is too big (%llx)\n", pCamiVersionString->ServerVersionStringSize);
1147  }
1148 
1150  if (NULL == gWinGuest->ServerVersionString)
1151  {
1153  }
1154 
1156  pCamiVersionString->ServerVersionStringSize);
1157 
1158  pUmStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pWin->UmStructuresTable);
1159  if (!IS_CAMI_ARRAY_OK(pUmStructures, pWin->UmStructuresCount))
1160  {
1161  ERROR("[ERROR] Um Structures for OS %d KPTI %d is64 %d are outside the update buffer. \n",
1162  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1164  }
1165 
1167  {
1168  ERROR("[ERROR] Expected %d structures, got %d.", winKmStructureEnd, pWin->KmStructuresCount);
1169  return INT_STATUS_NOT_SUPPORTED;
1170  }
1171 
1173  {
1174  ERROR("[ERROR] Expected %d structures, got %d.", winUmStructureEnd, pWin->UmStructuresCount);
1175  return INT_STATUS_NOT_SUPPORTED;
1176  }
1177 
1179  if (!INT_SUCCESS(status))
1180  {
1181  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1182  // Shall we bail out?
1183  }
1184 
1185  status = IntCamiLoadOpaqueFields(pKmStructures, gWinKmStructures, winKmStructureEnd, introGuestWindows);
1186  if (!INT_SUCCESS(status))
1187  {
1188  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for win km structures: 0x%08x\n", status);
1189  return status;
1190  }
1191 
1192  status = IntCamiLoadOpaqueFields(pUmStructures, gWinUmStructures, winUmStructureEnd, introGuestWindows);
1193  if (!INT_SUCCESS(status))
1194  {
1195  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for win um structures: 0x%08x\n", status);
1196  return status;
1197  }
1198 
1199  for (DWORD j = 0; j < pWin->FunctionCount; j++)
1200  {
1202  const CAMI_WIN_FUNCTION_PATTERN *pPatterns;
1203  const DWORD *pArgs;
1204 
1205  pPatterns = GET_CAMI_STRUCT(const CAMI_WIN_FUNCTION_PATTERN *, pFunTable[j].PatternsTable);
1206  if (!IS_CAMI_ARRAY_OK(pPatterns, pFunTable[j].PatternsCount))
1207  {
1208  ERROR("[ERROR] Function %d has patterns outside the update buffer. \n", j);
1210  }
1211 
1212  pArgs = GET_CAMI_STRUCT(const DWORD *, pFunTable[j].ArgumentsTable);
1213  if (!IS_CAMI_ARRAY_OK(pArgs, pFunTable[j].ArgumentsCount))
1214  {
1215  ERROR("[ERROR] Function %d has arguments outside the update buffer. Will skip!\n", j);
1216  continue;
1217  }
1218 
1219  pWf = HpAllocWithTag(sizeof(*pWf) + pFunTable[j].PatternsCount * sizeof(pWf->Patterns[0]), IC_TAG_CAMI);
1220  if (NULL == pWf)
1221  {
1222  // Bail out if we ran out of memory, we won't be able to
1223  // load the rest anyway and we'll basically be useless
1224  // without function hooks...
1226  }
1227 
1228  for (DWORD k = 0; k < pFunTable[j].PatternsCount; k++)
1229  {
1230  const WORD *pPatHash;
1231 
1232  pPatHash = GET_CAMI_STRUCT(const WORD *, pPatterns[k].HashOffset);
1233  if (!IS_CAMI_ARRAY_OK(pPatHash, pPatterns[k].HashLength))
1234  {
1235  ERROR("[ERROR] Hash for pattern %d of function %d spills outside the update buffer. Will skip!",
1236  k, j);
1239  }
1240 
1241  memcpy(pWf->Patterns[k].SectionHint, pPatterns[k].SectionHint, 8);
1242 
1243  pWf->Patterns[k].Signature.Length = MIN(SIG_MAX_PATTERN, pPatterns[k].HashLength);
1244  memcpy(pWf->Patterns[k].Signature.Pattern, pPatHash, 2ull * pWf->Patterns[k].Signature.Length);
1245  }
1246 
1247  pWf->NameHash = pFunTable[j].NameHash;
1248  pWf->PatternsCount = pFunTable[j].PatternsCount;
1249 
1250  status = IntWinApiUpdateHookDescriptor(pWf, pFunTable[j].ArgumentsCount, pArgs);
1251  if (!INT_SUCCESS(status))
1252  {
1253  WARNING("[WARNING] Failed to add function %d %x to a hook descriptor: 0x%08x\n",
1254  j, pFunTable[j].NameHash, status);
1256  }
1257  }
1258 
1259  return INT_STATUS_SUCCESS;
1260  }
1261 
1262  return INT_STATUS_NOT_SUPPORTED;
1263 }
1264 
1265 
1266 static INTSTATUS
1268  _In_ const CAMI_HEADER *CamiHeader
1269  )
1279 {
1280  const CAMI_SECTION_HEADER *pSec;
1281  const CAMI_LIX_DESCRIPTOR *pLixOsList;
1282  INTSTATUS status;
1283 
1285  if (NULL == pSec)
1286  {
1287  ERROR("[ERROR] Failed to find Linux section header\n");
1288  return INT_STATUS_NOT_FOUND;
1289  }
1290 
1291  pLixOsList = GET_CAMI_STRUCT(const CAMI_LIX_DESCRIPTOR *, pSec->DescriptorTable);
1292  if (!IS_CAMI_ARRAY_OK(pLixOsList, pSec->EntryCount))
1293  {
1294  ERROR("[ERROR] Linux supported OS descriptors are outside the update buffer!");
1296  }
1297 
1298  for (DWORD i = 0; i < pSec->EntryCount; i++)
1299  {
1300  const CAMI_LIX_DESCRIPTOR *pLix = pLixOsList + i;
1301 
1303  {
1304  continue;
1305  }
1306 
1308  {
1309  continue;
1310  }
1311 
1312  if (lixStructureEnd > pLix->StructuresCount)
1313  {
1314  ERROR("[ERROR] Expected %d fields, got %d.", lixStructureEnd, pLix->StructuresCount);
1315  return INT_STATUS_NOT_SUPPORTED;
1316  }
1317 
1319  if (!INT_SUCCESS(status))
1320  {
1321  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1322  }
1323 
1324  return status;
1325  }
1326 
1328 }
1329 
1330 
1331 static INTSTATUS
1333  _In_ const CAMI_HEADER *CamiHeader
1334  )
1344 {
1345  const CAMI_SECTION_HEADER *pSec;
1346  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1347  INTSTATUS status;
1348 
1350  if (NULL == pSec)
1351  {
1352  ERROR("[ERROR] Failed to find windows section header\n");
1353  return INT_STATUS_NOT_FOUND;
1354  }
1355 
1356  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1357  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1358  {
1359  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1361  }
1362 
1363  for (DWORD i = 0; i < pSec->EntryCount; i++)
1364  {
1365  const CAMI_WIN_DESCRIPTOR *pWin = pWinOsList + i;
1366 
1367  if ((gGuest.OSVersion != pWin->BuildNumber) ||
1368  (gGuest.Guest64 != pWin->Is64) ||
1369  (gGuest.KptiInstalled != pWin->Kpti))
1370  {
1371  continue;
1372  }
1373 
1375  {
1376  continue;
1377  }
1378 
1380  if (!INT_SUCCESS(status))
1381  {
1382  ERROR("[ERROR] Failed to load introcore options for this OS: 0x%08x\n", status);
1383  }
1384 
1385  return status;
1386  }
1387 
1389 }
1390 
1391 
1392 INTSTATUS
1394  _In_ BOOLEAN KptiInstalled,
1395  _In_ BOOLEAN Guest64,
1396  _Out_opt_ DWORD *NtBuildNumberList,
1397  _Inout_ DWORD *Count
1398  )
1418 {
1419  const CAMI_SECTION_HEADER *pSec;
1420  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1421  const CAMI_WIN_DESCRIPTOR *pWin;
1422  DWORD i, lastNt, cnt;
1423 
1424  if (NULL == Count)
1425  {
1427  }
1428 
1429  if (NULL != NtBuildNumberList && 0 == *Count)
1430  {
1432  }
1433 
1434  if (NULL == gUpdateBuffer || 0 == gUpdateBufferSize)
1435  {
1437  }
1438 
1441  if (NULL == pSec)
1442  {
1443  ERROR("[ERROR] Failed to find windows section header\n");
1444  return INT_STATUS_NOT_FOUND;
1445  }
1446 
1447  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1448  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1449  {
1450  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1452  }
1453 
1454  lastNt = cnt = 0;
1455  // the OS list from CAMI is sorted by NtBuildNumber, so it's fine.
1456  for (i = 0; i < pSec->EntryCount; i++)
1457  {
1458  pWin = pWinOsList + i;
1459 
1461  Guest64 != pWin->Is64 || KptiInstalled != pWin->Kpti)
1462  {
1463  continue;
1464  }
1465 
1466  if (pWin->BuildNumber != lastNt)
1467  {
1468  lastNt = pWin->BuildNumber;
1469 
1470  if (NULL != NtBuildNumberList)
1471  {
1472  if (cnt >= *Count)
1473  {
1474  return INT_STATUS_SUCCESS;
1475  }
1476 
1477  NtBuildNumberList[cnt] = lastNt;
1478  }
1479 
1480  cnt++;
1481  }
1482  }
1483 
1484  *Count = cnt;
1485 
1486  return INT_STATUS_SUCCESS;
1487 }
1488 
1489 
1490 INTSTATUS
1492  _In_ DWORD CamiSectionHint
1493  )
1501 {
1502  INTSTATUS status;
1503  const CAMI_HEADER *pCami;
1504 
1505  if (NULL == gUpdateBuffer || 0 == gUpdateBufferSize)
1506  {
1508  }
1509 
1510  pCami = (const CAMI_HEADER *)gUpdateBuffer;
1511 
1512  status = INT_STATUS_NOT_FOUND;
1513  if (CamiSectionHint & CAMI_SECTION_HINT_SUPPORTED_OS)
1514  {
1515  if (CamiSectionHint & CAMI_SECTION_HINT_WINDOWS)
1516  {
1517  status = IntCamiLoadWindows(pCami);
1518  }
1519  else if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1520  {
1521  status = IntCamiLoadLinux(pCami);
1522  }
1523  else
1524  {
1525  return INT_STATUS_NOT_SUPPORTED;
1526  }
1527  }
1528  else if (CamiSectionHint & CAMI_SECTION_HINT_SYSCALLS)
1529  {
1530  status = IntCamiLoadSyscalls(pCami);
1531  }
1532  else if (CamiSectionHint & CAMI_SECTION_HINT_DIST_SIG)
1533  {
1534  if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1535  {
1536  status = IntCamiLoadLixDistSigs(pCami);
1537  }
1538  else
1539  {
1540  status = INT_STATUS_NOT_SUPPORTED;
1541  }
1542  }
1543  else if (CamiSectionHint & CAMI_SECTION_HINT_PROT_OPTIONS)
1544  {
1545  if (CamiSectionHint & CAMI_SECTION_HINT_WINDOWS)
1546  {
1547  status = IntCamiLoadProtOptionsWin(pCami);
1548  }
1549  else if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1550  {
1551  status = IntCamiLoadProtOptionsLinux(pCami);
1552  }
1553  }
1554 
1555  if (!INT_SUCCESS(status))
1556  {
1557  ERROR("[ERROR] Failed loading from hint 0x%08x: 0x%08x\n", CamiSectionHint, status);
1558  }
1559 
1560  return status;
1561 }
1562 
1563 
1564 INTSTATUS
1566  _In_ const BYTE *UpdateBuffer,
1567  _In_ DWORD BufferLength
1568  )
1577 {
1578  const CAMI_HEADER *pHeader;
1579 
1580  if (NULL == UpdateBuffer)
1581  {
1583  }
1584 
1585  if (0 == BufferLength)
1586  {
1588  }
1589 
1590  if (sizeof(*pHeader) > BufferLength)
1591  {
1592  ERROR("[ERROR] BufferLength is smaller than file header (%d vs %zu)\n", BufferLength, sizeof(*pHeader));
1594  }
1595 
1596  pHeader = (const CAMI_HEADER *)UpdateBuffer;
1597 
1598  if (pHeader->Magic != CAMI_MAGIC_WORD)
1599  {
1600  LOG("[ERROR] Invalid cami magic word! Expected 0x%x, got 0x%x\n", CAMI_MAGIC_WORD, pHeader->Magic);
1602  }
1603 
1604  if (BufferLength != pHeader->FileSize)
1605  {
1606  LOG("[ERROR] Buffer length is not equal with header file size. (%d vs %d)\n", BufferLength, pHeader->FileSize);
1608  }
1609 
1610  LOG("[INFO] Loaded cami version %u.%u build %u\n",
1611  pHeader->Version.Major, pHeader->Version.Minor, pHeader->Version.BuildNumber);
1612 
1613  memcpy(&gCamiVersion, &pHeader->Version, sizeof(pHeader->Version));
1614 
1615  if (gCamiVersion.Major != UPDATE_CAMI_MIN_VER_MAJOR)
1616  {
1617  ERROR("[ERROR] Update's file major (%d.%d) version is different form ours (%d.%d)\n",
1618  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1619 
1620  return INT_STATUS_NOT_SUPPORTED;
1621  }
1622 
1623  if (gCamiVersion.Minor > UPDATE_CAMI_MIN_VER_MINOR)
1624  {
1625  WARNING("[WARNING] Update's file minor (%d.%d) version is newer than ours (%d.%d). "
1626  "Not all features will be available!\n",
1627  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1628  }
1629  else if (gCamiVersion.Minor < UPDATE_CAMI_MIN_VER_MINOR)
1630  {
1631  ERROR("[ERROR] Update's file minor (%d.%d) version is older than ours (%d.%d). Will not load.\n",
1632  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1633 
1634  return INT_STATUS_NOT_SUPPORTED;
1635  }
1636 
1637  gUpdateBuffer = UpdateBuffer;
1638  gUpdateBufferSize = BufferLength;
1639 
1640  return INT_STATUS_SUCCESS;
1641 }
1642 
1643 
1644 void
1646  void
1647  )
1651 {
1652  INTSTATUS status;
1653 
1654  if (NULL == gUpdateBuffer)
1655  {
1656  ASSERT( gUpdateBufferSize == 0 );
1657  return;
1658  }
1659 
1660 #ifdef INT_COMPILER_GNUC
1661 # pragma GCC diagnostic push
1662 # pragma GCC diagnostic ignored "-Wcast-qual"
1663 #endif
1664 
1666 
1667 #ifdef INT_COMPILER_GNUC
1668 # pragma GCC diagnostic pop
1669 #endif
1670 
1671  if (!INT_SUCCESS(status))
1672  {
1673  WARNING("[WARNING] IntReleaseBuffer failed: 0x%08x\n", status);
1674  }
1675 
1676  gUpdateBuffer = NULL;
1677  gUpdateBufferSize = 0;
1678 }
1679 
1680 
1681 INTSTATUS
1683  _Out_ DWORD *MajorVersion,
1684  _Out_ DWORD *MinorVersion,
1685  _Out_ DWORD *BuildNumber
1686  )
1696 {
1697  if (NULL == MajorVersion)
1698  {
1700  }
1701 
1702  if (NULL == MinorVersion)
1703  {
1705  }
1706 
1707  if (NULL == BuildNumber)
1708  {
1710  }
1711 
1712  *MajorVersion = gCamiVersion.Major;
1713  *MinorVersion = gCamiVersion.Minor;
1714  *BuildNumber = gCamiVersion.BuildNumber;
1715 
1716  return INT_STATUS_SUCCESS;
1717 }
1718 
1719 
1720 INTSTATUS
1722  _In_ DWORD Items
1723  )
1731 {
1732  if (gCamiProcessProtectionData.Items != NULL)
1733  {
1734  ERROR("[ERROR] Cami protected processes array already allocated!");
1735  return INT_STATUS_NOT_SUPPORTED;
1736  }
1737 
1738  if (Items == 0)
1739  {
1741  }
1742 
1743  gCamiProcessProtectionData.Items = HpAllocWithTag(Items * sizeof(CAMI_PROCESS_PROTECTION_INFO), IC_TAG_CAMI);
1744  if (gCamiProcessProtectionData.Items == NULL)
1745  {
1747  }
1748 
1749  gCamiProcessProtectionData.Count = Items;
1750 
1751  return INT_STATUS_SUCCESS;
1752 }
1753 
1754 
1755 INTSTATUS
1757  void
1758  )
1762 {
1763  if (gCamiProcessProtectionData.Items == NULL)
1764  {
1765  return INT_STATUS_SUCCESS;
1766  }
1767 
1768  HpFreeAndNullWithTag(&gCamiProcessProtectionData.Items, IC_TAG_CAMI);
1769  gCamiProcessProtectionData.Items = NULL;
1770  gCamiProcessProtectionData.Count = 0;
1771 
1772  return INT_STATUS_SUCCESS;
1773 }
QWORD MaxIntroVersion
Maximum introcore version which supports this OS.
The end of the fields.
Definition: winguest.h:172
CAMI_STRING_ENCODING Encoding
Encoding of the name.
CHAR ServerVersionString[MAX_VERSION_STRING_SIZE]
The version string if the OS is a server.
LIX_OPAQUE_FIELDS OsSpecificFields
OS-dependent and specific information.
Definition: lixguest.h:576
Describes a Linux function used by the detour mechanism.
Definition: lixguest.h:49
static INTSTATUS IntCamiLoadProtOptionsWin(const CAMI_HEADER *CamiHeader)
Load and apply all of the enforced protection options for Windows guests.
INTSTATUS IntCamiUpdateProcessProtectionInfo(void *ProtectedProcess)
Update a process&#39; protection flags using the ones from CAMI.
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
Exposes the types, constants and functions used to handle Windows processes events (creation...
Describe process protection options.
Definition: update_guests.c:90
#define IC_TAG_CAMI
Live update allocations.
Definition: memtags.h:122
Used for the WIN_OPAQUE_FIELDS.Um.Peb array.
Definition: winguest.h:249
The tag for LIX_FIELD_MMSTRUCT.
Definition: lixguest.h:68
uint8_t BYTE
Definition: intro_types.h:47
DWORD CustomProtectionOffset
Protection flags for this OS. (pointer to a CAMI_CUSTOM_OS_PROTECTION struct)
#define OFFSET_OF(Type, Member)
Definition: introlists.h:33
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
Definition: winguest.c:35
DWORD SignatureId
The unique ID of the signature.
DWORD HookHandler
Used to identify the index of the LIX_FN_DETOUR the in the gLixHookHandlersx64.
Definition: lixguest.h:52
Describe the introcore protection options.
DWORD gLinuxDistSigsCount
Holds the number of loaded linux distribution signatures.
Definition: lixguest.c:36
#define _In_
Definition: intro_sal.h:21
The end of the fields.
Definition: winguest.h:453
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
BOOLEAN SkipOnBoot
Unused.
Definition: lixguest.h:53
INTSTATUS IntCamiSetUpdateBuffer(const BYTE *UpdateBuffer, DWORD BufferLength)
Initialize the update buffer with the one from the integrator.
DWORD CoreOptionsOffset
Intro core options. File pointer to a CAMI_PROT_OPTIONS structure.
uint16_t WORD
Definition: intro_types.h:48
Used for the WIN_OPAQUE_FIELDS.Um.Dll array.
Definition: winguest.h:248
WORD Pattern[SIG_MAX_PATTERN]
Definition: patsig.h:32
The end of the fields.
Definition: winguest.h:620
DWORD gSysenterSignaturesCount
Holds the number of loaded syscall signatures.
Definition: guests.c:79
static INTSTATUS IntCamiUpdateProcessProtectionInfoWin(PROTECTED_PROCESS_INFO *ProtectedProcess)
Update a windows process&#39; protection flags using the ones from CAMI.
CAMI_STRING_ENCODING
Describes the encoding of a string received from the CAMI file.
Definition: update_guests.h:52
Used for the WIN_OPAQUE_FIELDS.Km.VadLong array.
Definition: winguest.h:230
DWORD BuildNumber
Build number for this Windows OS.
WORD PatternLength
The length of the pattern. (count of DWORDs)
static const CAMI_STRUCTURE gLinuxStructures[lixStructureEnd]
Describe the Linux fields to be loaded from the update buffer.
The end of the fields.
Definition: winguest.h:430
struct _CAMI_PROCESS_PROTECTION_DATA * PCAMI_PROCESS_PROTECTION_DATA
The tag for LIX_FIELD_DENTRY.
Definition: lixguest.h:67
BYTE SkipOnBoot
TRUE if this function should not be hooked on boot.
QWORD MinIntroVersion
Minimum introcore version which supports this OS.
The end of tags.
Definition: lixguest.h:79
#define GET_CAMI_STRUCT(Type, Offset)
Get a CAMI structure from an update buffer.
Definition: update_guests.c:67
void IntCamiUpdateProcessProtectionItems(void *Name, CAMI_STRING_ENCODING Encoding, CAMI_PROT_OPTIONS *Options)
Update a protected process protection flags.
DWORD UmStructuresTable
UM opaque fields file pointer (pointer to a CAMI_OPAQUE_STRUCTURE array.
The end of tags.
Definition: lixguest.h:184
DWORD ProcOptionsCount
The number of entries in the ProcOptionsTable.
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
DWORD FunctionsCount
The number of function to be hooked.
Definition: lixguest.h:387
DWORD Minor
Minor version of this file.
Definition: update_guests.h:68
The end of tags.
Definition: lixguest.h:208
The end of the fields.
Definition: winguest.h:322
#define ARRAYSIZE(A)
Definition: introdefs.h:101
INTSTATUS IntCamiLoadSection(DWORD CamiSectionHint)
Load CAMI objects from section with given hint.
static INTSTATUS IntCamiLoadLinux(const CAMI_HEADER *CamiHeader)
Loads all of the necessary information about the current windows guest that is needed by intro to sup...
The end of tags.
Definition: lixguest.h:280
static INTSTATUS IntCamiLoadWindows(const CAMI_HEADER *CamiHeader)
Loads all of the necessary information about the current windows guest that is needed by intro to sup...
static INTSTATUS IntCamiLoadPatternSignatures(const CAMI_SECTION_HEADER *SectionHeader, PATTERN_SIGNATURE **PatternSignatures, DWORD *PatternSignaturesCount)
Allocate and load pattern signatures.
The tag for LIX_FIELD_FILES.
Definition: lixguest.h:72
DWORD Offset
Offset inside the tested buffer at which the pattern should be found.
Definition: patsig.h:27
Describe a CAMI file windows descriptor. Load support for a windows guest.
The end of tags.
Definition: lixguest.h:268
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
Section will contain linux related information.
Definition: update_guests.h:48
#define ERROR(fmt,...)
Definition: glue.h:62
static INTSTATUS IntCamiLoadSyscalls(const CAMI_HEADER *CamiHeader)
Loads the syscall signatures from their section.
Describe the introcore protection options for a process.
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
The end of tags.
Definition: lixguest.h:357
int INTSTATUS
The status data type.
Definition: introstatus.h:24
#define UPDATE_CAMI_MIN_VER_MAJOR
Definition: update_guests.h:62
The end of the fields.
Definition: winguest.h:189
The end of the fields.
Definition: winguest.h:295
DWORD OSVersion
Os version.
Definition: guests.h:277
Used for the WIN_OPAQUE_FIELDS.Km.Mmpfn array.
Definition: winguest.h:225
INT_VERSION_INFO IntHviVersion
The HVI version. Used to check for compatibility issues with the cami version.
Definition: introcore.c:27
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
void IntCamiClearUpdateBuffer(void)
Uninitialize the update buffer and notify the integrator that we don&#39;t need it anymore.
DWORD VersionStringOffset
VersionString pointer (pointer to a CAMI_WIN_VERSION_STRING struct)
Describe the CAMI version.
Definition: update_guests.h:66
Used for the WIN_OPAQUE_FIELDS.Km.VadFlags array.
Definition: winguest.h:231
Used for the WIN_OPAQUE_FIELDS.Km.EprocessFlags array.
Definition: winguest.h:228
Used for the WIN_OPAQUE_FIELDS.Km.Pcr array.
Definition: winguest.h:223
QWORD MinIntroVersion
Minimum introcore version which supports this OS.
DWORD StructureTag
Specifies which opaque field structure to load.
Definition: update_guests.c:76
BOOLEAN IntMatchPatternUtf8(const CHAR *Pattern, const CHAR *String, DWORD Flags)
Matches a pattern using glob match.
Definition: introcore.c:2454
The tag for LIX_FIELD_MODULE.
Definition: lixguest.h:64
#define IS_CAMI_STRUCTURE_OK(FilePointer)
Check whether a whole structure resides inside the update buffer.
Definition: update_guests.c:51
PCHAR ServerVersionString
A NULL terminated string containing Windows server version information.
Definition: winguest.h:817
size_t Offset
Offset of the structure to be loaded inside the OpaqueFields.
Definition: update_guests.c:83
static INTSTATUS IntCamiResetCoreOptions(void)
The tag for LIX_FIELD_SOCK.
Definition: lixguest.h:75
#define UPDATE_CAMI_MIN_VER_MINOR
Definition: update_guests.h:63
INTSTATUS IntCamiProtectedProcessAllocate(DWORD Items)
Initialize the global variable holding custom process protection options.
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:274
Describe a pattern signature.
QWORD Raw
Raw version information.
Definition: intro_types.h:2244
Encapsulates a protected Linux process.
Definition: lixguest.h:17
#define MIN(a, b)
Definition: introdefs.h:146
static INTSTATUS IntCamiUpdateProcessProtectionInfoLix(LIX_PROTECTED_PROCESS *ProtectedProcess)
Update a Linux process&#39; protection flags using the ones from CAMI.
WORD Build
Build number.
Definition: intro_types.h:2238
Describe a function to be hooked by introcore.
Section will contain information about a supported OS.
Definition: update_guests.h:42
Describe the CAMI file header.
Definition: update_guests.h:75
Used for the WIN_OPAQUE_FIELDS.Km.Token array.
Definition: winguest.h:226
Describe a CAMI file Linux descriptor. Load support for a Linux guest.
Definition: update_guests.h:98
#define LOG(fmt,...)
Definition: glue.h:61
Encapsulates a protected Windows process.
Definition: winguest.h:23
static CAMI_PROCESS_PROTECTION_DATA gCamiProcessProtectionData
Loaded process protection data from CAMI.
DWORD Offset
Offset inside the buffer.
The end of the fields.
Definition: winguest.h:525
The tag for LIX_FIELD_BINPRM.
Definition: lixguest.h:65
Describe a function to be hooked by introcore.
DWORD EntryCount
How many entries of this type are in the DescriptorTable.
Definition: update_guests.h:92
DWORD DescriptorTable
Pointer to a CAMI descriptor table.
Definition: update_guests.h:94
The end of the fields.
Definition: winguest.h:366
struct _CAMI_STRUCTURE CAMI_STRUCTURE
Describe the way we load the guest offsets from the update buffer.
static const CAMI_STRUCTURE gWinUmStructures[winUmStructureEnd]
Describe the windows um fields to be loaded from the update buffer.
DWORD Count
The number of elements in Items.
DWORD HooksTable
Hooked functions file pointer. (pointer to a CAMI_LIX_HOOK array).
The end of tags.
Definition: lixguest.h:134
DWORD Length
The valid size of the Pattern array.
Definition: patsig.h:25
QWORD ServerVersionStringSize
Size of the server version string, if exists.
The end of tags.
Definition: lixguest.h:152
Describe a CAMI file section header.
Definition: update_guests.h:89
#define _Inout_
Definition: intro_sal.h:20
BOOLEAN Is64
If this OS is 64 bits.
static INTSTATUS IntCamiLoadOpaqueFields(const CAMI_OPAQUE_STRUCTURE *CamiStructures, const CAMI_STRUCTURE *ToLoad, DWORD Count, INTRO_GUEST_TYPE OsType)
Load a set of opaque filed offsets from the update buffer.
#define _Out_opt_
Definition: intro_sal.h:30
QWORD VersionStringSize
Size of the version string.
DWORD BuildNumber
Build number.
Definition: update_guests.h:71
DWORD ShemuOptionsOffset
Shemu options. File pointer to a CAMI_PROT_OPTIONS structure.
DWORD ProcOptionsTable
Process protection options. Pointer to a CAMI_PROC_PROT_OPTIONS array.
DWORD FileSize
The size of the update file. Should be equal with the value of BufferSize.
Definition: update_guests.h:82
#define INT_STATUS_NOT_INITIALIZED
Definition: introstatus.h:266
BYTE HookHandler
The hook handler index from the API_HOOK_DESCRIPTOR.
Used for the WIN_OPAQUE_FIELDS.Km.Process array.
Definition: winguest.h:220
#define ASSERT(x)
Definition: introdefs.h:62
The end of the fields.
Definition: winguest.h:210
The tag for LIX_FIELD_NSPROXY.
Definition: lixguest.h:77
#define MAX_VERSION_STRING_SIZE
Maximum size of a version string.
Definition: update_guests.h:28
BOOLEAN IntMatchPatternUtf16(const WCHAR *Pattern, const WCHAR *String, DWORD Flags)
Matches a pattern using glob match.
Definition: introcore.c:2491
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:286
Describes a Linux guest.
Definition: lixguest.h:473
unsigned long long QWORD
Definition: intro_types.h:53
Section will contain protection flags.
Definition: update_guests.h:45
QWORD MaxIntroVersion
Maximum introcore version which supports this OS.
CHAR VersionString[MAX_VERSION_LENGTH]
The version string.
Definition: lixguest.h:489
#define TRUE
Definition: intro_types.h:30
#define INT_STATUS_INVALID_PARAMETER_4
Definition: introstatus.h:71
static INTSTATUS IntCamiSetCoreOptions(const CAMI_PROT_OPTIONS *Options)
Update the guest protection flags using the ones from CAMI.
#define IS_CAMI_ARRAY_OK(StartPointer, Count)
Check whether a whole array resides inside the update buffer.
Definition: update_guests.c:55
The end of the fields.
Definition: winguest.h:541
CHAR SectionHint[8]
Optional section name hint.
Definition: winguest.h:89
#define TRACE(fmt,...)
Definition: glue.h:58
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
struct _CAMI_PROCESS_PROTECTION_DATA CAMI_PROCESS_PROTECTION_DATA
Describe a list of process protection options.
The end of tags.
Definition: lixguest.h:170
The tag for LIX_FIELD_FS.
Definition: lixguest.h:70
#define INT_STATUS_INVALID_DATA_STATE
Definition: introstatus.h:183
The end of the fields.
Definition: winguest.h:603
The tag for LIX_FIELD_VMA.
Definition: lixguest.h:66
#define IS_CAMI_FILEOFFSET_OK(FileOffset)
Check whether a file offset overflows the update buffer.
Definition: update_guests.c:43
The end of tags.
Definition: lixguest.h:243
static const CAMI_SECTION_HEADER * IntCamiFindSectionHeaderByHint(const CAMI_HEADER *CamiHeader, DWORD SectionHint)
Iterate through all of the section headers from the update buffer and return the one matching the hin...
Used for the WIN_OPAQUE_FIELDS.Km.Thread array.
Definition: winguest.h:221
String will be encoded in utf-8.
Definition: update_guests.h:54
struct _CAMI_PROCESS_PROTECTION_INFO * PCAMI_PROCESS_PROTECTION_INFO
Exposes the definitions used by the CAMI parser and the functions used to load guest support informat...
size_t strlcpy(char *dst, const char *src, size_t dest_size)
Definition: introcrt.c:1093
QWORD ForceFeedback
Options feedback only.
void IntLixProcUpdateProtectedProcess(const void *Name, const CAMI_STRING_ENCODING Encoding, const CAMI_PROT_OPTIONS *Options)
Updates the protection flags for Linux tasks that should be protected based on options received via C...
Definition: lixprocess.c:1171
struct _CAMI_PROCESS_PROTECTION_INFO::@269 Name
The process name.
CAMI_VERSION Version
Version.
Definition: update_guests.h:79
DWORD PatternOffset
Pattern file pointer. (pointer to a DWORD array)
#define WARNING(fmt,...)
Definition: glue.h:60
PATTERN_SIGNATURE * gSysenterSignatures
Pointer to the syscall signatures that will be loaded from the update buffer.
Definition: guests.c:78
The end of the tags.
Definition: winguest.h:255
Describe windows version strings.
LIX_FUNCTION * Functions
An array of LIX_FUNCTION to be hooked.
Definition: lixguest.h:388
CHAR VersionString[MAX_VERSION_STRING_SIZE]
The versions string used to match this OS.
Describes a function that is not exported.
Definition: winguest.h:99
WCHAR Name16[32]
The process name as a wide char string.
Definition: update_guests.c:96
INTSTATUS IntReleaseBuffer(void *Buffer, DWORD Size)
Definition: glue.c:1083
The end of the fields.
Definition: winguest.h:383
The end of tags.
Definition: lixguest.h:308
INTRO_GUEST_TYPE
The type of the introspected operating system.
Definition: intro_types.h:1877
uint16_t WCHAR
Definition: intro_types.h:63
static INTSTATUS IntCamiSetProcProtOptions(const CAMI_PROC_PROT_OPTIONS *Table, DWORD TableCount)
Loads all the process protection flags from CAMI.
The tag for LIX_FIELD_INODE.
Definition: lixguest.h:73
uint32_t DWORD
Definition: intro_types.h:49
#define LIX_MAX_HOOKED_FN_COUNT
Definition: lixguest.h:40
Used for the WIN_OPAQUE_FIELDS.Km.DrvObj array.
Definition: winguest.h:222
The tag for LIX_FIELD_SOCKET.
Definition: lixguest.h:74
PCHAR VersionString
A NULL terminated string containing Windows version information.
Definition: winguest.h:813
void IntGuestUpdateShemuOptions(QWORD NewOptions)
Update shemu options.
Definition: guests.c:1395
Used for the WIN_OPAQUE_FIELDS.Km.Ungrouped array.
Definition: winguest.h:227
BOOLEAN glob_match_numeric_utf8(char const *Pattern, char const *String)
Definition: introcrt.c:766
The end of tags.
Definition: lixguest.h:256
Holds information about a Windows guest.
Definition: winguest.h:796
INTSTATUS IntCamiProtectedProcessFree(void)
Uninitialize the global holding custom process protection options.
void IntLixTaskUpdateProtection(void)
Adjusts protection for all active Linux processes.
Definition: lixprocess.c:4458
#define IC_TAG_NAME
Object name.
Definition: memtags.h:56
QWORD ForceOff
Options which will be disabled.
The end of the fields.
Definition: winguest.h:637
The end of the fields.
Definition: winguest.h:474
Used for the WIN_OPAQUE_FIELDS.Km.PoolDescriptor array.
Definition: winguest.h:224
The tag for LIX_FIELD_INFO.
Definition: lixguest.h:63
The end of tags.
Definition: lixguest.h:105
INTSTATUS IntCamiGetWinSupportedList(BOOLEAN KptiInstalled, BOOLEAN Guest64, DWORD *NtBuildNumberList, DWORD *Count)
Return a list of supported Windows NtBuildNumbers.
void IntWinProcUpdateProtectedProcess(const void *Name, const CAMI_STRING_ENCODING Encoding, const CAMI_PROT_OPTIONS *Options)
This function updates the protection for the given process.
Definition: winprocess.c:3481
Describe the members of a guest opaque structure.
PATTERN_SIGNATURE Signature
The pattern signature.
Definition: winguest.h:91
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:48
INTSTATUS IntWinProcUpdateProtection(void)
Iterates trough the global process list (gWinProcesses) in order to update the protection state for e...
Definition: winprocess.c:1155
Used for the WIN_OPAQUE_FIELDS.Km.VadShort array.
Definition: winguest.h:229
static INTSTATUS IntCamiLoadProtOptionsLinux(const CAMI_HEADER *CamiHeader)
Load and apply all of the enforced protection options for Linux guests.
Describe a function pattern.
The end of the fields.
Definition: winguest.h:411
#define INT_STATUS_INVALID_DATA_TYPE
Definition: introstatus.h:139
CHAR VersionString[MAX_VERSION_STRING_SIZE]
The version string.
DWORD PatternsCount
The number of entries in the Patterns array.
Definition: winguest.h:105
CAMI_PROCESS_PROTECTION_INFO * Items
Array of process protection options.
INTSTATUS IntWinApiUpdateHookDescriptor(WIN_UNEXPORTED_FUNCTION *Function, DWORD ArgumentsCount, const DWORD *Arguments)
Update a hook descriptor with corresponding function patterns and argument list from CAMI...
Definition: winapi.c:595
static void IntCamiUpdateProtOptions(const CAMI_PROT_OPTIONS *Src, INTRO_PROT_OPTIONS *Dst)
Updates the current protection options.
Introspection version info.
Definition: intro_types.h:2233
static const BYTE * gUpdateBuffer
The buffer holding the update file.
Definition: update_guests.c:21
The end of the tags.
Definition: winguest.h:238
Section will contain windows related information.
Definition: update_guests.h:47
DWORD Magic
Magic value. Should be CAMI_MAGIC_WORD.
Definition: update_guests.h:77
DWORD NameHash
Crc32 of the function name.
Definition: lixguest.h:51
INTRO_PROT_OPTIONS ShemuOptions
Flags which describe the way shemu will give detections.
Definition: guests.h:268
The end of tags.
Definition: lixguest.h:328
DWORD NameHash
Crc32 checksum of the function name.
Definition: winguest.h:102
DWORD NameHash
Function name hash.
static CAMI_VERSION gCamiVersion
The version of the loaded update file.
Definition: update_guests.c:18
#define SIG_MAX_PATTERN
The maximum size of a pattern.
Definition: patsig.h:11
BOOLEAN KptiInstalled
True if KPTI was detected as installed (not necessarily active).
Definition: guests.h:288
QWORD Original
The original options as received from GLUE_IFACE.NewGuestNotification. This is updated when GLUE_IFAC...
Definition: guests.h:227
BOOLEAN Kpti
If this OS has KPTI support.
#define CAMI_MAGIC_WORD
Cami header magic number.
Definition: update_guests.h:34
The tag for LIX_FIELD_FDTABLE.
Definition: lixguest.h:71
DWORD StructuresTable
Opaque structures file pointer. (pointer to a CAMI_OPAQUE_STRUCTURE array).
static BOOLEAN IntCamiCheckIntroVersion(QWORD MinIntroVersion, QWORD MaxIntroVersion)
Check if the CAMI buffer is compatible with the Intro version.
Describe a list of process protection options.
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
#define INT_STATUS_NOT_SUPPORTED
Definition: introstatus.h:287
static const CAMI_STRUCTURE gWinKmStructures[winKmStructureEnd]
Describe the windows km fields to be loaded from the update buffer.
DWORD FunctionTable
Functions file pointer. (pointer to a CAMI_WIN_FUNCTION array.
struct _CAMI_PROCESS_PROTECTION_INFO CAMI_PROCESS_PROTECTION_INFO
Describe process protection options.
The end of tags.
Definition: lixguest.h:341
void IntGuestUpdateCoreOptions(QWORD NewOptions)
Updates Introcore options.
Definition: guests.c:1424
static INTSTATUS IntCamiSetShemuOptions(const CAMI_PROT_OPTIONS *Options)
Update the shemu flags using the ones from CAMI.
Describes a signature that can be used for searching or matching guest contents.
Definition: patsig.h:23
#define INT_STATUS_INVALID_PARAMETER_MIX
Definition: introstatus.h:98
The end of the fields.
Definition: winguest.h:350
The end of tags.
Definition: lixguest.h:294
Describes options for this guest.
Definition: guests.h:223
INTSTATUS IntCamiGetVersion(DWORD *MajorVersion, DWORD *MinorVersion, DWORD *BuildNumber)
Get the version of the loaded CAMI support file.
CHAR Name8[64]
The process name as a char string.
Definition: update_guests.c:97
BYTE SectionHint[8]
Section hint where this pattern should be found.
static INTSTATUS IntCamiLoadOsOptions(DWORD OptionsFileOffset)
Load custom protection options for the guest OS or for protected processes.
Section will contain distribution signatures.
Definition: update_guests.h:44
Describe the introcore protection options for a guest.
char CHAR
Definition: intro_types.h:56
DWORD Major
Major version of this file.
Definition: update_guests.h:69
DWORD SignatureId
Signature ID.
Definition: patsig.h:26
PATTERN_SIGNATURE * gLinuxDistSigs
Pointer to the linux distribution signatures that will be loaded from the update buffer.
Definition: lixguest.c:34
#define WORD_MAX
Definition: introtypes.h:32
The tag for LIX_FIELD_UNGROUPED.
Definition: lixguest.h:78
CAMI_PROT_OPTIONS Options
Specifies the process protection.
String will be encoded in utf-16.
Definition: update_guests.h:55
static DWORD gUpdateBufferSize
The size of the update buffer.
Definition: update_guests.c:24
Used for the WIN_OPAQUE_FIELDS.Km.SyscallNumbers array.
Definition: winguest.h:232
Section will contain syscall signatures.
Definition: update_guests.h:43
The tag for LIX_FIELD_CRED.
Definition: lixguest.h:76
static INTSTATUS IntCamiResetShemuOptions(void)
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:267
Describe the way we load the guest offsets from the update buffer.
Definition: update_guests.c:70
DWORD MembersCount
The number of fields to be loaded.
Definition: update_guests.c:86
DWORD NameHash
Function name hash.
QWORD ForceBeta
Options beta only.
The tag for LIX_FIELD_TASKSTRUCT.
Definition: lixguest.h:69
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
Definition: lixguest.c:29
WIN_UNEXPORTED_FUNCTION_PATTERN Patterns[0]
The patterns used to search for this function.
Definition: winguest.h:107
DWORD CustomProtectionOffset
Protection flags for this OS. (pointer to a CAMI_CUSTOM_OS_PROTECTION).
#define INT_STATUS_INVALID_DATA_SIZE
Definition: introstatus.h:142
The end of tags.
Definition: lixguest.h:375
static INTSTATUS IntCamiLoadLixDistSigs(const CAMI_HEADER *CamiHeader)
Loads the Linux distribution signatures from their section.
struct _INT_VERSION_INFO::@327 VersionInfo
Structured version information.
#define FALSE
Definition: intro_types.h:34
DWORD KmStructuresTable
KM opaque fields file pointer. (pointer to a CAMI_OPAQUE_STRUCTURE array.
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68