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 "introdefs.h"
13 #include "introstatus.h"
14 #include "winapi.h"
15 #include "guests.h"
16 #include "winprocess.h"
17 #include "lixprocess.h"
18 #include "introcrt.h"
19 
21 static CAMI_VERSION gCamiVersion = { 0 };
22 
24 static const BYTE *gUpdateBuffer = NULL;
25 
28 
31 
34 
37 
40 
43 
44 
46 #define IS_CAMI_FILEOFFSET_OK(FileOffset) __likely((FileOffset) < gUpdateBufferSize)
47 
49 #define IS_CAMI_FILEPOINTER_OK(FilePointer) __likely((const BYTE*)(FilePointer) >= (const BYTE*)gUpdateBuffer) && \
50  ((const BYTE*)(FilePointer) < (const BYTE*)gUpdateBuffer + \
51  gUpdateBufferSize)
52 
54 #define IS_CAMI_STRUCTURE_OK(FilePointer) __likely(IS_CAMI_FILEPOINTER_OK(FilePointer) && \
55  IS_CAMI_FILEPOINTER_OK(((const BYTE*)((FilePointer) + 1) - 1)))
56 
58 #define IS_CAMI_ARRAY_OK(StartPointer, Count) __likely(IS_CAMI_FILEPOINTER_OK(StartPointer) && \
59  ((Count) < CAMI_MAX_ENTRY_COUNT) && \
60  (((DWORD)(Count) == 0) || \
61  (IS_CAMI_FILEPOINTER_OK((const BYTE*)((StartPointer) + \
62  (DWORD)(Count)) - 1))))
63 
70 #define GET_CAMI_STRUCT(Type, Offset) ((Type)(const void *)((const BYTE*)gUpdateBuffer + (DWORD)(Offset)))
71 
73 typedef struct _CAMI_STRUCTURE
74 {
80 
86  size_t Offset;
87 
91 
94 {
95  struct
96  {
97  union
98  {
99  WCHAR Name16[32];
100  CHAR Name8[64];
101  };
102 
104  } Name;
105 
108 
111 {
115 
116 
119 
122 {
124  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Info),
125  .MembersCount = lixFieldInfoEnd},
126 
127  {.StructureTag = lixStructureModule,
128  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Module),
129  .MembersCount = lixFieldModuleEnd},
130 
131  {.StructureTag = lixStructureBinprm,
132  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Binprm),
133  .MembersCount = lixFieldBinprmEnd},
134 
135  {.StructureTag = lixStructureVma,
136  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Vma),
137  .MembersCount = lixFieldVmaEnd},
138 
139  {.StructureTag = lixStructureDentry,
140  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Dentry),
141  .MembersCount = lixFieldDentryEnd},
142 
143  {.StructureTag = lixStructureMmStruct,
144  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.MmStruct),
145  .MembersCount = lixFieldMmStructEnd},
146 
147  {.StructureTag = lixStructureTaskStruct,
148  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.TaskStruct),
149  .MembersCount = lixFieldTaskStructEnd},
150 
151  {.StructureTag = lixStructureFs,
152  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Fs),
153  .MembersCount = lixFieldFsEnd},
154 
155  {.StructureTag = lixStructureFdTable,
156  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.FdTable),
157  .MembersCount = lixFieldFdTableEnd},
158 
159  {.StructureTag = lixStructureFiles,
160  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Files),
161  .MembersCount = lixFieldFilesEnd},
162 
163  {.StructureTag = lixStructureInode,
164  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Inode),
165  .MembersCount = lixFieldInodeEnd},
166 
167  {.StructureTag = lixStructureSocket,
168  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Socket),
169  .MembersCount = lixFieldSocketEnd},
170 
171  {.StructureTag = lixStructureSock,
172  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Sock),
173  .MembersCount = lixFieldSockEnd},
174 
175  {.StructureTag = lixStructureCred,
176  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Cred),
177  .MembersCount = lixFieldCredEnd},
178 
179  {.StructureTag = lixStructureNsProxy,
180  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.NsProxy),
181  .MembersCount = lixFieldNsProxyEnd},
182 
183  {.StructureTag = lixStructureUngrouped,
184  .Offset = OFFSET_OF(LINUX_GUEST, OsSpecificFields.OpaqueFields.Ungrouped),
185  .MembersCount = lixFieldUngroupedEnd},
186 };
187 
190 {
192  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Process),
193  .MembersCount = winKmFieldProcessEnd},
194 
195  {.StructureTag = winKmStructureThread,
196  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Thread),
197  .MembersCount = winKmFieldThreadEnd},
198 
199  {.StructureTag = winKmStructureDrvObj,
200  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.DrvObj),
201  .MembersCount = winKmFieldDrvObjEnd},
202 
203  {.StructureTag = winKmStructurePcr,
204  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Pcr),
205  .MembersCount = winKmFieldPcrEnd},
206 
207  {.StructureTag = winKmStructurePoolDescriptor,
208  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.PoolDescriptor),
209  .MembersCount = winKmFieldPoolDescriptorEnd},
210 
211  {.StructureTag = winKmStructureMmpfn,
212  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Mmpfn),
213  .MembersCount = winKmFieldMmpfnEnd},
214 
215  {.StructureTag = winKmStructureToken,
216  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Token),
217  .MembersCount = winKmFieldTokenEnd},
218 
219  {.StructureTag = winKmStructureUngrouped,
220  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.Ungrouped),
221  .MembersCount = winKmFieldUngroupedEnd},
222 
223  {.StructureTag = winKmStructureEprocessFlags,
224  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.EprocessFlags),
225  .MembersCount = winKmFieldEprocessFlagsEnd},
226 
227  {.StructureTag = winKmStructureVadShort,
228  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadShort),
229  .MembersCount = winKmFieldVadShortEnd},
230 
231  {.StructureTag = winKmStructureVadLong,
232  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadLong),
233  .MembersCount = winKmFieldVadLongEnd},
234 
235  {.StructureTag = winKmStructureVadFlags,
236  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.VadFlags),
237  .MembersCount = winKmFieldVadFlagsEnd},
238 
239  {.StructureTag = winKmStructureSyscallNumbers,
240  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.SyscallNumbers),
241  .MembersCount = winKmFieldSyscallNumbersEnd},
242 
243  {.StructureTag = winKmStructureFileObject,
244  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Km.FileObject),
245  .MembersCount = winKmFieldFileObjectEnd},
246 };
247 
250 {
252  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Dll),
253  .MembersCount = winUmFieldDllEnd },
254 
255  {.StructureTag = winUmStructurePeb,
256  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Peb),
257  .MembersCount = winUmFieldPebEnd },
258 
259  {.StructureTag = winUmStructureTeb,
260  .Offset = OFFSET_OF(WINDOWS_GUEST, OsSpecificFields.Um.Teb),
261  .MembersCount = winUmFieldTebEnd },
262 };
263 
264 
265 static BOOLEAN
267  _In_ QWORD MinIntroVersion,
268  _In_ QWORD MaxIntroVersion
269  )
275 {
276  INT_VERSION_INFO minVer, maxVer;
277 
278  minVer.Raw = MinIntroVersion;
279  maxVer.Raw = MaxIntroVersion;
280 
281  // Make sure we don't compare build numbers.
282  minVer.VersionInfo.Build = 0;
283  maxVer.VersionInfo.Build = WORD_MAX;
284 
285  return IntHviVersion.Raw >= minVer.Raw && IntHviVersion.Raw <= maxVer.Raw;
286 }
287 
288 
289 static const CAMI_SECTION_HEADER *
291  _In_ const CAMI_HEADER *CamiHeader,
292  _In_ DWORD SectionHint
293  )
303 {
304  const CAMI_SECTION_HEADER *pHeaders;
305 
306  pHeaders = GET_CAMI_STRUCT(const CAMI_SECTION_HEADER *, CamiHeader->PointerToSectionsHeaders);
307  if (!IS_CAMI_ARRAY_OK(pHeaders, CamiHeader->NumberOfSections))
308  {
309  ERROR("[ERROR] Sections table entries are outside the update buffer!\n");
310  return NULL;
311  }
312 
313  for (DWORD i = 0; i < CamiHeader->NumberOfSections; i++)
314  {
315  if ((pHeaders[i].Hint & SectionHint) == SectionHint)
316  {
317  return (pHeaders + i);
318  }
319  }
320 
321  return NULL;
322 }
323 
324 
325 static INTSTATUS
327  _In_ const CAMI_OPAQUE_STRUCTURE *CamiStructures,
328  _In_ const CAMI_STRUCTURE *ToLoad,
329  _In_ DWORD Count,
330  _In_ INTRO_GUEST_TYPE OsType
331  )
346 {
347  char *pBasePtr = NULL;
348 
349  switch (OsType)
350  {
351  case introGuestLinux:
352  pBasePtr = (char *)gLixGuest;
353  break;
354 
355  case introGuestWindows:
356  pBasePtr = (char *)gWinGuest;
357  break;
358 
359  default:
361  }
362 
363  for (DWORD iStruct = 0; iStruct < Count; iStruct++)
364  {
365  const DWORD *pFields;
366 
367  if (CamiStructures->MembersCount < ToLoad->MembersCount)
368  {
369  ERROR("[ERROR] For structure %d we need at least %d fields, got only %d\n",
370  iStruct, ToLoad->MembersCount, CamiStructures->MembersCount);
372  }
373 
374  pFields = GET_CAMI_STRUCT(const DWORD *, CamiStructures->Members);
375  if (!IS_CAMI_ARRAY_OK(pFields, CamiStructures->MembersCount))
376  {
377  ERROR("[ERROR] Members for structure %d are outside the update buffer!\n", iStruct);
379  }
380 
381  memcpy(pBasePtr + ToLoad->Offset, pFields, sizeof(DWORD) * ToLoad->MembersCount);
382 
383  CamiStructures++;
384  ToLoad++;
385  }
386 
387  return INT_STATUS_SUCCESS;
388 
389 }
390 
391 
392 static INTSTATUS
394  _In_ const CAMI_SECTION_HEADER *SectionHeader,
395  _Out_ PATTERN_SIGNATURE **PatternSignatures,
396  _Out_ DWORD *PatternSignaturesCount
397  )
407 {
408  const CAMI_PATTERN_SIGNATURE *pCamiSignatures;
409 
410  pCamiSignatures = GET_CAMI_STRUCT(const CAMI_PATTERN_SIGNATURE *, SectionHeader->DescriptorTable);
411  if (!IS_CAMI_ARRAY_OK(pCamiSignatures, SectionHeader->EntryCount))
412  {
413  LOG("[ERROR] Pattern signature descriptors are outside the update buffer!");
415  }
416 
417  if (SectionHeader->EntryCount == 0)
418  {
419  ERROR("[ERROR] Invalid entry count for the pattern signature array: %u\n", SectionHeader->EntryCount);
421  }
422 
423  *PatternSignatures = HpAllocWithTag(sizeof(PATTERN_SIGNATURE) * SectionHeader->EntryCount, IC_TAG_CAMI);
424  if (NULL == *PatternSignatures)
425  {
427  }
428 
429  *PatternSignaturesCount = 0;
430 
431  for (DWORD i = 0; i < SectionHeader->EntryCount; i++)
432  {
433  const CAMI_PATTERN_SIGNATURE *pCamiPat;
434  PPATTERN_SIGNATURE pPat;
435  const WORD *pPatternHash;
436 
437  pCamiPat = pCamiSignatures + i;
438  pPat = *PatternSignatures + i;
439 
440  pPatternHash = GET_CAMI_STRUCT(const WORD *, pCamiPat->PatternOffset);
441  if (!IS_CAMI_ARRAY_OK(pPatternHash, pCamiPat->PatternLength))
442  {
443  ERROR("[ERROR] Hash for signature %d is outside the update buffer!\n", i);
444 
445  HpFreeAndNullWithTag(PatternSignatures, IC_TAG_CAMI);
447  }
448 
449  pPat->SignatureId = pCamiPat->SignatureId;
450  pPat->Offset = pCamiPat->Offset;
451  pPat->Length = MIN(pCamiPat->PatternLength, ARRAYSIZE(pPat->Pattern));
452 
453  memcpy(pPat->Pattern, pPatternHash, pPat->Length * sizeof(pPat->Pattern[0]));
454  }
455 
456  *PatternSignaturesCount = SectionHeader->EntryCount;
457 
458  return INT_STATUS_SUCCESS;
459 }
460 
461 
462 static INTSTATUS
464  _In_ const CAMI_HEADER *CamiHeader
465  )
473 {
474  const CAMI_SECTION_HEADER *pSec;
475 
477  if (NULL == pSec)
478  {
479  ERROR("[ERROR] Failed to find syscalls section header\n");
480  return INT_STATUS_NOT_FOUND;
481  }
482 
483  return IntCamiLoadPatternSignatures(pSec, &gSysenterSignatures, &gSysenterSignaturesCount);
484 }
485 
486 
487 static INTSTATUS
489  _In_ const CAMI_HEADER *CamiHeader
490  )
498 {
499  const CAMI_SECTION_HEADER *pSec;
500 
502  if (NULL == pSec)
503  {
504  ERROR("[ERROR] Failed to find syscalls section header\n");
505  return INT_STATUS_NOT_FOUND;
506  }
507 
508  return IntCamiLoadPatternSignatures(pSec, &gLinuxDistSigs, &gLinuxDistSigsCount);
509 }
510 
511 
512 static void
514  _In_ const CAMI_PROT_OPTIONS *Src,
516  )
523 {
524  if (Dst->ForceOff != Src->ForceOff)
525  {
526  LOG("[CAMI] New force off options: 0x%016llx\n", Src->ForceOff);
527  }
528 
529  Dst->ForceOff = Src->ForceOff;
530 
531  if (Dst->Beta != Src->ForceBeta)
532  {
533  LOG("[CAMI] New force beta options: 0x%016llx\n", Src->ForceBeta);
534  }
535 
536  Dst->Beta = Src->ForceBeta;
537 
538  if (Dst->Feedback != Src->ForceFeedback)
539  {
540  LOG("[CAMI] New force feedback options: 0x%016llx\n", Src->ForceFeedback);
541  }
542 
543  Dst->Feedback = Src->ForceFeedback;
544 }
545 
546 
547 static INTSTATUS
549  _In_ const CAMI_PROT_OPTIONS *Options
550  )
558 {
559  LOG("[CAMI] Will set new core options!\n");
560 
562 
564 
565  return INT_STATUS_SUCCESS;
566 }
567 
568 
569 static INTSTATUS
571  _In_ const CAMI_PROT_OPTIONS *Options
572  )
580 {
581  LOG("[CAMI] Will set new shemu options!\n");
582 
584 
586 
587  return INT_STATUS_SUCCESS;
588 }
589 
590 
591 static INTSTATUS
593  _In_ LIX_PROTECTED_PROCESS *ProtectedProcess
594  )
602 {
603  for (DWORD index = 0; index < gCamiProcessProtectionData.Count; index++)
604  {
605  BOOLEAN match = FALSE;
606  if (gCamiProcessProtectionData.Items[index].Name.Encoding != CAMI_STRING_ENCODING_UTF8)
607  {
608  WARNING("[WARNING] Unsupported process name encoding: %d. Will skip...\n",
609  gCamiProcessProtectionData.Items[index].Name.Encoding);
610  }
611  else
612  {
613  if (IntMatchPatternUtf8(gCamiProcessProtectionData.Items[index].Name.Name8,
614  ProtectedProcess->CommPattern,
615  0))
616  {
617  match = TRUE;
618  }
619  }
620 
621  if (match)
622  {
623  ProtectedProcess->Protection.Current =
624  ProtectedProcess->Protection.Original & ~(gCamiProcessProtectionData.Items[index].Options.ForceOff);
625  ProtectedProcess->Protection.Beta = gCamiProcessProtectionData.Items[index].Options.ForceBeta;
626  ProtectedProcess->Protection.Feedback = gCamiProcessProtectionData.Items[index].Options.ForceFeedback;
627 
628  TRACE("[CAMI] Protection options for '%s': %llx %llx %llx", ProtectedProcess->CommPattern,
629  ProtectedProcess->Protection.Current, ProtectedProcess->Protection.Beta,
630  ProtectedProcess->Protection.Feedback);
631  }
632  }
633 
634  return INT_STATUS_SUCCESS;
635 }
636 
637 
638 static INTSTATUS
640  _In_ PROTECTED_PROCESS_INFO *ProtectedProcess
641  )
649 {
650  for (DWORD index = 0; index < gCamiProcessProtectionData.Count; index++)
651  {
652  BOOLEAN match = FALSE;
653  switch (gCamiProcessProtectionData.Items[index].Name.Encoding)
654  {
656  {
657  if (IntMatchPatternUtf16(gCamiProcessProtectionData.Items[index].Name.Name16,
658  ProtectedProcess->FullNamePattern,
659  0))
660  {
661  match = TRUE;
662  }
663  break;
664  }
666  {
667  if (IntMatchPatternUtf8(gCamiProcessProtectionData.Items[index].Name.Name8,
668  ProtectedProcess->ImageBaseNamePattern,
669  0))
670  {
671  match = TRUE;
672  }
673  break;
674  }
675  default:
676  {
677  WARNING("[WARNING] Unsupported process name encoding: %d. Will skip...\n",
678  gCamiProcessProtectionData.Items[index].Name.Encoding);
679  }
680  }
681 
682  if (match)
683  {
684  ProtectedProcess->Protection.Current =
685  ProtectedProcess->Protection.Original & ~(gCamiProcessProtectionData.Items[index].Options.ForceOff);
686  ProtectedProcess->Protection.Beta = gCamiProcessProtectionData.Items[index].Options.ForceBeta;
687  ProtectedProcess->Protection.Feedback = gCamiProcessProtectionData.Items[index].Options.ForceFeedback;
688 
689  TRACE("[CAMI] Protection options for '%s': %x %llx %llx", ProtectedProcess->ImageBaseNamePattern,
690  ProtectedProcess->Protection.Current, ProtectedProcess->Protection.Beta,
691  ProtectedProcess->Protection.Feedback);
692 
693  }
694  }
695 
696  return INT_STATUS_SUCCESS;
697 }
698 
699 
700 INTSTATUS
702  _In_ void *ProtectedProcess
703  )
713 {
715  {
716  return IntCamiUpdateProcessProtectionInfoWin(ProtectedProcess);
717  }
718  else if (gGuest.OSType == introGuestLinux)
719  {
720  return IntCamiUpdateProcessProtectionInfoLix(ProtectedProcess);
721  }
722 
724 }
725 
726 
727 void
729  _In_ void *Name,
730  _In_ CAMI_STRING_ENCODING Encoding,
731  _In_ CAMI_PROT_OPTIONS *Options
732  )
740 {
742  {
743  IntWinProcUpdateProtectedProcess(Name, Encoding, Options);
744  }
745  else if (gGuest.OSType == introGuestLinux)
746  {
747  IntLixProcUpdateProtectedProcess(Name, Encoding, Options);
748  }
749 }
750 
751 
752 static INTSTATUS
754  _In_ const CAMI_PROC_PROT_OPTIONS *Table,
755  _In_ DWORD TableCount
756  )
765 {
766  for (DWORD index = 0; index < TableCount; index++)
767  {
768  const CAMI_PROT_OPTIONS *pOptions = GET_CAMI_STRUCT(const CAMI_PROT_OPTIONS *, Table[index].OptionsOffset);
769  if (!IS_CAMI_STRUCTURE_OK(pOptions))
770  {
771  ERROR("[ERROR] CAMI_PROT_OPTIONS struct is invalid! (%p)", pOptions);
773  }
774 
775  memcpy(gCamiProcessProtectionData.Items[index].Name.Name8, Table[index].Name8, 64);
776  gCamiProcessProtectionData.Items[index].Name.Encoding = Table[index].Encoding;
777  gCamiProcessProtectionData.Items[index].Options = *pOptions;
778 
779  TRACE("[CAMI] NameHash : %s -> ForceOff : 0x%llx, ForceBeta: 0x%llx, ForceFeedback: 0x%llx",
780  Table[index].Name8, pOptions->ForceOff, pOptions->ForceBeta, pOptions->ForceFeedback);
781 
782  IntCamiUpdateProcessProtectionItems(gCamiProcessProtectionData.Items[index].Name.Name8,
783  gCamiProcessProtectionData.Items[index].Name.Encoding,
784  &gCamiProcessProtectionData.Items[index].Options);
785  }
786 
788  {
790  }
791  else if (gGuest.OSType == introGuestLinux)
792  {
794  }
795  else
796  {
798  }
799 
800  return INT_STATUS_SUCCESS;
801 }
802 
803 
804 static INTSTATUS
806  void
807  )
813 {
814  const CAMI_PROT_OPTIONS defaultOpts = {0};
815 
816  return IntCamiSetCoreOptions(&defaultOpts);
817 }
818 
819 
820 static INTSTATUS
822  void
823  )
829 {
830  const CAMI_PROT_OPTIONS defaultOpts = {0};
831 
832  return IntCamiSetShemuOptions(&defaultOpts);
833 }
834 
835 
836 static INTSTATUS
838  _In_ DWORD OptionsFileOffset
839  )
847 {
848  INTSTATUS status;
849  const CAMI_CUSTOM_OS_PROTECTION *pOsProt;
850  const CAMI_PROT_OPTIONS *pCoreProtOpt, *pShemuProtOpt;
851 
852  if (0 == OptionsFileOffset)
853  {
855 
858 
859  return INT_STATUS_SUCCESS;
860  }
861 
862  pOsProt = GET_CAMI_STRUCT(const CAMI_CUSTOM_OS_PROTECTION *, OptionsFileOffset);
863  if (!IS_CAMI_STRUCTURE_OK(pOsProt))
864  {
865  ERROR("[ERROR] Invalid file offset: %d / %d\n", OptionsFileOffset, gUpdateBufferSize);
867  }
868 
869  pCoreProtOpt = GET_CAMI_STRUCT(const CAMI_PROT_OPTIONS *, pOsProt->CoreOptionsOffset);
870  if (!IS_CAMI_STRUCTURE_OK(pCoreProtOpt))
871  {
872  ERROR("[ERROR] Invalid file offset: %d / %d\n", pOsProt->CoreOptionsOffset, gUpdateBufferSize);
874  }
875 
876  pShemuProtOpt = GET_CAMI_STRUCT(const CAMI_PROT_OPTIONS *, pOsProt->ShemuOptionsOffset);
877  if (!IS_CAMI_STRUCTURE_OK(pShemuProtOpt))
878  {
879  ERROR("[ERROR] Invalid file offset: %d / %d\n", pOsProt->ShemuOptionsOffset, gUpdateBufferSize);
881  }
882 
884 
885  if (pOsProt->ProcOptionsCount > 0)
886  {
888  pOsProt->ProcOptionsTable);
889  if (!IS_CAMI_ARRAY_OK(pProcProt, pOsProt->ProcOptionsCount))
890  {
891  ERROR("[ERROR] Invalid ProcOptionsTable : 0x%0x / %08x.\n", pOsProt->ProcOptionsTable, gUpdateBufferSize);
893  }
894 
896  if (!INT_SUCCESS(status))
897  {
898  ERROR("[ERROR] IntCamiProtectedProcessAllocate failed with status: 0x%08x.", status);
899  return status;
900  }
901 
902  status = IntCamiSetProcProtOptions(pProcProt, pOsProt->ProcOptionsCount);
903  if (!INT_SUCCESS(status))
904  {
905  ERROR("[ERROR] IntCamiSetProcProtOptions failed with status: 0x%08x.\n", status);
906  return status;
907  }
908  }
909 
910  status = IntCamiSetCoreOptions(pCoreProtOpt);
911  if (!INT_SUCCESS(status))
912  {
913  ERROR("[ERROR] IntCamiSetCoreOptions failed with status: 0x%08x.\n", status);
914  return status;
915  }
916 
917  status = IntCamiSetShemuOptions(pShemuProtOpt);
918  if (!INT_SUCCESS(status))
919  {
920  ERROR("[ERROR] IntCamiSetShemuOptions failed with status: 0x%08x.\n", status);
921  return status;
922  }
923 
924  return INT_STATUS_SUCCESS;
925 }
926 
927 
928 static INTSTATUS
930  _In_ const CAMI_HEADER *CamiHeader
931  )
945 {
946  const CAMI_SECTION_HEADER *pSec;
947  const CAMI_LIX_DESCRIPTOR *pLixOsList;
948  INTSTATUS status;
949 
951  if (NULL == pSec)
952  {
953  ERROR("[ERROR] Failed to find Linux section header\n");
954  return INT_STATUS_NOT_FOUND;
955  }
956 
957  pLixOsList = GET_CAMI_STRUCT(const CAMI_LIX_DESCRIPTOR *, pSec->DescriptorTable);
958  if (!IS_CAMI_ARRAY_OK(pLixOsList, pSec->EntryCount))
959  {
960  ERROR("[ERROR] Linux supported OS descriptors are outside the update buffer!");
962  }
963 
964  for (DWORD i = 0; i < pSec->EntryCount; i++)
965  {
966  const CAMI_LIX_DESCRIPTOR *pLix;
967  const CAMI_LIX_HOOK *pHooks;
968  const CAMI_OPAQUE_STRUCTURE *pStructures;
969 
970  pLix = pLixOsList + i;
971 
973  {
974  ERROR("[ERROR] Version string is not null terminated.");
976  }
977 
979  {
980  continue;
981  }
982 
984  {
985  LOG("[WARNING] This OS is no longer supported by introcore!\n");
986  continue;
987  }
988 
989  if (lixStructureEnd > pLix->StructuresCount)
990  {
991  ERROR("[ERROR] Expected %d fields, got %d.", lixStructureEnd, pLix->StructuresCount);
993  }
994 
995  if (pLix->HooksCount > LIX_MAX_HOOKED_FN_COUNT || pLix->HooksCount == 0)
996  {
997  ERROR("[ERROR] Unsupported number of hooks! Got %d, expected a max of %d!\n",
1000  }
1001 
1002  pStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pLix->StructuresTable);
1003  if (!IS_CAMI_ARRAY_OK(pStructures, pLix->StructuresCount))
1004  {
1005  ERROR("[ERROR] Fields for OS %s are outside the update buffer.", pLix->VersionString);
1007  }
1008 
1009  pHooks = GET_CAMI_STRUCT(const CAMI_LIX_HOOK *, pLix->HooksTable);
1010  if (!IS_CAMI_ARRAY_OK(pHooks, pLix->HooksCount))
1011  {
1012  ERROR("[ERROR] Hooks for OS %s are outside the update buffer.", pLix->VersionString);
1014  }
1015 
1017  if (!INT_SUCCESS(status))
1018  {
1019  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1020  // Shall we bail out?
1021  }
1022 
1023  status = IntCamiLoadOpaqueFields(pStructures, gLinuxStructures, lixStructureEnd, introGuestLinux);
1024  if (!INT_SUCCESS(status))
1025  {
1026  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for linux fields. Status: 0x%08x\n", status);
1027  return status;
1028  }
1029 
1031 
1034 
1035  if (NULL == gLixGuest->OsSpecificFields.Functions)
1036  {
1038  }
1039 
1040  for (DWORD j = 0; j < pLix->HooksCount; j++)
1041  {
1043 
1044  pFun->NameHash = pHooks[j].NameHash;
1045  pFun->SkipOnBoot = pHooks[j].SkipOnBoot;
1046  pFun->HookHandler = pHooks[j].HookHandler;
1047  }
1048 
1050 
1051  return INT_STATUS_SUCCESS;
1052  }
1053 
1054  return INT_STATUS_NOT_SUPPORTED;
1055 }
1056 
1057 
1058 static INTSTATUS
1060  _In_ const CAMI_HEADER *CamiHeader
1061  )
1076 {
1077  const CAMI_SECTION_HEADER *pSec;
1078  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1079  INTSTATUS status;
1080 
1082  if (NULL == pSec)
1083  {
1084  ERROR("[ERROR] Failed to find Windows section header\n");
1085  return INT_STATUS_NOT_FOUND;
1086  }
1087 
1088  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1089  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1090  {
1091  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1093  }
1094 
1095  for (DWORD i = 0; i < pSec->EntryCount; i++)
1096  {
1097  const CAMI_WIN_DESCRIPTOR *pWin;
1098  const CAMI_OPAQUE_STRUCTURE *pKmStructures, *pUmStructures;
1099  const CAMI_WIN_FUNCTION *pFunTable;
1100  const CAMI_WIN_VERSION_STRING *pCamiVersionString;
1101 
1102  pWin = pWinOsList + i;
1103 
1104  if (gGuest.OSVersion != pWin->BuildNumber ||
1105  gGuest.Guest64 != pWin->Is64 ||
1106  gGuest.KptiInstalled != pWin->Kpti)
1107  {
1108  continue;
1109  }
1110 
1112  {
1113  LOG("[WARNING] This OS is no longer supported by introcore!\n");
1114  continue;
1115  }
1116 
1117  pFunTable = GET_CAMI_STRUCT(const CAMI_WIN_FUNCTION *, pWin->FunctionTable);
1118  if (!IS_CAMI_ARRAY_OK(pFunTable, pWin->FunctionCount))
1119  {
1120  ERROR("[ERROR] Functions for OS %d KPTI %d is64 %d are outside the update buffer. ",
1121  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1123  }
1124 
1125  pKmStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pWin->KmStructuresTable);
1126  if (!IS_CAMI_ARRAY_OK(pKmStructures, pWin->KmStructuresCount))
1127  {
1128  ERROR("[ERROR] Km Structures for OS %d KPTI %d is64 %d are outside the update buffer. \n",
1129  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1131  }
1132 
1133  pCamiVersionString = GET_CAMI_STRUCT(const CAMI_WIN_VERSION_STRING *, pWin->VersionStringOffset);
1134  if (!IS_CAMI_STRUCTURE_OK(pCamiVersionString))
1135  {
1136  ERROR("[ERROR] CAMI_WIN_VERSION_STRING struct is invalid! (%p)", pCamiVersionString);
1138  }
1139 
1140  if (pCamiVersionString->VersionStringSize > MAX_VERSION_STRING_SIZE ||
1141  pCamiVersionString->VersionStringSize == 0)
1142  {
1143  ERROR("[ERROR] VersionString size is too big (%llx)\n", pCamiVersionString->VersionStringSize);
1145  }
1146 
1148  if (NULL == gWinGuest->VersionString)
1149  {
1151  }
1152 
1153  strlcpy(gWinGuest->VersionString, pCamiVersionString->VersionString, pCamiVersionString->VersionStringSize);
1154 
1155  if (pCamiVersionString->ServerVersionStringSize > MAX_VERSION_STRING_SIZE ||
1156  pCamiVersionString->ServerVersionStringSize == 0)
1157  {
1158  ERROR("[ERROR] VersionString size is too big (%llx)\n", pCamiVersionString->ServerVersionStringSize);
1160  }
1161 
1163  if (NULL == gWinGuest->ServerVersionString)
1164  {
1166  }
1167 
1169  pCamiVersionString->ServerVersionStringSize);
1170 
1171  pUmStructures = GET_CAMI_STRUCT(const CAMI_OPAQUE_STRUCTURE *, pWin->UmStructuresTable);
1172  if (!IS_CAMI_ARRAY_OK(pUmStructures, pWin->UmStructuresCount))
1173  {
1174  ERROR("[ERROR] Um Structures for OS %d KPTI %d is64 %d are outside the update buffer. \n",
1175  pWin->BuildNumber, pWin->Kpti, pWin->Is64);
1177  }
1178 
1180  {
1181  ERROR("[ERROR] Expected %d structures, got %d.", winKmStructureEnd, pWin->KmStructuresCount);
1182  return INT_STATUS_NOT_SUPPORTED;
1183  }
1184 
1186  {
1187  ERROR("[ERROR] Expected %d structures, got %d.", winUmStructureEnd, pWin->UmStructuresCount);
1188  return INT_STATUS_NOT_SUPPORTED;
1189  }
1190 
1192  if (!INT_SUCCESS(status))
1193  {
1194  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1195  // Shall we bail out?
1196  }
1197 
1198  status = IntCamiLoadOpaqueFields(pKmStructures, gWinKmStructures, winKmStructureEnd, introGuestWindows);
1199  if (!INT_SUCCESS(status))
1200  {
1201  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for win km structures: 0x%08x\n", status);
1202  return status;
1203  }
1204 
1205  status = IntCamiLoadOpaqueFields(pUmStructures, gWinUmStructures, winUmStructureEnd, introGuestWindows);
1206  if (!INT_SUCCESS(status))
1207  {
1208  ERROR("[ERROR] IntCamiLoadOpaqueFields failed for win um structures: 0x%08x\n", status);
1209  return status;
1210  }
1211 
1212  for (DWORD j = 0; j < pWin->FunctionCount; j++)
1213  {
1215  const CAMI_WIN_FUNCTION_PATTERN *pPatterns;
1216  const DWORD *pArgs;
1217 
1218  pPatterns = GET_CAMI_STRUCT(const CAMI_WIN_FUNCTION_PATTERN *, pFunTable[j].PatternsTable);
1219  if (!IS_CAMI_ARRAY_OK(pPatterns, pFunTable[j].PatternsCount))
1220  {
1221  ERROR("[ERROR] Function %d has patterns outside the update buffer. \n", j);
1223  }
1224 
1225  pArgs = GET_CAMI_STRUCT(const DWORD *, pFunTable[j].ArgumentsTable);
1226  if (!IS_CAMI_ARRAY_OK(pArgs, pFunTable[j].ArgumentsCount))
1227  {
1228  ERROR("[ERROR] Function %d has arguments outside the update buffer. Will skip!\n", j);
1229  continue;
1230  }
1231 
1232  pWf = HpAllocWithTag(sizeof(*pWf) + pFunTable[j].PatternsCount * sizeof(pWf->Patterns[0]), IC_TAG_CAMI);
1233  if (NULL == pWf)
1234  {
1235  // Bail out if we ran out of memory, we won't be able to
1236  // load the rest anyway and we'll basically be useless
1237  // without function hooks...
1239  }
1240 
1241  for (DWORD k = 0; k < pFunTable[j].PatternsCount; k++)
1242  {
1243  const WORD *pPatHash;
1244 
1245  pPatHash = GET_CAMI_STRUCT(const WORD *, pPatterns[k].HashOffset);
1246  if (!IS_CAMI_ARRAY_OK(pPatHash, pPatterns[k].HashLength))
1247  {
1248  ERROR("[ERROR] Hash for pattern %d of function 0x%x spills outside the update buffer. Will skip!",
1249  k, pFunTable[j].NameHash);
1250 
1252  goto _free_on_err;
1253  }
1254 
1255  if (pPatterns[k].Extended != 0)
1256  {
1258  const DWORD *pArgs2;
1259 
1260  pPatEx = GET_CAMI_STRUCT(const CAMI_WIN_FUNCTION_PATTERN_EXTENSION*, pPatterns[k].Extended);
1261  if (!IS_CAMI_STRUCTURE_OK(pPatEx))
1262  {
1263  ERROR("[ERROR] Extension for pattern %d (function 0x%x) spills outside the update buffer.\n",
1264  k, pFunTable[j].NameHash);
1265 
1267  goto _free_on_err;
1268  }
1269 
1270  pArgs2 = GET_CAMI_STRUCT(const DWORD *, pPatEx->ArgumentsTable);
1271  if (!IS_CAMI_ARRAY_OK(pArgs2, pPatEx->ArgumentsCount))
1272  {
1273  ERROR("[ERROR] Arguments array for pattern %d (function 0x%x) are outside the update buffer\n",
1274  k, pFunTable[j].NameHash);
1275 
1277  goto _free_on_err;
1278  }
1279 
1280  if (pPatEx->ArgumentsCount > ARRAYSIZE(pWf->Patterns[k].Arguments.Argv))
1281  {
1282  ERROR("[ERROR] Too many arguments for pattern %d (function 0x%x)\n",
1283  k, pFunTable[j].NameHash);
1284 
1286  goto _free_on_err;
1287  }
1288 
1289  pWf->Patterns[k].Arguments.Argc = pPatEx->ArgumentsCount;
1290  memcpy(pWf->Patterns[k].Arguments.Argv,
1291  pArgs2,
1292  sizeof(pWf->Patterns[k].Arguments.Argv[0]) * pPatEx->ArgumentsCount);
1293  }
1294 
1295  memcpy(pWf->Patterns[k].SectionHint, pPatterns[k].SectionHint, 8);
1296 
1297  pWf->Patterns[k].Signature.Length = MIN(SIG_MAX_PATTERN, pPatterns[k].HashLength);
1298  memcpy(pWf->Patterns[k].Signature.Pattern, pPatHash, 2ull * pWf->Patterns[k].Signature.Length);
1299  }
1300 
1301  status = INT_STATUS_SUCCESS;
1302 
1303 _free_on_err:
1304 
1305  if (!INT_SUCCESS(status))
1306  {
1307  if (pWf != NULL)
1308  {
1310  }
1311 
1312  return status;
1313  }
1314 
1315  pWf->NameHash = pFunTable[j].NameHash;
1316  pWf->PatternsCount = pFunTable[j].PatternsCount;
1317 
1318  status = IntWinApiUpdateHookDescriptor(pWf, pFunTable[j].ArgumentsCount, pArgs);
1319  if (!INT_SUCCESS(status))
1320  {
1321  WARNING("[WARNING] Failed to add function %d %x to a hook descriptor: 0x%08x\n",
1322  j, pFunTable[j].NameHash, status);
1324  }
1325  }
1326 
1327  return INT_STATUS_SUCCESS;
1328  }
1329 
1330  return INT_STATUS_NOT_SUPPORTED;
1331 }
1332 
1333 
1334 static INTSTATUS
1336  _In_ const CAMI_HEADER *CamiHeader
1337  )
1347 {
1348  const CAMI_SECTION_HEADER *pSec;
1349  const CAMI_LIX_DESCRIPTOR *pLixOsList;
1350  INTSTATUS status;
1351 
1353  if (NULL == pSec)
1354  {
1355  ERROR("[ERROR] Failed to find Linux section header\n");
1356  return INT_STATUS_NOT_FOUND;
1357  }
1358 
1359  pLixOsList = GET_CAMI_STRUCT(const CAMI_LIX_DESCRIPTOR *, pSec->DescriptorTable);
1360  if (!IS_CAMI_ARRAY_OK(pLixOsList, pSec->EntryCount))
1361  {
1362  ERROR("[ERROR] Linux supported OS descriptors are outside the update buffer!");
1364  }
1365 
1366  for (DWORD i = 0; i < pSec->EntryCount; i++)
1367  {
1368  const CAMI_LIX_DESCRIPTOR *pLix = pLixOsList + i;
1369 
1371  {
1372  ERROR("[ERROR] Version string is not null terminated.");
1374  }
1375 
1377  {
1378  continue;
1379  }
1380 
1382  {
1383  continue;
1384  }
1385 
1386  if (lixStructureEnd > pLix->StructuresCount)
1387  {
1388  ERROR("[ERROR] Expected %d fields, got %d.", lixStructureEnd, pLix->StructuresCount);
1389  return INT_STATUS_NOT_SUPPORTED;
1390  }
1391 
1393  if (!INT_SUCCESS(status))
1394  {
1395  ERROR("[ERROR] Failed to load introcore options for this OS. Status: 0x%08x\n", status);
1396  }
1397 
1398  return status;
1399  }
1400 
1402 }
1403 
1404 
1405 static INTSTATUS
1407  _In_ const CAMI_HEADER *CamiHeader
1408  )
1418 {
1419  const CAMI_SECTION_HEADER *pSec;
1420  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1421  INTSTATUS status;
1422 
1424  if (NULL == pSec)
1425  {
1426  ERROR("[ERROR] Failed to find windows section header\n");
1427  return INT_STATUS_NOT_FOUND;
1428  }
1429 
1430  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1431  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1432  {
1433  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1435  }
1436 
1437  for (DWORD i = 0; i < pSec->EntryCount; i++)
1438  {
1439  const CAMI_WIN_DESCRIPTOR *pWin = pWinOsList + i;
1440 
1441  if ((gGuest.OSVersion != pWin->BuildNumber) ||
1442  (gGuest.Guest64 != pWin->Is64) ||
1443  (gGuest.KptiInstalled != pWin->Kpti))
1444  {
1445  continue;
1446  }
1447 
1449  {
1450  continue;
1451  }
1452 
1454  if (!INT_SUCCESS(status))
1455  {
1456  ERROR("[ERROR] Failed to load introcore options for this OS: 0x%08x\n", status);
1457  }
1458 
1459  return status;
1460  }
1461 
1463 }
1464 
1465 
1466 INTSTATUS
1468  _In_ BOOLEAN KptiInstalled,
1469  _In_ BOOLEAN Guest64,
1470  _Out_opt_ DWORD *NtBuildNumberList,
1471  _Inout_ DWORD *Count
1472  )
1492 {
1493  const CAMI_SECTION_HEADER *pSec;
1494  const CAMI_WIN_DESCRIPTOR *pWinOsList;
1495  const CAMI_WIN_DESCRIPTOR *pWin;
1496  DWORD i, lastNt, cnt;
1497 
1498  if (NULL == Count)
1499  {
1501  }
1502 
1503  if (NULL != NtBuildNumberList && 0 == *Count)
1504  {
1506  }
1507 
1508  if (NULL == gUpdateBuffer || 0 == gUpdateBufferSize)
1509  {
1511  }
1512 
1515  if (NULL == pSec)
1516  {
1517  ERROR("[ERROR] Failed to find windows section header\n");
1518  return INT_STATUS_NOT_FOUND;
1519  }
1520 
1521  pWinOsList = GET_CAMI_STRUCT(const CAMI_WIN_DESCRIPTOR *, pSec->DescriptorTable);
1522  if (!IS_CAMI_ARRAY_OK(pWinOsList, pSec->EntryCount))
1523  {
1524  ERROR("[ERROR] Windows supported OS descriptors are outside the update buffer!");
1526  }
1527 
1528  lastNt = cnt = 0;
1529  // the OS list from CAMI is sorted by NtBuildNumber, so it's fine.
1530  for (i = 0; i < pSec->EntryCount; i++)
1531  {
1532  pWin = pWinOsList + i;
1533 
1535  Guest64 != pWin->Is64 || KptiInstalled != pWin->Kpti)
1536  {
1537  continue;
1538  }
1539 
1540  if (pWin->BuildNumber != lastNt)
1541  {
1542  lastNt = pWin->BuildNumber;
1543 
1544  if (NULL != NtBuildNumberList)
1545  {
1546  if (cnt >= *Count)
1547  {
1548  return INT_STATUS_SUCCESS;
1549  }
1550 
1551  NtBuildNumberList[cnt] = lastNt;
1552  }
1553 
1554  cnt++;
1555  }
1556  }
1557 
1558  *Count = cnt;
1559 
1560  return INT_STATUS_SUCCESS;
1561 }
1562 
1563 
1564 INTSTATUS
1566  _In_ DWORD CamiSectionHint
1567  )
1575 {
1576  INTSTATUS status;
1577  const CAMI_HEADER *pCami;
1578 
1579  if (NULL == gUpdateBuffer || 0 == gUpdateBufferSize)
1580  {
1582  }
1583 
1584  pCami = (const CAMI_HEADER *)gUpdateBuffer;
1585 
1586  status = INT_STATUS_NOT_FOUND;
1587  if (CamiSectionHint & CAMI_SECTION_HINT_SUPPORTED_OS)
1588  {
1589  if (CamiSectionHint & CAMI_SECTION_HINT_WINDOWS)
1590  {
1591  status = IntCamiLoadWindows(pCami);
1592  }
1593  else if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1594  {
1595  status = IntCamiLoadLinux(pCami);
1596  }
1597  else
1598  {
1599  return INT_STATUS_NOT_SUPPORTED;
1600  }
1601  }
1602  else if (CamiSectionHint & CAMI_SECTION_HINT_SYSCALLS)
1603  {
1604  status = IntCamiLoadSyscalls(pCami);
1605  }
1606  else if (CamiSectionHint & CAMI_SECTION_HINT_DIST_SIG)
1607  {
1608  if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1609  {
1610  status = IntCamiLoadLixDistSigs(pCami);
1611  }
1612  else
1613  {
1614  status = INT_STATUS_NOT_SUPPORTED;
1615  }
1616  }
1617  else if (CamiSectionHint & CAMI_SECTION_HINT_PROT_OPTIONS)
1618  {
1619  if (CamiSectionHint & CAMI_SECTION_HINT_WINDOWS)
1620  {
1621  status = IntCamiLoadProtOptionsWin(pCami);
1622  }
1623  else if (CamiSectionHint & CAMI_SECTION_HINT_LINUX)
1624  {
1625  status = IntCamiLoadProtOptionsLinux(pCami);
1626  }
1627  }
1628 
1629  if (!INT_SUCCESS(status))
1630  {
1631  ERROR("[ERROR] Failed loading from hint 0x%08x: 0x%08x\n", CamiSectionHint, status);
1632  }
1633 
1634  return status;
1635 }
1636 
1637 
1638 INTSTATUS
1640  _In_ const BYTE *UpdateBuffer,
1641  _In_ DWORD BufferLength
1642  )
1651 {
1652  const CAMI_HEADER *pHeader;
1653 
1654  if (NULL == UpdateBuffer)
1655  {
1657  }
1658 
1659  if (0 == BufferLength)
1660  {
1662  }
1663 
1664  if (sizeof(*pHeader) > BufferLength)
1665  {
1666  ERROR("[ERROR] BufferLength is smaller than file header (%d vs %zu)\n", BufferLength, sizeof(*pHeader));
1668  }
1669 
1670  pHeader = (const CAMI_HEADER *)UpdateBuffer;
1671 
1672  if (pHeader->Magic != CAMI_MAGIC_WORD)
1673  {
1674  LOG("[ERROR] Invalid cami magic word! Expected 0x%x, got 0x%x\n", CAMI_MAGIC_WORD, pHeader->Magic);
1676  }
1677 
1678  if (BufferLength != pHeader->FileSize)
1679  {
1680  LOG("[ERROR] Buffer length is not equal with header file size. (%d vs %d)\n", BufferLength, pHeader->FileSize);
1682  }
1683 
1684  LOG("[INFO] Loaded cami version %u.%u build %u\n",
1685  pHeader->Version.Major, pHeader->Version.Minor, pHeader->Version.BuildNumber);
1686 
1687  memcpy(&gCamiVersion, &pHeader->Version, sizeof(pHeader->Version));
1688 
1689  if (gCamiVersion.Major != UPDATE_CAMI_MIN_VER_MAJOR)
1690  {
1691  ERROR("[ERROR] Update's file major (%d.%d) version is different form ours (%d.%d)\n",
1692  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1693 
1694  return INT_STATUS_NOT_SUPPORTED;
1695  }
1696 
1697  if (gCamiVersion.Minor > UPDATE_CAMI_MIN_VER_MINOR)
1698  {
1699  WARNING("[WARNING] Update's file minor (%d.%d) version is newer than ours (%d.%d). "
1700  "Not all features will be available!\n",
1701  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1702  }
1703  else if (gCamiVersion.Minor < UPDATE_CAMI_MIN_VER_MINOR)
1704  {
1705  ERROR("[ERROR] Update's file minor (%d.%d) version is older than ours (%d.%d). Will not load.\n",
1706  gCamiVersion.Major, gCamiVersion.Minor, UPDATE_CAMI_MIN_VER_MAJOR, UPDATE_CAMI_MIN_VER_MINOR);
1707 
1708  return INT_STATUS_NOT_SUPPORTED;
1709  }
1710 
1711  gUpdateBuffer = UpdateBuffer;
1712  gUpdateBufferSize = BufferLength;
1713 
1714  return INT_STATUS_SUCCESS;
1715 }
1716 
1717 
1718 void
1720  void
1721  )
1725 {
1726  INTSTATUS status;
1727 
1728  if (NULL == gUpdateBuffer)
1729  {
1730  ASSERT( gUpdateBufferSize == 0 );
1731  return;
1732  }
1733 
1734 #ifdef INT_COMPILER_GNUC
1735 # pragma GCC diagnostic push
1736 # pragma GCC diagnostic ignored "-Wcast-qual"
1737 #endif
1738 
1740 
1741 #ifdef INT_COMPILER_GNUC
1742 # pragma GCC diagnostic pop
1743 #endif
1744 
1745  if (!INT_SUCCESS(status))
1746  {
1747  WARNING("[WARNING] IntReleaseBuffer failed: 0x%08x\n", status);
1748  }
1749 
1750  gUpdateBuffer = NULL;
1751  gUpdateBufferSize = 0;
1752 }
1753 
1754 
1755 INTSTATUS
1757  _Out_ DWORD *MajorVersion,
1758  _Out_ DWORD *MinorVersion,
1759  _Out_ DWORD *BuildNumber
1760  )
1770 {
1771  if (NULL == MajorVersion)
1772  {
1774  }
1775 
1776  if (NULL == MinorVersion)
1777  {
1779  }
1780 
1781  if (NULL == BuildNumber)
1782  {
1784  }
1785 
1786  *MajorVersion = gCamiVersion.Major;
1787  *MinorVersion = gCamiVersion.Minor;
1788  *BuildNumber = gCamiVersion.BuildNumber;
1789 
1790  return INT_STATUS_SUCCESS;
1791 }
1792 
1793 
1794 INTSTATUS
1796  _In_ DWORD Items
1797  )
1805 {
1806  if (gCamiProcessProtectionData.Items != NULL)
1807  {
1808  ERROR("[ERROR] Cami protected processes array already allocated!");
1809  return INT_STATUS_NOT_SUPPORTED;
1810  }
1811 
1812  if (Items == 0)
1813  {
1815  }
1816 
1817  gCamiProcessProtectionData.Items = HpAllocWithTag(Items * sizeof(CAMI_PROCESS_PROTECTION_INFO), IC_TAG_CAMI);
1818  if (gCamiProcessProtectionData.Items == NULL)
1819  {
1821  }
1822 
1823  gCamiProcessProtectionData.Count = Items;
1824 
1825  return INT_STATUS_SUCCESS;
1826 }
1827 
1828 
1829 INTSTATUS
1831  void
1832  )
1836 {
1837  if (gCamiProcessProtectionData.Items == NULL)
1838  {
1839  return INT_STATUS_SUCCESS;
1840  }
1841 
1842  HpFreeAndNullWithTag(&gCamiProcessProtectionData.Items, IC_TAG_CAMI);
1843  gCamiProcessProtectionData.Items = NULL;
1844  gCamiProcessProtectionData.Count = 0;
1845 
1846  return INT_STATUS_SUCCESS;
1847 }
QWORD MaxIntroVersion
Maximum introcore version which supports this OS.
The end of the fields.
Definition: winguest.h:174
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:579
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:93
#define IC_TAG_CAMI
Live update allocations.
Definition: memtags.h:124
Used for the WIN_OPAQUE_FIELDS.Um.Peb array.
Definition: winguest.h:251
The tag for LIX_FIELD_MMSTRUCT.
Definition: lixguest.h:68
DWORD Argc
The number of valid entries inside the Argv array.
Definition: detours.h:110
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:37
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:37
#define _In_
Definition: intro_sal.h:21
The end of the fields.
Definition: winguest.h:466
#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:250
WORD Pattern[SIG_MAX_PATTERN]
Definition: patsig.h:32
The end of the fields.
Definition: winguest.h:634
DWORD gSysenterSignaturesCount
Holds the number of loaded syscall signatures.
Definition: guests.c:81
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:232
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:436
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:70
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:187
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:390
DWORD Minor
Minor version of this file.
Definition: update_guests.h:68
The end of tags.
Definition: lixguest.h:211
The end of the fields.
Definition: winguest.h:326
#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:283
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:271
#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:360
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:191
The end of the fields.
Definition: winguest.h:298
DWORD OSVersion
Os version.
Definition: guests.h:281
Used for the WIN_OPAQUE_FIELDS.Km.Mmpfn array.
Definition: winguest.h:227
INT_VERSION_INFO IntHviVersion
The HVI version. Used to check for compatibility issues with the cami version.
Definition: introcore.c:27
DWORD ArgumentsCount
Arguments count.
#define INT_STATUS_CORRUPTED_DATA
Definition: introstatus.h:156
#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:233
Used for the WIN_OPAQUE_FIELDS.Km.EprocessFlags array.
Definition: winguest.h:230
Used for the WIN_OPAQUE_FIELDS.Km.Pcr array.
Definition: winguest.h:225
QWORD MinIntroVersion
Minimum introcore version which supports this OS.
DWORD StructureTag
Specifies which opaque field structure to load.
Definition: update_guests.c:79
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:54
PCHAR ServerVersionString
A NULL terminated string containing Windows server version information.
Definition: winguest.h:831
size_t Offset
Offset of the structure to be loaded inside the OpaqueFields.
Definition: update_guests.c:86
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:278
Describe a pattern signature.
QWORD Raw
Raw version information.
Definition: intro_types.h:2407
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:2401
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:228
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:24
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:539
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:372
Describe the arguments for a function.
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:136
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:154
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:222
#define ASSERT(x)
Definition: introdefs.h:62
The end of the fields.
Definition: winguest.h:212
The tag for LIX_FIELD_NSPROXY.
Definition: lixguest.h:77
DWORD Argv[DET_ARGS_MAX]
Argument encoding. See DET_ARG_REGS and DET_ARG_ON_STACK.
Definition: detours.h:111
#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:290
Describes a Linux guest.
Definition: lixguest.h:476
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:492
#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.
DWORD ArgumentsTable
Arguments file offset. (pointer to a DWORD array)
#define IS_CAMI_ARRAY_OK(StartPointer, Count)
Check whether a whole array resides inside the update buffer.
Definition: update_guests.c:58
The end of the fields.
Definition: winguest.h:555
CHAR SectionHint[8]
Optional section name hint.
Definition: winguest.h:90
#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:172
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:617
The tag for LIX_FIELD_VMA.
Definition: lixguest.h:66
The end of tags.
Definition: lixguest.h:246
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:223
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:1173
CAMI_VERSION Version
Version.
Definition: update_guests.h:79
DWORD PatternOffset
Pattern file pointer. (pointer to a DWORD array)
struct _INT_VERSION_INFO::@339 VersionInfo
Structured version information.
#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:80
The end of the tags.
Definition: winguest.h:257
Describe windows version strings.
LIX_FUNCTION * Functions
An array of LIX_FUNCTION to be hooked.
Definition: lixguest.h:391
CHAR VersionString[MAX_VERSION_STRING_SIZE]
The versions string used to match this OS.
Describes a function that is not exported.
Definition: winguest.h:101
WCHAR Name16[32]
The process name as a wide char string.
Definition: update_guests.c:99
INTSTATUS IntReleaseBuffer(void *Buffer, DWORD Size)
Definition: glue.c:1083
The end of the fields.
Definition: winguest.h:389
The end of tags.
Definition: lixguest.h:311
INTRO_GUEST_TYPE
The type of the introspected operating system.
Definition: intro_types.h:2040
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:224
The tag for LIX_FIELD_SOCKET.
Definition: lixguest.h:74
PCHAR VersionString
A NULL terminated string containing Windows version information.
Definition: winguest.h:827
void IntGuestUpdateShemuOptions(QWORD NewOptions)
Update shemu options.
Definition: guests.c:1397
Used for the WIN_OPAQUE_FIELDS.Km.Ungrouped array.
Definition: winguest.h:229
BOOLEAN glob_match_numeric_utf8(char const *Pattern, char const *String)
Definition: introcrt.c:766
The end of tags.
Definition: lixguest.h:259
Holds information about a Windows guest.
Definition: winguest.h:810
INTSTATUS IntCamiProtectedProcessFree(void)
Uninitialize the global holding custom process protection options.
void IntLixTaskUpdateProtection(void)
Adjusts protection for all active Linux processes.
Definition: lixprocess.c:4495
#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:651
The end of the fields.
Definition: winguest.h:488
Used for the WIN_OPAQUE_FIELDS.Km.PoolDescriptor array.
Definition: winguest.h:226
The tag for LIX_FIELD_INFO.
Definition: lixguest.h:63
The end of tags.
Definition: lixguest.h:107
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:3657
Describe the members of a guest opaque structure.
PATTERN_SIGNATURE Signature
The pattern signature.
Definition: winguest.h:92
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
INTSTATUS IntWinProcUpdateProtection(void)
Iterates trough the global process list (gWinProcesses) in order to update the protection state for e...
Definition: winprocess.c:1162
Used for the WIN_OPAQUE_FIELDS.Km.VadShort array.
Definition: winguest.h:231
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:417
#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:107
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:615
static void IntCamiUpdateProtOptions(const CAMI_PROT_OPTIONS *Src, INTRO_PROT_OPTIONS *Dst)
Updates the current protection options.
Introspection version info.
Definition: intro_types.h:2396
static const BYTE * gUpdateBuffer
The buffer holding the update file.
Definition: update_guests.c:24
The end of the tags.
Definition: winguest.h:240
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:272
The end of tags.
Definition: lixguest.h:331
DWORD NameHash
Crc32 checksum of the function name.
Definition: winguest.h:104
DWORD NameHash
Function name hash.
static CAMI_VERSION gCamiVersion
The version of the loaded update file.
Definition: update_guests.c:21
#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:292
QWORD Original
The original options as received from GLUE_IFACE.NewGuestNotification. This is updated when GLUE_IFAC...
Definition: guests.h:231
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:344
void IntGuestUpdateCoreOptions(QWORD NewOptions)
Updates Introcore options.
Definition: guests.c:1426
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:354
The end of tags.
Definition: lixguest.h:297
Describes options for this guest.
Definition: guests.h:227
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.
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
struct _CAMI_PROCESS_PROTECTION_INFO::@276 Name
The process name.
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:35
#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:27
Used for the WIN_OPAQUE_FIELDS.Km.SyscallNumbers array.
Definition: winguest.h:234
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:271
Describe the way we load the guest offsets from the update buffer.
Definition: update_guests.c:73
DWORD MembersCount
The number of fields to be loaded.
Definition: update_guests.c:89
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:30
WIN_UNEXPORTED_FUNCTION_PATTERN Patterns[0]
The patterns used to search for this function.
Definition: winguest.h:109
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:378
static INTSTATUS IntCamiLoadLixDistSigs(const CAMI_HEADER *CamiHeader)
Loads the Linux distribution signatures from their section.
Status values returned by most functions that can signal different success or failure states...
#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