Bitdefender Hypervisor Memory Introspection
debugger.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "debugger.h"
6 #include "codeblocks.h"
7 #include "decoder.h"
8 #include "deployer.h"
9 #include "gpacache.h"
10 #include "hook.h"
11 #include "hook_cr.h"
12 #include "icache.h"
13 #include "introapi.h"
14 #include "kernvm.h"
15 #include "memcloak.h"
16 #include "ptfilter.h"
17 #include "swapmem.h"
18 #include "vasmonitor.h"
19 #include "vecore.h"
20 #include "visibility.h"
21 #include "winnet.h"
22 #include "winpe.h"
23 #include "winpfn.h"
24 #include "winprocesshp.h"
25 #include "lixksym.h"
26 
29 
31 extern BOOLEAN gLoadPtDriver;
35 
36 
38  _In_ DWORD Argc,
39  _In_ const char *Argv[]
40  );
41 
43  void
44  );
45 
46 
47 static INTSTATUS
49  _In_ void *Context,
50  _In_ QWORD Cr3,
51  _In_ QWORD VirtualAddress,
52  _In_ QWORD PhysicalAddress,
53  _In_reads_bytes_(DataSize) void *Data,
54  _In_ DWORD DataSize,
55  _In_ DWORD Flags
56  )
57 {
58  UNREFERENCED_PARAMETER(Context);
60 
61  LOG("[DEBUG] Swapped %d bytes from GLA 0x%016llx, GPA 0x%016llx, CR3 0x%016llx, flags %d\n",
62  DataSize, VirtualAddress, PhysicalAddress, Cr3, Flags);
63 
64  return INT_STATUS_SUCCESS;
65 }
66 
67 
68 static INTSTATUS
70  _In_ void *Context,
71  _In_ QWORD VirtualAddress,
72  _In_ QWORD OldEntry,
73  _In_ QWORD NewEntry,
74  _In_ QWORD OldPageSize,
75  _In_ QWORD NewPageSize
76  )
77 {
78 #if LOG_LEVEL == 0
79  UNREFERENCED_PARAMETER(Context);
80  UNREFERENCED_PARAMETER(VirtualAddress);
81  UNREFERENCED_PARAMETER(OldEntry);
82  UNREFERENCED_PARAMETER(NewEntry);
83  UNREFERENCED_PARAMETER(OldPageSize);
84  UNREFERENCED_PARAMETER(NewPageSize);
85 #endif
86 
87  LOG("Modified GVA 0x%016llx, Context %p, from 0x%016llx to 0x%016llx, size 0x%016llx to 0x%016llx\n",
88  VirtualAddress, Context, OldEntry, NewEntry, OldPageSize, NewPageSize);
89 
90  return INT_STATUS_SUCCESS;
91 }
92 
93 
95 
96 
97 static INTSTATUS
99  _In_ QWORD Cr3,
100  _In_ QWORD VirtualAddress,
101  _In_ QWORD Entry,
102  _In_ QWORD PageSize
103  )
104 {
105  if ((Entry & PHYS_PAGE_MASK) == gTargetPML4)
106  {
107  LOG("[ITVA] CR3 0x%016llx, GVA 0x%016llx -> GPA 0x%016llx, size %llx ********\n",
108  Cr3, VirtualAddress, Entry, PageSize);
109  }
110 
111  return INT_STATUS_SUCCESS;
112 }
113 
114 
116 static BYTE *gPagesBitmap = NULL;
117 
118 
119 static INTSTATUS
121  _In_ QWORD Cr3,
122  _In_ QWORD VirtualAddress,
123  _In_ QWORD PhysicalAddress,
124  _In_ QWORD PageSize
125  )
126 {
127  UNREFERENCED_PARAMETER(PageSize);
129 
130  // Ignore physical pages that were already touched.
131  if (_bittestandset64((INT64 *)gPagesBitmap, (PhysicalAddress & PHYS_PAGE_MASK) >> 12))
132  {
133  return INT_STATUS_SUCCESS;
134  }
135 
136  if (Cr3 == gGuest.Mm.SystemCr3)
137  {
138  // Kernel space.
139  if (VirtualAddress >= 0xFFFF800000000000)
140  {
141  if (PhysicalAddress & PT_RW)
142  {
143  gPagesWrite++;
144  }
145  else
146  {
147  gPagesRead++;
148  }
149 
150  if (PhysicalAddress & PT_D)
151  {
152  gPagesDirty++;
153  }
154  }
155  }
156  else
157  {
158  // User space.
159  if (VirtualAddress < 0xFFFF800000000000)
160  {
161  if (PhysicalAddress & PT_RW)
162  {
163  gPagesWrite++;
164  }
165  else
166  {
167  gPagesRead++;
168  }
169 
170  if (PhysicalAddress & PT_D)
171  {
172  gPagesDirty++;
173  }
174  }
175  }
176 
177  return INT_STATUS_SUCCESS;
178 }
179 
180 
181 static void
183  void
184  )
185 {
186  INTSTATUS status;
187  DWORD i, j;
188  BYTE r, w, x;
189  LIST_ENTRY *list, *table;
190 
191  if (NULL == gHooks)
192  {
193  return;
194  }
195 
196  for (j = 0; j < 3; j++)
197  {
198  if (0 == j)
199  {
200  table = gHooks->GpaHooks.GpaHooksRead;
201  }
202  else if (1 == j)
203  {
204  table = gHooks->GpaHooks.GpaHooksWrite;
205  }
206  else
207  {
209  }
210 
211  for (i = 0; i < GPA_HOOK_TABLE_SIZE; i++)
212  {
213  list = table[i].Flink;
214 
215  while (list != &table[i])
216  {
217  PHOOK_GPA pHook = CONTAINING_RECORD(list, HOOK_GPA, Link);
218 
219  list = list->Flink;
220 
221  status = IntGetEPTPageProtection(gGuest.UntrustedEptIndex, pHook->GpaPage, &r, &w, &x);
222  if (!INT_SUCCESS(status))
223  {
224  ERROR("[ERROR] IntGetEPTPageProtection failed: 0x%08x\n", status);
225  }
226 
227  if ((pHook->Header.EptHookType == IG_EPT_HOOK_READ) && (1 == r))
228  {
229  ERROR("[ERROR] Invalid {read} internal state: hook %p\n", pHook);
230  }
231 
232  if ((pHook->Header.EptHookType == IG_EPT_HOOK_WRITE) && (1 == w))
233  {
234  ERROR("[ERROR] Invalid {write} internal state: hook %p\n", pHook);
235  }
236 
237  if ((pHook->Header.EptHookType == IG_EPT_HOOK_EXECUTE) && (1 == x))
238  {
239  ERROR("[ERROR] Invalid {execute} internal state: hook %p\n", pHook);
240  }
241  }
242  }
243  }
244 }
245 
246 
247 
248 static void
250  _In_ KM_EXCEPTION *Exception
251  )
252 {
253  LOG("%p : OriginatorName: %08x, Victim: %08x, Flg: %08x, Type: %02d, Sig: %d\n",
254  Exception, Exception->OriginatorNameHash,
255  Exception->VictimNameHash, Exception->Flags, Exception->Type, Exception->SigCount);
256 
257  if (Exception->SigCount > 0)
258  {
259  char siglist[256];
260  char *l = siglist;
261  int ret, rem = sizeof(siglist);
262 
263  ret = snprintf(l, rem, "--> Signatures:");
264  if (ret < 0 || ret >= rem)
265  {
266  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
267  return;
268  }
269  else
270  {
271  rem -= ret;
272  l += ret;
273  }
274 
275  for (DWORD i = 0; i < Exception->SigCount; i++)
276  {
277  ret = snprintf(l, rem, " 0x%04x", Exception->Signatures[i].Value);
278  if (ret < 0 || ret >= rem)
279  {
280  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
281  break;
282  }
283  else
284  {
285  rem -= ret;
286  l += ret;
287  }
288  }
289 
290  LOG("%s\n", siglist);
291  }
292 }
293 
294 
295 static void
297  _In_ UM_EXCEPTION *Exception
298  )
299 {
300  LOG("%p : Originator: %08x, Victim: %08x, Process: %08x, Flg: %08x, Type: %02d, Sig: %d\n",
301  Exception, Exception->OriginatorNameHash, Exception->Victim.NameHash,
302  Exception->Victim.ProcessHash, Exception->Flags, Exception->Type, Exception->SigCount);
303 
304  if (Exception->SigCount > 0)
305  {
306  char siglist[256];
307  char *l = siglist;
308  int ret, rem = sizeof(siglist);
309 
310  ret = snprintf(l, rem, "--> Signatures:");
311  if (ret < 0 || ret >= rem)
312  {
313  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
314  return;
315  }
316  else
317  {
318  rem -= ret;
319  l += ret;
320  }
321 
322  for (DWORD i = 0; i < Exception->SigCount; i++)
323  {
324  ret = snprintf(l, rem, " 0x%04x", Exception->Signatures[i].Value);
325  if (ret < 0 || ret >= rem)
326  {
327  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
328  break;
329  }
330  else
331  {
332  rem -= ret;
333  l += ret;
334  }
335  }
336 
337  LOG("%s\n", siglist);
338  }
339 
340 }
341 
342 
343 static void
345  _In_ UM_EXCEPTION_GLOB *Exception
346  )
347 {
348  LOG("%p : Originator: %s, Victim: %s, Process: %s, Flg: %08x, Type: %02d, Sig: %d\n",
349  Exception, Exception->OriginatorNameGlob, Exception->Victim.NameGlob,
350  Exception->Victim.ProcessGlob, Exception->Flags, Exception->Type, Exception->SigCount);
351 
352  if (Exception->SigCount > 0)
353  {
354  char siglist[256];
355  char *l = siglist;
356  int ret, rem = sizeof(siglist);
357 
358  ret = snprintf(l, rem, "--> Signatures:");
359  if (ret < 0 || ret >= rem)
360  {
361  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
362  return;
363  }
364  else
365  {
366  rem -= ret;
367  l += ret;
368  }
369 
370  for (DWORD i = 0; i < Exception->SigCount; i++)
371  {
372  ret = snprintf(l, rem, " 0x%4x", Exception->Signatures[i].Value);
373  if (ret < 0 || ret >= rem)
374  {
375  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
376  break;
377  }
378  else
379  {
380  rem -= ret;
381  l += ret;
382  }
383  }
384 
385  LOG("%s\n", siglist);
386  }
387 
388 }
389 
390 
391 static INTSTATUS
393  _In_opt_ void *Context,
394  _In_ DWORD Cr,
395  _In_ QWORD OldValue,
396  _In_ QWORD NewValue,
397  _Out_ INTRO_ACTION *Action
398  )
399 {
400  UNREFERENCED_PARAMETER(Context);
401 #if LOG_LEVEL == 0
402  UNREFERENCED_PARAMETER(NewValue);
403  UNREFERENCED_PARAMETER(OldValue);
405 #endif
406 
407  LOG("[CPU %d] Written CR%d from 0x0x%016llx to 0x0x%016llx\n", gVcpu->Index, Cr, OldValue, NewValue);
408 
409  *Action = introGuestAllowed;
410 
411  return INT_STATUS_SUCCESS;
412 }
413 
414 
415 #ifdef DEBUG_MEM_ALLOCS
416 
417 typedef struct _DBG_ALLOCATION
418 {
419  LIST_ENTRY Link;
420  RBNODE RbNode;
421  void *Address;
422  DWORD Size;
423  DWORD Tag;
424  const char *File;
425  DWORD Line;
426 } DBG_ALLOCATION, *PDBG_ALLOCATION;
427 
428 
430 IntDbgFreeAllocNode(
431  _Inout_ RBNODE *Node
432  )
433 {
435 }
436 
437 
439 IntDbgCompareAllocNode(
440  _In_ RBNODE *Left,
441  _In_ RBNODE *Right
442  )
443 {
444  DBG_ALLOCATION *p1 = CONTAINING_RECORD(Left, DBG_ALLOCATION, RbNode);
445  DBG_ALLOCATION *p2 = CONTAINING_RECORD(Right, DBG_ALLOCATION, RbNode);
446  size_t a1, a2;
447 
448  a1 = (size_t)p1->Address;
449  a2 = (size_t)p2->Address;
450 
451  if (a1 < a2)
452  {
453  return -1;
454  }
455  else if (a1 > a2)
456  {
457  return 1;
458  }
459  else
460  {
461  return 0;
462  }
463 }
464 
465 
466 static size_t gTotalMemUsed = 0;
467 static size_t gTotalAllocations = 0;
468 static size_t gTotalFrees = 0;
469 
470 static size_t gMaxMemUsed = 0;
471 static size_t gMaxAllocations = 0;
472 
473 static RBTREE gAllocTree = RB_TREE_INIT(gAllocTree, IntDbgFreeAllocNode, IntDbgCompareAllocNode);
474 static LIST_HEAD gAllocations = LIST_HEAD_INIT(gAllocations);
475 
476 
477 __attribute__((malloc))
478 __attribute__ ((alloc_size (1)))
479 __must_check void *
480 IntDbgAllocMem(
481  _In_ size_t Size,
482  _In_ DWORD Tag,
483  _In_ const char *FileName,
484  _In_ DWORD Line
485  )
486 {
487  DBG_ALLOCATION *pAlloc;
488  void *addr = NULL;
489 
490  addr = IntAllocWithTag(Size, Tag, FileName, Line);
491  if (NULL == addr)
492  {
493  return NULL;
494  }
495 
496  pAlloc = IntAllocWithTag(sizeof(*pAlloc), IC_TAG_ALLOC, FileName, Line);
497  if (NULL == pAlloc)
498  {
499  IntFreeWithTag(&addr, Tag, __LINE__);
500  return NULL;
501  }
502 
503  pAlloc->Address = addr;
504  pAlloc->Size = Size;
505  pAlloc->Tag = Tag;
506  pAlloc->File = FileName;
507  pAlloc->Line = Line;
508 
509  InsertTailList(&gAllocations, &pAlloc->Link);
510  RbInsertNode(&gAllocTree, &pAlloc->RbNode);
511 
512  gTotalAllocations++;
513  gTotalMemUsed += Size;
514 
515  if (gTotalMemUsed > gMaxMemUsed)
516  {
517  gMaxMemUsed = gTotalMemUsed;
518  }
519 
520  if (gTotalAllocations > gMaxAllocations)
521  {
522  gMaxAllocations = gTotalAllocations;
523  }
524 
525  return addr;
526 }
527 
528 
529 INTSTATUS
530 IntDbgFreeMem(
531  _Inout_ _At_(*Address, _Post_null_) void **Address,
532  _In_ DWORD Tag,
533  _In_ DWORD Line
534  )
535 {
536  DBG_ALLOCATION target;
537  RBNODE *result;
538 
539  target.Address = *Address;
540  gTotalFrees++;
541 
542  INTSTATUS status = RbLookupNode(&gAllocTree, &target.RbNode, &result);
543  if (INT_SUCCESS(status) && result)
544  {
545  DBG_ALLOCATION *pAlloc = CONTAINING_RECORD(result, DBG_ALLOCATION, RbNode);
546 
547  if (Tag != pAlloc->Tag)
548  {
549  ERROR("[ERROR] Tag different from what was requested: %08x != %08x for allocation from %s:%d\n",
550  pAlloc->Tag, Tag, pAlloc->File, pAlloc->Line);
551  }
552 
553  gTotalMemUsed -= pAlloc->Size;
554 
555  RemoveEntryList(&pAlloc->Link);
556  RbDeleteNode(&gAllocTree, &pAlloc->RbNode);
557 
559  }
560  else
561  {
562  ERROR("[CRITICAL] Trying to free an invalid address: %p\n", *Address);
563  }
564 
565  return INT_STATUS_SUCCESS;
566 }
567 
568 
569 INTSTATUS
570 IntDbgDumpAllocs(
571  _In_opt_ DWORD Tag
572  )
573 {
574  LIST_ENTRY *list;
575 
576  QWORD size = 0;
577  QWORD total = 0;
578 
579  list = gAllocations.Flink;
580  while (list != &gAllocations)
581  {
582  DBG_ALLOCATION *pAlloc = CONTAINING_RECORD(list, DBG_ALLOCATION, Link);
583  list = list->Flink;
584 
585  if (0 == Tag || Tag == pAlloc->Tag)
586  {
587  LOG("Alloc: %p:%6d, tag %08x (%c%c%c%c), from %s:%d\n",
588  pAlloc->Address,
589  pAlloc->Size,
590  pAlloc->Tag,
591  (pAlloc->Tag & 0xFF),
592  (pAlloc->Tag >> 8) & 0xFF,
593  (pAlloc->Tag >> 16) & 0xFF,
594  (pAlloc->Tag >> 24) & 0xFF,
595  pAlloc->File,
596  pAlloc->Line);
597 
598  total++;
599  size += pAlloc->Size;
600  }
601  }
602 
603  LOG("%lld allocations with %lld bytes\n", total, size);
604  LOG("Total memory allocated: %lld bytes\n", gTotalMemUsed);
605 
606  return INT_STATUS_SUCCESS;
607 }
608 
609 
610 INTSTATUS
611 IntDbgCheckAllocs(
612  void
613  )
614 {
615  LIST_ENTRY *list;
616 
617  list = gAllocations.Flink;
618  while (list != &gAllocations)
619  {
620  DBG_ALLOCATION *pAlloc = CONTAINING_RECORD(list, DBG_ALLOCATION, Link);
621  BYTE *pp = (BYTE *)pAlloc->Address - 8;
622 
623  if (*((QWORD *)pp) != 0xBDBDBDBDBDBDBDBD)
624  {
625  LOG("Buffer underflow for alloc at %p (struct: %p)!\n", pAlloc->Address, pAlloc);
626  }
627 
628  if (*((QWORD *)(pp + 8 + pAlloc->Size)) != 0xBDBDBDBDBDBDBDBD)
629  {
630  LOG("Buffer overflow for alloc at %p (struct: %p)!\n", pAlloc->Address, pAlloc);
631  }
632 
633  list = list->Flink;
634  }
635 
636  LOG("Total memory allocated: %lld bytes\n", gTotalMemUsed);
637 
638  return INT_STATUS_SUCCESS;
639 }
640 
641 #endif
642 
643 
644 
645 static void
647  void
648  );
649 
650 
651 static void
653  void
654  )
655 {
656  INTSTATUS status;
657  QWORD currentModule;
658  DWORD count = 0;
659 
660  currentModule = gWinGuest->PsLoadedModuleList;
661  if (currentModule == 0)
662  {
663  LOG("gWinGuest->PsLoadedModuleList is 0\n");
664  return;
665  }
666 
667  if (gGuest.Guest64)
668  {
669  status = IntKernVirtMemFetchQword(currentModule, &currentModule);
670  }
671  else
672  {
673  status = IntKernVirtMemFetchDword(currentModule, (DWORD *) &currentModule);
674  currentModule &= 0xFFFFFFFF;
675  }
676  if (!INT_SUCCESS(status))
677  {
678  ERROR("[ERROR] Failed getting the Flink value of MODULE at 0x%016llx: 0x%08x\n", currentModule, status);
679  return;
680  }
681 
682  while (currentModule != gWinGuest->PsLoadedModuleList)
683  {
684  LDR_DATA_TABLE_ENTRY32 *pModEntry32 = NULL;
685  LDR_DATA_TABLE_ENTRY64 *pModEntry64 = NULL;
686  WCHAR moduleName[MAX_PATH] = {0};
687  DWORD nameLength, sizeOfImage;
688  QWORD nameAddress, moduleBase;
689 
690  if (gGuest.Guest64)
691  {
692  status = IntVirtMemMap(currentModule, sizeof(*pModEntry64), 0, 0, &pModEntry64);
693  }
694  else
695  {
696  status = IntVirtMemMap(currentModule, sizeof(*pModEntry32), 0, 0, &pModEntry32);
697  }
698  if (!INT_SUCCESS(status))
699  {
700  ERROR("[ERROR] Failed to map the modules info at 0x%016llx: 0x%08x\n", currentModule, status);
701  break;
702  }
703 
704  if (gGuest.Guest64)
705  {
706  nameLength = 0xFFFF & pModEntry64->DriverPath.Length;
707  nameAddress = pModEntry64->DriverPath.Buffer;
708  moduleBase = pModEntry64->DllBase;
709  sizeOfImage = 0xffffffff & pModEntry64->SizeOfImage;
710  }
711  else
712  {
713  nameLength = 0xFFFF & pModEntry32->DriverPath.Length;
714  nameAddress = FIX_GUEST_POINTER(FALSE, pModEntry32->DriverPath.Buffer);
715  moduleBase = 0xffffffff & pModEntry32->DllBase;
716  sizeOfImage = pModEntry32->SizeOfImage;
717  }
718 
719  if (nameLength > MAX_PATH)
720  {
721  nameLength = MAX_PATH;
722  }
723 
724  // Copy the name into the given buffer. Safe, nameLength is truncated to MAX_PATH.
725  status = IntKernVirtMemRead(nameAddress, nameLength, moduleName, NULL);
726  if (!INT_SUCCESS(status))
727  {
728  ERROR("[ERROR] Failed reading module's path from VA 0x%016llx with length %x: 0x%08x\n",
729  nameAddress, nameLength, status);
730  goto _next;
731  }
732 
733  moduleName[nameLength / 2] = 0;
734 
735  LOG(" #%03d Base: 0x%016llx, SizeOfImage: 0x%08x, Path: %s\n",
736  count++, moduleBase, sizeOfImage, utf16_for_log(moduleName));
737 
738 _next:
739  if (gGuest.Guest64)
740  {
741  currentModule = pModEntry64->InLoadOrderLinks.Flink;
742  IntVirtMemUnmap(&pModEntry64);
743  }
744  else
745  {
746  currentModule = pModEntry32->InLoadOrderLinks.Flink;
747  currentModule &= 0xFFFFFFFF;
748  IntVirtMemUnmap(&pModEntry32);
749  }
750  }
751 }
752 
753 
754 static void
756  _In_ DWORD Argc,
757  _In_ const char *Argv[]
758  )
759 {
760  INTSTATUS status;
761  QWORD address;
762  DWORD write;
763 
764  if (Argc < 3)
765  {
766  ERROR("[ERROR] Invalid number of arguments!");
767  return;
768  }
769 
770  address = strtoull(Argv[1], NULL, 0);
771  write = (DWORD)strtoull(Argv[3], NULL, 0);
772 
773  status = IntInjectExceptionInGuest(VECTOR_PF, address, write != 0, 0);
774  if (!INT_SUCCESS(status))
775  {
776  ERROR("[ERROR] IntInjectExceptionInGuest failed: 0x%08x\n", status);
777  }
778 }
779 
780 
781 static void
783  _In_ DWORD Argc,
784  _In_ const char *Argv[]
785  )
786 {
787  QWORD address, gpa, pfnAddress;
788  DWORD pfnSize;
789  PBYTE pfnBuffer;
790  INTSTATUS status;
791  WORD refCount, flags;
792 
793  if (gWinGuest->MmPfnDatabase == 0)
794  {
795  ERROR("[ERROR] MmPfnDatabase is 0\n");
796  return;
797  }
798 
799  if (Argc < 3)
800  {
801  ERROR("[ERROR] Invalid number of arguments!\n");
802  return;
803  }
804 
805  address = strtoull(Argv[2], NULL, 0);
806  if (0 == address)
807  {
808  ERROR("[ERROR] %s is not a valid address\n", Argv[2]);
809  return;
810  }
811 
812  if (Argv[1][0] == 'v')
813  {
814  status = IntTranslateVirtualAddress(address, gGuest.Mm.SystemCr3, &gpa);
815  if (!INT_SUCCESS(status))
816  {
817  ERROR("[ERROR] GVA 0x%016llx to GPA failed: 0x%08x\n", address, status);
818  return;
819  }
820  }
821  else if (Argv[1][0] == 'p')
822  {
823  gpa = address;
824  }
825  else
826  {
827  ERROR("[ERROR] Give `v` or `p` for the address type\n");
828  return;
829  }
830 
831  pfnAddress = WIN_PFN_GET_STRUCT_VA(gWinGuest->MmPfnDatabase, gpa);
833  {
834  pfnSize = WIN_KM_FIELD(Mmpfn, Size);
835  }
836  else
837  {
838  pfnSize = WIN_KM_FIELD(Mmpfn, PaeSize);
839  }
840 
841  status = IntVirtMemMap(pfnAddress, pfnSize, 0, 0, &pfnBuffer);
842  if (!INT_SUCCESS(status))
843  {
844  ERROR("[ERROR] Failed mapping PFN structure from 0x%016llx: 0x%08x\n", pfnAddress, status);
845  return;
846  }
847 
848  LOG("PFN %llx at 0x%016llx for GPA 0x%016llx\n", gpa >> 12, pfnAddress, gpa);
849 
850  if (gGuest.Guest64)
851  {
852  LOG("PteAddress: 0x%016llx\n", *(QWORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, Pte)));
853  }
854  else if (gGuest.PaeEnabled)
855  {
856  LOG("PteAddress: 0x%08x\n", *(DWORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, PaePte)));
857  }
858  else
859  {
860  LOG("PteAddress: 0x%08x\n", *(DWORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, Pte)));
861  }
862 
864  {
865  refCount = *(WORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, RefCount));
866  flags = *(WORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, Flags));
867  }
868  else
869  {
870  refCount = *(WORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, PaeRefCount));
871  flags = *(WORD *)(pfnBuffer + WIN_KM_FIELD(Mmpfn, PaeFlags));
872  }
873 
874  LOG("RefCount: %x\t\tFlags: %x\n", refCount, flags);
875 
876  IntVirtMemUnmap(&pfnBuffer);
877 }
878 
879 
880 static void
882  _In_ DWORD Argc,
883  _In_ const char *Argv[]
884  )
885 {
886  QWORD addressStart, rip;
887  DWORD length, level;
888  PBYTE code;
889  INTSTATUS status;
890 
891  if (Argc < 2)
892  {
893  ERROR("[ERROR] Minimum number of arguments expected: 2\n");
894  return;
895  }
896 
897  addressStart = strtoull(Argv[1], NULL, 0);
898  if (0 == addressStart)
899  {
900  WARNING("[WARNING] %s is not a valid address\n", Argv[1]);
901  return;
902  }
903 
904  if (Argc > 2)
905  {
906  length = strtoul(Argv[2], NULL, 0);
907  if (0 == length)
908  {
909  WARNING("[WARNING] %s is not a valid length\n", Argv[2]);
910  return;
911  }
912  }
913  else
914  {
915  // By default we go to the end of the page
916  length = PAGE_REMAINING(addressStart);
917  }
918 
919  if (Argc > 3)
920  {
921  rip = strtoul(Argv[3], NULL, 0);
922  if (0 == rip)
923  {
924  WARNING("[WARNING] %s is not a valid rip\n", Argv[3]);
925  return;
926  }
927  }
928  else
929  {
930  rip = addressStart;
931  }
932 
933  if (Argc > 4)
934  {
935  level = strtoul(Argv[4], NULL, 0);
936  if (1 != level && 2 != level)
937  {
938  WARNING("[WARNING] %s is not a valid level\n", Argv[4]);
939  return;
940  }
941  }
942  else
943  {
944  level = cbLevelNormal;
945  }
946 
947  code = HpAllocWithTag(length, IC_TAG_CDBK);
948  if (NULL == code)
949  {
950  return;
951  }
952 
953  status = IntKernVirtMemRead(addressStart, length, code, NULL);
954  if (!INT_SUCCESS(status))
955  {
956  ERROR("[ERROR] Failed reading from GVA 0x%016llx: 0x%08x\n", addressStart, length);
957  goto _clean_leave;
958  }
959 
960  LOG("[CODEBLOCKS] Dumping codeblocks for RIP 0x%016llx (from 0x%016llx to 0x%016llx)\n",
961  rip, addressStart, addressStart + length);
962 
963  status = IntFragDumpBlocks(code,
964  addressStart,
965  length,
967  (BYTE)level,
968  rip,
969  FALSE);
970  if (!INT_SUCCESS(status))
971  {
972  ERROR("[ERROR] Failed extracting blocks from VA 0x%016llx: 0x%08x\n", addressStart, status);
973  }
974 
975 _clean_leave:
977 }
978 
979 
980 static void
982  void
983  )
984 {
985  DWORD i, id;
986  LIST_ENTRY *list;
987  PEXCEPTIONS pExceptions;
988  DWORD totalKernel;
989  DWORD totalUser;
990 
991  pExceptions = gGuest.Exceptions;
992  if (NULL == pExceptions)
993  {
994  LOG("[DBGINTRO] There are no exceptions loaded!\n");
995  return;
996  }
997 
998  totalKernel = 0;
999 
1000  LOG("[DBGINTRO] Kernel exceptions:\n");
1001 
1002  list = pExceptions->NoNameKernelExceptions.Flink;
1003  while (list != &pExceptions->NoNameKernelExceptions)
1004  {
1005  KM_EXCEPTION *pException = CONTAINING_RECORD(list, KM_EXCEPTION, Link);
1006  list = list->Flink;
1007 
1008  DbgDumpKmException(pException);
1009 
1010  totalKernel++;
1011  }
1012 
1013  list = pExceptions->GenericKernelExceptions.Flink;
1014  while (list != &pExceptions->GenericKernelExceptions)
1015  {
1016  KM_EXCEPTION *pException = CONTAINING_RECORD(list, KM_EXCEPTION, Link);
1017  list = list->Flink;
1018 
1019  DbgDumpKmException(pException);
1020 
1021  totalKernel++;
1022  }
1023 
1024  for (id = 0; id < EXCEPTION_TABLE_SIZE; id++)
1025  {
1026  list = pExceptions->KernelExceptions[id].Flink;
1027  while (list != &pExceptions->KernelExceptions[id])
1028  {
1029  KM_EXCEPTION *pException = CONTAINING_RECORD(list, KM_EXCEPTION, Link);
1030  list = list->Flink;
1031 
1032  DbgDumpKmException(pException);
1033 
1034  totalKernel++;
1035  }
1036  }
1037 
1038  LOG("[DBGINTRO] User exceptions:\n");
1039 
1040  totalUser = 0;
1041  list = pExceptions->GenericUserExceptions.Flink;
1042  while (list != &pExceptions->GenericUserExceptions)
1043  {
1044  UM_EXCEPTION *pException = CONTAINING_RECORD(list, UM_EXCEPTION, Link);
1045  list = list->Flink;
1046 
1047  DbgDumpUmException(pException);
1048 
1049  totalUser++;
1050  }
1051 
1052  totalUser = 0;
1053  list = pExceptions->NoNameUserExceptions.Flink;
1054  while (list != &pExceptions->NoNameUserExceptions)
1055  {
1056  UM_EXCEPTION *pException = CONTAINING_RECORD(list, UM_EXCEPTION, Link);
1057  list = list->Flink;
1058 
1059  DbgDumpUmException(pException);
1060 
1061  totalUser++;
1062  }
1063 
1064  totalUser = 0;
1065  list = pExceptions->GlobUserExceptions.Flink;
1066  while (list != &pExceptions->GlobUserExceptions)
1067  {
1068  UM_EXCEPTION_GLOB *pException = CONTAINING_RECORD(list, UM_EXCEPTION_GLOB, Link);
1069  list = list->Flink;
1070 
1071  DbgDumpUmExceptionGlobMatch(pException);
1072 
1073  totalUser++;
1074 
1075  }
1076 
1077  // 4. User exceptions (per table)
1078  for (id = 0; id < EXCEPTION_TABLE_SIZE; id++)
1079  {
1080  list = pExceptions->UserExceptions[id].Flink;
1081  while (list != &pExceptions->UserExceptions[id])
1082  {
1083  UM_EXCEPTION *pException = CONTAINING_RECORD(list, UM_EXCEPTION, Link);
1084  list = list->Flink;
1085 
1086  DbgDumpUmException(pException);
1087 
1088  totalUser++;
1089  }
1090  }
1091 
1092  LOG("[DBGINTRO] Codeblocks signatures:\n");
1093  list = pExceptions->CbSignatures.Flink;
1094  while (list != &pExceptions->CbSignatures)
1095  {
1096  SIG_CODEBLOCKS *pSignature = CONTAINING_RECORD(list, SIG_CODEBLOCKS, Link);
1097  SIG_CODEBLOCK_HASH *pSigHash;
1098  list = list->Flink;
1099 
1100  LOG("%p : Id: %04x, Flags: %08x, Score: %02d, Lists: %02d\n",
1101  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->Score, pSignature->ListsCount);
1102 
1103  pSigHash = (SIG_CODEBLOCK_HASH *)pSignature->Object;
1104  for (i = 0; i < pSignature->ListsCount; i++)
1105  {
1106  DWORD hashSize = sizeof(SIG_CODEBLOCK_HASH) + pSigHash->Count * sizeof(DWORD);
1107 
1108  char hashes[256];
1109  char *l = hashes;
1110  int ret, rem = sizeof(hashes);
1111 
1112  ret = snprintf(l, rem, "--> List(%u):", pSigHash->Count);
1113  if (ret < 0 || ret >= rem)
1114  {
1115  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
1116  return;
1117  }
1118  else
1119  {
1120  rem -= ret;
1121  l += ret;
1122  }
1123 
1124  for (DWORD j = 0; j < pSigHash->Count; j++)
1125  {
1126  ret = snprintf(l, rem, " %08x", pSigHash->Hashes[j]);
1127  if (ret < 0 || ret >= rem)
1128  {
1129  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
1130  break;
1131  }
1132  else
1133  {
1134  rem -= ret;
1135  l += ret;
1136  }
1137  }
1138 
1139  LOG("%s\n", hashes);
1140 
1141  // advance to the next hash list
1142  pSigHash = (SIG_CODEBLOCK_HASH *)((BYTE *)pSigHash + hashSize);
1143  }
1144  }
1145 
1146  LOG("[DBGINTRO] Export signatures:\n");
1147  list = pExceptions->ExportSignatures.Flink;
1148  while (list != &pExceptions->ExportSignatures)
1149  {
1150  SIG_EXPORT *pSignature = CONTAINING_RECORD(list, SIG_EXPORT, Link);
1151  SIG_EXPORT_HASH *pSigHash;
1152  list = list->Flink;
1153 
1154  LOG("%p : Id: %04x, Flags: %08x, Library: %08x, Lists: %02d\n",
1155  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->LibraryNameHash, pSignature->ListsCount);
1156 
1157  pSigHash = (SIG_EXPORT_HASH *)pSignature->Object;
1158  for (DWORD j = 0; j < pSignature->ListsCount; j++)
1159  {
1160  LOG("--> List(%d): Delta: %02x, Hash: %08x\n", j, pSigHash[j].Delta, pSigHash[j].Hash);
1161  }
1162  }
1163 
1164  LOG("[DBGINTRO] Value signatures:\n");
1165  list = pExceptions->ValueSignatures.Flink;
1166  while (list != &pExceptions->ValueSignatures)
1167  {
1168  SIG_VALUE *pSignature = CONTAINING_RECORD(list, SIG_VALUE, Link);
1169  SIG_VALUE_HASH *pSigHash;
1170  list = list->Flink;
1171 
1172  LOG("%p : Id: %04x, Flags: %08x, Score: %02d, Lists: %02d\n",
1173  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->Score, pSignature->ListsCount);
1174 
1175  pSigHash = (SIG_VALUE_HASH *)pSignature->Object;
1176  for (DWORD j = 0; j < pSignature->ListsCount; j++)
1177  {
1178  LOG("--> List(%d): Offset: %02x, Size: %02x, Hash: %08x\n",
1179  j, pSigHash[j].Offset, pSigHash[j].Size, pSigHash[j].Hash);
1180  }
1181  }
1182 
1183  LOG("[DBGINTRO] Idt signatures:\n");
1184  list = pExceptions->IdtSignatures.Flink;
1185  while (list != &pExceptions->IdtSignatures)
1186  {
1187  PSIG_IDT pSignature = CONTAINING_RECORD(list, SIG_IDT, Link);
1188  list = list->Flink;
1189 
1190  LOG("%p : Id: %04x, Flags: %08x, Entry: %0d \n",
1191  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->Entry);
1192  }
1193 
1194  LOG("[DBGINTRO] Value code signatures:\n");
1195  list = pExceptions->ValueCodeSignatures.Flink;
1196  while (list != &pExceptions->ValueCodeSignatures)
1197  {
1198  PSIG_VALUE_CODE pSignature = CONTAINING_RECORD(list, SIG_VALUE_CODE, Link);
1199  PWORD pPattern;
1200  list = list->Flink;
1201 
1202  LOG("%p : Id: %04x, Flags: %08x, Offset: %02d, Length: %02d\n",
1203  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->Offset, pSignature->Length);
1204 
1205  pPattern = (PWORD)pSignature->Object;
1206  for (DWORD j = 0; j < pSignature->Length; j++)
1207  {
1208  LOG("--> Item(%d): %02x\n", j, pPattern[j]);
1209  }
1210  }
1211 
1212  LOG("[DBGINTRO] Version OS signatures:\n");
1213  list = pExceptions->VersionOsSignatures.Flink;
1214  while (list != &pExceptions->VersionOsSignatures)
1215  {
1216  SIG_VERSION_OS *pSignature = CONTAINING_RECORD(list, SIG_VERSION_OS, Link);
1217  list = list->Flink;
1218 
1219  LOG("%p : Id: %04x, Flags: %08x, Minimum: 0x%llx, Maximum: 0x%llx\n",
1220  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->Minimum.Value, pSignature->Maximum.Value);
1221  }
1222 
1223  LOG("[DBGINTRO] Version Introcore signatures:\n");
1224  list = pExceptions->VersionIntroSignatures.Flink;
1225  while (list != &pExceptions->VersionIntroSignatures)
1226  {
1227  SIG_VERSION_INTRO *pSignature = CONTAINING_RECORD(list, SIG_VERSION_INTRO, Link);
1228  list = list->Flink;
1229 
1230  LOG("%p : Id: %04x, Flags: %08x, Minimum: %d.%d.%d, Maximum: %d.%d.%d\n",
1231  pSignature, pSignature->Id.Value, pSignature->Flags,
1232  pSignature->Minimum.Major, pSignature->Minimum.Minor, pSignature->Minimum.Revision,
1233  pSignature->Maximum.Major, pSignature->Maximum.Minor, pSignature->Maximum.Revision);
1234  }
1235 
1236  LOG("[DBGINTRO] Process creation signatures:\n");
1237  list = pExceptions->ProcessCreationSignatures.Flink;
1238  while (list != &pExceptions->ProcessCreationSignatures)
1239  {
1240  SIG_PROCESS_CREATION *pSignature = CONTAINING_RECORD(list, SIG_PROCESS_CREATION, Link);
1241  list = list->Flink;
1242 
1243  LOG("%p : Id: %04x, Flags: %08x, Create-Mask: 0x%08x\n",
1244  pSignature, pSignature->Id.Value, pSignature->Flags, pSignature->CreateMask);
1245  }
1246 }
1247 
1248 
1249 static void
1251  void
1252  )
1253 {
1254  DWORD count;
1255  LIST_ENTRY *list;
1256 
1257  if (NULL == gHooks)
1258  {
1259  return;
1260  }
1261 
1262  LOG("GVA hooks:\n");
1263 
1264  count = 0;
1265 
1266  list = &gHooks->GvaHooks.GvaHooks;
1267  while (list != &gHooks->GvaHooks.GvaHooks)
1268  {
1269  HOOK_GVA *pHook = CONTAINING_RECORD(list, HOOK_GVA, Link);
1270 
1271  LOG("%04d: GVA: 0x%016llx, Offset: %04x, Length: %04x, Flags: %08x, "
1272  "Type: %d, integrity: %s, writable: %s, GPA hook: %p\n",
1273  count++,
1274  pHook->GvaPage, pHook->Offset, pHook->Length, pHook->Header.Flags, pHook->Header.EptHookType,
1275  pHook->IsIntegrityOn ? "yes" : "no",
1276  pHook->IsPageWritable ? "yes" : "no", pHook->GpaHook);
1277 
1278  list = list->Flink;
1279  }
1280 
1281 
1283 
1284  LOG("Removed hooks queue:\n");
1285 
1286  while (list != &gHooks->GvaHooks.RemovedHooksList)
1287  {
1288  HOOK_GVA *pHook = CONTAINING_RECORD(list, HOOK_GVA, Link);
1289 
1290  LOG("%04d: GVA: 0x%016llx, Offset: %04x, Length: %04x, Flags: %08x, Type: %d, GPA hook: %p\n",
1291  count++,
1292  pHook->GvaPage, pHook->Offset, pHook->Length, pHook->Header.Flags, pHook->Header.EptHookType,
1293  pHook->GpaHook);
1294 
1295  list = list->Flink;
1296  }
1297 }
1298 
1299 
1300 static void
1302  void
1303  )
1304 {
1306  {
1307  IntWinProcDump();
1308  }
1309  else if (gGuest.OSType == introGuestLinux)
1310  {
1311  IntLixTaskDump();
1312  }
1313 }
1314 
1315 
1316 static void
1318  _In_ DWORD Argc,
1319  _In_ const char *Argv[]
1320  )
1321 {
1322  CHAR fullPath[MAX_PATH];
1323 
1324  if (Argc < 3)
1325  {
1326  ERROR("[ERROR] Invalid number of arguments!\n");
1327  return;
1328  }
1329 
1330  if (Argc > 3 || Argv[1][0] == '\'' || Argv[1][0] == '\"')
1331  {
1332  DWORD arg;
1333  size_t last = 0;
1334 
1335  memset(fullPath, 0, sizeof(fullPath));
1336 
1337  for (arg = 1; arg < Argc - 1; arg++)
1338  {
1339  size_t len = strlen(Argv[arg]);
1340 
1341  if (arg == 1)
1342  {
1343  // Starts with ' or " (probably surrounded by it)
1344  if (Argv[arg][0] == '\"' || Argv[arg][0] == '\'')
1345  {
1346  // Skip the ' or "
1347  strlcpy(&fullPath[last], &Argv[arg][1], sizeof(fullPath) - last);
1348  len--;
1349  }
1350  else
1351  {
1352  strlcpy(&fullPath[last], Argv[arg], sizeof(fullPath) - last);
1353  }
1354  }
1355  else
1356  {
1357  strlcpy(&fullPath[last], Argv[arg], sizeof(fullPath) - last);
1358  }
1359 
1360  last += len;
1361 
1362  if (arg < Argc - 2)
1363  {
1364  fullPath[last] = ' ';
1365  last++;
1366  }
1367  else // the last one
1368  {
1369  // Ends with ' or " (probably surrounded by it)
1370  if (fullPath[last - 1] == '\"' || fullPath[last - 1] == '\'')
1371  {
1372  // Delete the ' or "
1373  fullPath[last - 1] = 0;
1374  }
1375  }
1376  }
1377 
1378  IntAddRemoveProtectedProcessUtf8(gIntHandle, fullPath, strtoul(Argv[Argc - 1], 0, 0), TRUE, 0);
1379  }
1380  else
1381  {
1382  IntAddRemoveProtectedProcessUtf8(gIntHandle, Argv[1], strtoul(Argv[2], 0, 0), TRUE, 0);
1383  }
1384 
1385 }
1386 
1387 
1388 static void
1390  _In_ DWORD Argc,
1391  _In_ const char *Argv[]
1392  )
1393 {
1394  CHAR fullPath[MAX_PATH];
1395 
1396  if (Argc < 2)
1397  {
1398  ERROR("[ERROR] Invalid number of arguments!\n");
1399  return;
1400  }
1401 
1402  if (Argc > 2 || Argv[1][0] == '\'' || Argv[1][0] == '\"')
1403  {
1404  DWORD arg;
1405  size_t last = 0;
1406 
1407  memset(fullPath, 0, sizeof(fullPath));
1408 
1409  for (arg = 1; arg < Argc; arg++)
1410  {
1411  size_t len = strlen(Argv[arg]);
1412 
1413  if (arg == 1)
1414  {
1415  // Starts with ' or " (probably surrounded by it)
1416  if (Argv[arg][0] == '\"' || Argv[arg][0] == '\'')
1417  {
1418  // Skip the ' or "
1419  strlcpy(&fullPath[last], &Argv[arg][1], sizeof(fullPath) - last);
1420  len--;
1421  }
1422  else
1423  {
1424  strlcpy(&fullPath[last], Argv[arg], sizeof(fullPath) - last);
1425  }
1426  }
1427  else
1428  {
1429  strlcpy(&fullPath[last], Argv[arg], sizeof(fullPath) - last);
1430  }
1431 
1432  last += len;
1433 
1434  if (arg < Argc - 1)
1435  {
1436  fullPath[last] = ' ';
1437  last++;
1438  }
1439  else // the last one
1440  {
1441  // Ends with ' or " (probably surrounded by it)
1442  if (fullPath[last - 1] == '\"' || fullPath[last - 1] == '\'')
1443  {
1444  // Delete the ' or "
1445  fullPath[last - 1] = 0;
1446  }
1447  }
1448  }
1449 
1451  }
1452  else
1453  {
1455  }
1456 }
1457 
1458 
1459 static void
1461  void
1462  )
1463 {
1465 }
1466 
1467 
1468 static void
1470  void
1471  )
1472 {
1474  {
1476  }
1477  else if (gGuest.OSType == introGuestLinux)
1478  {
1480  }
1481 }
1482 
1483 
1484 static void
1486  void
1487  )
1488 {
1490 }
1491 
1492 
1493 static void
1495  _In_ DWORD Argc,
1496  _In_ const char *Argv[]
1497  )
1498 {
1499  QWORD address;
1500  DWORD size;
1501 
1502  if (Argc < 3)
1503  {
1504  ERROR("[ERROR] Invalid number of arguments!\n");
1505  return;
1506  }
1507 
1508  address = strtoull(Argv[1], NULL, 0);
1509  if (0 == address)
1510  {
1511  ERROR("[ERROR] %s is not a valid address\n", Argv[1]);
1512  return;
1513  }
1514 
1515  size = strtoul(Argv[2], NULL, 0);
1516  if (0 == size)
1517  {
1518  ERROR("[ERROR] %s is not a valid size\n", Argv[2]);
1519  }
1520 
1521  IntDisasmGva(address, size);
1522 }
1523 
1524 
1525 static void
1527  _In_ DWORD Argc,
1528  _In_ const char *Argv[]
1529  )
1530 {
1531  INTSTATUS status;
1532  DWORD tag;
1533  const char *name;
1534 
1535  if (Argc < 3)
1536  {
1537  ERROR("[ERROR] Invalid number of arguments!\n");
1538  return;
1539  }
1540 
1541  name = Argv[1];
1542  tag = strtoul(Argv[2], NULL, 0);
1543 
1544  status = IntDepInjectProcess(tag, NULL, 0, name, Argv[3]);
1545  if (!INT_SUCCESS(status))
1546  {
1547  ERROR("[ERROR] IntDepInjectAgent failed: 0x%08x\n", status);
1548  }
1549 }
1550 
1551 
1552 static void
1554  _In_ DWORD Argc,
1555  _In_ const char *Argv[]
1556  )
1557 {
1558  INTSTATUS status;
1559  const char *name;
1560  CHAR *content = "abcdefghijklmnopqrstuvwxyz";
1561 
1562  if (Argc < 2)
1563  {
1564  ERROR("[ERROR] Invalid number of arguments!\n");
1565  return;
1566  }
1567 
1568  name = Argv[1];
1569 
1570  status = IntDepInjectFile((PBYTE)content, 27, name);
1571  if (!INT_SUCCESS(status))
1572  {
1573  ERROR("[ERROR] IntDepInjectAgent failed: 0x%08x\n", status);
1574  }
1575 }
1576 
1577 
1578 static void
1580  _In_ DWORD Argc,
1581  _In_ const char *Argv[]
1582  )
1583 {
1584  QWORD cr3;
1585 
1586  if (Argc < 2)
1587  {
1588  ERROR("[ERROR] Invalid number of arguments!\n");
1589  return;
1590  }
1591 
1592  cr3 = strtoull(Argv[1], NULL, 0);
1593  gTargetPML4 = strtoull(Argv[2], NULL, 0);
1594 
1595  LOG("[DBGINTRO] Begin iterate VA space 0x%016llx, search for 0x%016llx!\n", cr3, gTargetPML4);
1596 
1598 
1599  LOG("[DBGINTRO] Done!\n");
1600 }
1601 
1602 
1603 static void
1605  void
1606  )
1607 {
1608  LIST_ENTRY *list;
1609 
1610  gPagesRead = gPagesWrite = gPagesDirty = 0;
1611  gTargetPML4 = 0;
1612 
1613  gPagesBitmap = HpAllocWithTag(ONE_MEGABYTE, IC_TAG_ALLOC);
1614  if (NULL == gPagesBitmap)
1615  {
1616  return;
1617  }
1618 
1619  list = gWinProcesses.Flink;
1620  while (list != &gWinProcesses)
1621  {
1623 
1624  list = list->Flink;
1625 
1626  LOG("[DBGINTRO] Iterating VA space of process %s with CR3 %llx\n", pProc->Name, pProc->Cr3);
1627 
1629  }
1630 
1631  LOG("[DBGINTRO] %lld total present physical pages, %lld readable pages, %lld writable pages, %lld dirty pages\n",
1632  gPagesRead + gPagesWrite, gPagesRead, gPagesWrite, gPagesDirty);
1633 
1634  HpFreeAndNullWithTag(&gPagesBitmap, IC_TAG_ALLOC);
1635 }
1636 
1637 
1638 static void
1640  _In_ DWORD Argc,
1641  _In_ const char *Argv[]
1642  )
1643 {
1644  QWORD gla = 0, cr3 = 0;
1645  INTSTATUS status = INT_STATUS_SUCCESS;
1646  VA_TRANSLATION tr = { 0 };
1647 
1648  if (Argc != 3)
1649  {
1650  ERROR("[ERROR] Invalid number of arguments!\n");
1651  return;
1652  }
1653 
1654  cr3 = strtoull(Argv[1], 0, 0);
1655  gla = strtoull(Argv[2], 0, 0);
1656 
1657  status = IntTranslateVirtualAddressEx(gla, cr3, TRFLG_NONE, &tr);
1658  if (!INT_SUCCESS(status))
1659  {
1660  ERROR("[ERROR] IntTranslateVirtualAddressEx failed: 0x%08x\n", status);
1661  }
1662  else
1663  {
1664  LOG("%llx translated to %llx, %d levels, user: %d, write: %d, exec: %d\n",
1665  gla, tr.PhysicalAddress, tr.MappingsCount, tr.IsUser, tr.IsWritable, tr.IsExecutable);
1666 
1667  for (DWORD i = 0; i < tr.MappingsCount; i++)
1668  {
1669  LOG(" %d: %llx = %llx\n", i, tr.MappingsTrace[i], tr.MappingsEntries[i]);
1670  }
1671  }
1672 }
1673 
1674 
1675 static void
1677  _In_ DWORD Argc,
1678  _In_ const char *Argv[]
1679  )
1680 {
1681  INTSTATUS status;
1682  PHOOK_PTS pPts;
1683  QWORD va;
1684  QWORD cr3;
1685  QWORD id;
1686 
1687  if (Argc != 4)
1688  {
1689  ERROR("[ERROR] Invalid number of arguments!\n");
1690  return;
1691  }
1692 
1693  cr3 = strtoull(Argv[1], NULL, 0);
1694  va = strtoull(Argv[2], NULL, 0);
1695  id = strtoull(Argv[3], NULL, 0);
1696 
1697  status = IntHookPtsSetHook(cr3, va, DbgVaModificationHandler, (void *)id, NULL, 0, &pPts);
1698  if (!INT_SUCCESS(status))
1699  {
1700  ERROR("[ERROR] IntHookPtSetHook failed: 0x%08x\n", status);
1701  }
1702  else
1703  {
1704  LOG("-> %p\n", pPts);
1705  }
1706 }
1707 
1708 
1709 static void
1711  _In_ DWORD Argc,
1712  _In_ const char *Argv[]
1713  )
1714 {
1715  INTSTATUS status;
1716  PHOOK_PTS pPts;
1717 
1718  if (Argc != 2)
1719  {
1720  ERROR("[ERROR] Invalid number of arguments!\n");
1721  return;
1722  }
1723 
1724  pPts = (PHOOK_PTS)strtoull(Argv[1], NULL, 0);
1725 
1726  // We can't commit the hook, since other CPU blocked in the debugger may have hooks locks.
1727  status = IntHookPtsRemoveHook((HOOK_PTS **)&pPts, 0);
1728  if (!INT_SUCCESS(status))
1729  {
1730  ERROR("[ERROR] IntHookPtsRemoveHook failed: 0x%08x\n", status);
1731  }
1732 }
1733 
1734 
1735 static void
1737  _In_ DWORD Argc,
1738  _In_ const char *Argv[]
1739  )
1740 {
1741  INTSTATUS status;
1742  QWORD oldvalue, newvalue;
1743  PHOOK_PTS_ENTRY pPts;
1744 
1745  if (Argc != 4)
1746  {
1747  ERROR("[ERROR] Invalid number of arguments!\n");
1748  return;
1749  }
1750 
1751  pPts = (PHOOK_PTS_ENTRY)strtoull(Argv[1], NULL, 0);
1752 
1753  oldvalue = strtoull(Argv[2], NULL, 0);
1754 
1755  newvalue = strtoull(Argv[3], NULL, 0);
1756 
1757  status = IntHookPtsWriteEntry(pPts, oldvalue, newvalue);
1758  if (!INT_SUCCESS(status))
1759  {
1760  ERROR("[ERROR] IntHookPtsWriteEntry failed: 0x%08x\n", status);
1761  }
1762 }
1763 
1764 
1765 static void
1767  void
1768  )
1769 {
1770  for (DWORD i = 0; i < gGuest.CpuCount; i++)
1771  {
1772  LOG("Cpu %d state -> %d (%s)\n", i, gGuest.VcpuArray[i].State,
1773  gGuest.VcpuArray[i].State == CPU_STATE_ACTIVE ? "Active" :
1774  gGuest.VcpuArray[i].State == CPU_STATE_EPT_VIOLATION ? "EPT violation" :
1775  gGuest.VcpuArray[i].State == CPU_STATE_MSR_VIOLATION ? "MSR violation" :
1776  gGuest.VcpuArray[i].State == CPU_STATE_VMCALL ? "VMCALL" :
1777  gGuest.VcpuArray[i].State == CPU_STATE_TIMER ? "Timer" :
1778  gGuest.VcpuArray[i].State == CPU_STATE_CR_WRITE ? "CR Write" :
1779  gGuest.VcpuArray[i].State == CPU_STATE_DTR_LOAD ? "DTR Load" :
1780  gGuest.VcpuArray[i].State == CPU_STATE_XCR_WRITE ? "XCR Write" : "Unknown");
1781  }
1782 }
1783 
1784 
1785 static void
1787  void
1788  )
1789 {
1790  LOG("Guest options: 0x%016llx\n", gGuest.CoreOptions.Current);
1791 }
1792 
1793 
1794 static void
1796  _In_ DWORD Argc,
1797  _In_ const char *Argv[]
1798  )
1799 {
1800  QWORD newValue;
1801 
1802  if (Argc < 2)
1803  {
1804  ERROR("[ERROR] Invalid number of arguments!\n");
1805  return;
1806  }
1807 
1808  newValue = strtoull(Argv[1], NULL, 0);
1809 
1810  LOG("Old guest options 0x%016llx, new guest options 0x%016llx\n", gGuest.CoreOptions.Current, newValue);
1811 
1812  IntGuestUpdateCoreOptions(newValue);
1813 }
1814 
1815 
1816 static void
1818  void
1819  )
1820 {
1822 
1823  if (NULL == proc)
1824  {
1825  ERROR("[ERROR] No process found for the current CR3: 0x%016llx\n", gVcpu->Regs.Cr3);
1826  }
1827  else
1828  {
1829  LOG("Current process: 0x%016llx, PID %d, ImageName '%s'\n", proc->EprocessAddress, proc->Pid, proc->Name);
1830  }
1831 }
1832 
1833 
1834 static void
1836  _In_ DWORD Argc,
1837  _In_ const char *Argv[]
1838  )
1839 {
1840  QWORD gva, symEnd;
1841  CHAR symName[LIX_SYMBOL_NAME_LEN] = {0};
1842  INTSTATUS status;
1843 
1844  if (Argc != 2)
1845  {
1846  ERROR("[ERROR] Invalid number of arguments!\n");
1847  return;
1848  }
1849 
1850  symEnd = 0;
1851 
1852  // Let's be reasonable, and assume we will give a hex number (0x...)
1853  if (Argv[1][0] == '0')
1854  {
1855  gva = strtoull(Argv[1], 0, 0);
1856 
1857  status = IntKsymFindByAddress(gva, sizeof(symName), symName, NULL, &symEnd);
1858  if (!INT_SUCCESS(status))
1859  {
1860  LOG("No symbol at GVA 0x%016llx\n", gva);
1861  }
1862  else
1863  {
1864  LOG("Symbol at GVA 0x%016llx -> 0x%016llx: %s\n", gva, symEnd, symName);
1865  }
1866  }
1867  else
1868  {
1869  gva = IntKsymFindByName(Argv[1], &symEnd);
1870  if (!gva)
1871  {
1872  LOG("Can't find symbol %s\n", Argv[1]);
1873  }
1874  else
1875  {
1876  LOG("Symbol %s at GVA 0x%016llx -> 0x%016llx\n", symName, gva, symEnd);
1877  }
1878  }
1879 }
1880 
1881 
1882 static void
1884  void
1885  )
1886 {
1887  for (DWORD i = 0; i < gGuest.CpuCount; i++)
1888  {
1889  QWORD pcrBase = 0;
1890  INTSTATUS status = 0;
1891 
1892  if (!gGuest.VcpuArray[i].IdtBase)
1893  {
1894  LOG("CPU %d seems to be inactive, will skip.\n", i);
1895  continue;
1896  }
1897 
1898  status = IntFindKernelPcr(i, &pcrBase);
1899  if (!INT_SUCCESS(status))
1900  {
1901  ERROR("[ERROR] IntFindKernelPcr failed for %d: 0x%08x\n", i, status);
1902  continue;
1903  }
1904  else if (INT_STATUS_NOT_NEEDED_HINT == status)
1905  {
1906  LOG("CPU %d seems to be inactive, will skip.\n", i);
1907  continue;
1908  }
1909 
1910  LOG("KPCR on CPU %d is 0x%016llx\n", i, pcrBase);
1911  }
1912 }
1913 
1914 
1915 static void
1917  _In_ DWORD Argc,
1918  _In_ const char *Argv[]
1919  )
1920 {
1921  INTSTATUS status;
1922  INTRO_WIN_TOKEN *pToken;
1923  DWORD pid;
1924 
1925  if (Argc != 2)
1926  {
1927  ERROR("[ERROR] Invalid number of arguments!\n");
1928  return;
1929  }
1930 
1931  pid = strtoul(Argv[1], 0, 0);
1932 
1933  pToken = HpAllocWithTag(sizeof(*pToken), IC_TAG_DEBUG);
1934  if (NULL == pToken)
1935  {
1936  return;
1937  }
1938 
1939  status = IntWinGetAccessTokenFromProcess(pid, 0, pToken);
1940  if (!INT_SUCCESS(status))
1941  {
1942  ERROR("[ERROR] IntWinGetAccessTokenFromProcess failed for %d: 0x%x\n", pid, status);
1943  }
1944  else
1945  {
1946  IntWinDumpToken(pToken);
1947  }
1948 
1950 }
1951 
1952 
1953 static void
1955  _In_ DWORD Argc,
1956  _In_ const char *Argv[]
1957  )
1958 {
1959  QWORD ethread;
1960  INTSTATUS status;
1961  INTRO_WIN_TOKEN *pToken;
1962 
1963  if (Argc != 2)
1964  {
1965  ERROR("[ERROR] Invalid number of arguments!\n");
1966  return;
1967  }
1968 
1969  pToken = HpAllocWithTag(sizeof(*pToken), IC_TAG_DEBUG);
1970  if (NULL == pToken)
1971  {
1972  return;
1973  }
1974 
1975  ethread = strtoull(Argv[1], 0, 0);
1976 
1977  status = IntWinGetAccesTokenFromThread(ethread, pToken);
1978  if (INT_STATUS_NOT_FOUND == status)
1979  {
1980  LOG("No Impersonation Token found for Ethread %llx\n", ethread);
1981  }
1982  else if (!INT_SUCCESS(status))
1983  {
1984  ERROR("[ERROR] IntWinGetAccesTokenFromThread failed for %llx: 0x%x\n", ethread, status);
1985  }
1986  else
1987  {
1988  IntWinDumpToken(pToken);
1989  }
1990 
1992 }
1993 
1994 
1995 static void
1997  _In_ DWORD Argc,
1998  _In_ const char *Argv[]
1999  )
2000 {
2001  QWORD cr3;
2002  INTSTATUS status;
2003 
2004  if (Argc != 2)
2005  {
2006  ERROR("[ERROR] Invalid number of arguments!\n");
2007  return;
2008  }
2009 
2010  cr3 = strtoull(Argv[1], NULL, 0);
2011 
2012  status = IntVasDump(cr3);
2013  if (!INT_SUCCESS(status))
2014  {
2015  ERROR("[ERROR] IntVasDump failed: 0x%08x\n", status);
2016  }
2017 }
2018 
2019 
2020 static void
2022  _In_ DWORD Argc,
2023  _In_ const char *Argv[]
2024  )
2025 {
2026  QWORD cr3;
2027  QWORD gla;
2028  DWORD len;
2029  DWORD mod;
2030  INTSTATUS status;
2031 
2032  if (Argc < 5)
2033  {
2034  ERROR("[ERROR] Invalid number of arguments!\n");
2035  return;
2036  }
2037 
2038  cr3 = strtoull(Argv[1], NULL, 0);
2039  gla = strtoull(Argv[2], NULL, 0);
2040  len = strtoul(Argv[3], NULL, 0);
2041  mod = strtoul(Argv[4], NULL, 0);
2042 
2043  status = IntSwapMemReadData(cr3, gla, len, mod, NULL, 0, DbgSwapCallback, NULL, NULL);
2044  if (!INT_SUCCESS(status))
2045  {
2046  ERROR("[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
2047  }
2048 }
2049 
2050 
2051 static void
2053  _In_ DWORD Argc,
2054  _In_ const char *Argv[]
2055  )
2056 {
2057  QWORD root;
2058  INTSTATUS status;
2059 
2060  if (Argc < 2)
2061  {
2062  ERROR("[ERROR] Invalid number of arguments!\n");
2063  return;
2064  }
2065 
2066  if (2 == Argc)
2067  {
2068  root = strtoull(Argv[1], NULL, 0);
2069  }
2070  else
2071  {
2072  QWORD eproc, rootPtr;
2073 
2074  if (0 != strncasecmp(Argv[1], "eproc", sizeof("eproc")))
2075  {
2076  return;
2077  }
2078 
2079  eproc = strtoull(Argv[2], NULL, 0);
2080  rootPtr = eproc + WIN_KM_FIELD(Process, VadRoot);
2081 
2082  LOG("Fetching VAD root @ 0x%016llx from eprocess 0x%016llx\n", eproc, rootPtr);
2083 
2084  status = IntKernVirtMemFetchQword(rootPtr, &root);
2085  if (!INT_SUCCESS(status))
2086  {
2087  ERROR("[ERROR] IntKernVirtMemFetchQword failed: 0x%08x\n", status);
2088  return;
2089  }
2090  }
2091 
2092  if (!IS_KERNEL_POINTER_WIN(gGuest.Guest64, root))
2093  {
2094  ERROR("[ERROR] VAD Root must be a kernel pointer! 0x%016llx\n", root);
2095  return;
2096  }
2097 
2098  status = IntWinVadInOrderRecursiveTraversal(root, 0, IntWinVadShortDump, NULL);
2099  if (!INT_SUCCESS(status))
2100  {
2101  ERROR("[ERROR] IntWinVadInOrderTraversal failed: 0x%08x\n", status);
2102  }
2103 }
2104 
2105 
2106 static void
2108  _In_ DWORD Argc,
2109  _In_ const char *Argv[]
2110  )
2111 {
2112  const char *pName = NULL;
2113 
2114  if (Argc >= 2)
2115  {
2116  pName = Argv[1];
2117  }
2118 
2119  LOG("Dumping VADs for %s...\n", pName ? pName : "all processes");
2120 
2121  IntWinProcDumpVads(pName);
2122 }
2123 
2124 
2125 static void
2127  _In_ DWORD Argc,
2128  _In_ const char *Argv[]
2129  )
2130 {
2131  QWORD vadroot, startpage, endpage, res;
2132 
2133  if (Argc != 4)
2134  {
2135  ERROR("[ERROR] Invalid number of arguments!\n");
2136  return;
2137  }
2138 
2139  vadroot = strtoull(Argv[1], 0, 0);
2140  startpage = strtoull(Argv[2], 0, 0);
2141  endpage = strtoull(Argv[3], 0, 0);
2142 
2143  LOG("Searching for VAD [%llx, %llx] starting with %llx...\n", startpage, endpage, vadroot);
2144 
2145  res = IntWinVadFindNodeInGuestSpace(vadroot, startpage, endpage, 0, 0, FALSE);
2146 
2147  LOG("Found VAD at %llx\n", res);
2148 }
2149 
2150 
2151 static void
2153  _In_ DWORD Argc,
2154  _In_ const char *Argv[]
2155  )
2156 {
2157  UNREFERENCED_PARAMETER(Argc);
2158  UNREFERENCED_PARAMETER(Argv);
2159 
2160  WARNING("[WARNING] Not implemented\n");
2161 }
2162 
2163 
2164 static void
2166  void
2167  )
2168 {
2169  gLoadPtDriver = TRUE;
2170 }
2171 
2172 
2173 static void
2175  void
2176  )
2177 {
2179 }
2180 
2181 
2182 static void
2184  void
2185  )
2186 {
2188 }
2189 
2190 
2191 static void
2193  void
2194  )
2195 {
2197 }
2198 
2199 
2200 static void
2202  _In_ DWORD Argc,
2203  _In_ const char *Argv[]
2204  )
2205 {
2206  DWORD i, count;
2207  BYTE instruction[16];
2208  INSTRUX instrux;
2209  MEMADDR glas[32];
2210  CHAR text[ND_MIN_BUF_SIZE];
2211 
2212  if (Argc < 2)
2213  {
2214  ERROR("[ERROR] Invalid number of arguments!\n");
2215  return;
2216  }
2217 
2218  /*
2219  Instructions to test:
2220  VPGATHERDD xmm1, [rax + xmm2], xmm3 ---- 0xC4 0xE2 0x61 0x90 0x0C 0x10
2221  VPGATHERQQ xmm1, [rax + xmm2], xmm3 ---- 0xC4 0xE2 0xE1 0x91 0x0C 0x10
2222  VPGATHERDD ymm1, [rax + ymm2], ymm3 ---- 0xC4 0xE2 0x65 0x90 0x0C 0x10
2223  VPGATHERQQ ymm1, [rax + ymm2], ymm3 ---- 0xC4 0xE2 0xE5 0x91 0x0C 0x10
2224 
2225  VPGATHERDD xmm1, [rax + xmm15 * 8], xmm3 ---- 0xC4 0xA2 0x61 0x90 0x0C 0xF8
2226  VPGATHERQQ xmm1, [rax + xmm15 * 8], xmm3 ---- 0xC4 0xA2 0xE1 0x91 0x0C 0xF8
2227  VPGATHERDD ymm1, [rax + ymm13 * 4], ymm3 ---- 0xC4 0xA2 0x65 0x90 0x0C 0xA8
2228  VPGATHERQQ ymm1, [rax + ymm13 * 4], ymm3 ---- 0xC4 0xA2 0xE5 0x91 0x0C 0xA8
2229 
2230  VPSCATTERDD [rax + zmm17], zmm23 ---- 0x62 0xE2 0x7D 0x40 0xA0 0x3C 0x08
2231  VPSCATTERQQ [rax + zmm17], zmm23 ---- 0x62 0xE2 0xFD 0x40 0xA1 0x3C 0x08
2232  */
2233 
2234  for (i = 1; i < Argc; i++)
2235  {
2236  instruction[i - 1] = (BYTE)strtoul(Argv[i], NULL, 0);
2237  }
2238 
2239  IntDecDecodeInstructionFromBuffer(instruction, 16, IG_CS_TYPE_64B, &instrux);
2240 
2241  NdToText(&instrux, 0, ND_MIN_BUF_SIZE, text);
2242 
2243  count = 32;
2244 
2245  IntDecGetAccessedMem(&instrux, NULL, NULL, glas, &count);
2246 
2247  LOG("Got %d accesses for '%s':\n", count, text);
2248 
2249  for (i = 0; i < count; i++)
2250  {
2251  LOG(" Access at %llx, size %d, access %d\n", glas[i].Gla, glas[i].Size, glas[i].Access);
2252  }
2253 }
2254 
2255 
2256 static void
2258  _In_ DWORD Argc,
2259  _In_ const char *Argv[]
2260  )
2261 {
2262  INTSTATUS status;
2263  QWORD va;
2264  BYTE patchedData[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
2265  BYTE origData[16];
2266  void *pClk;
2267 
2268  if (Argc < 2)
2269  {
2270  ERROR("[ERROR] Invalid number of arguments!\n");
2271  return;
2272  }
2273 
2274  va = strtoull(Argv[1], NULL, 0);
2275 
2276  status = IntKernVirtMemRead(va, sizeof(origData), &origData, NULL);
2277  if (!INT_SUCCESS(status))
2278  {
2279  ERROR("[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
2280  return;
2281  }
2282 
2283  status = IntMemClkCloakRegion(va, 0, 16, 0, patchedData, origData, NULL, &pClk);
2284  if (!INT_SUCCESS(status))
2285  {
2286  ERROR("[ERROR] IntMemClkCloakRegion failed: 0x%08x\n", status);
2287  return;
2288  }
2289 }
2290 
2291 
2292 static void
2294  _In_ DWORD Argc,
2295  _In_ const char *Argv[]
2296  )
2297 {
2298  PHOOK_CR hook;
2299  DWORD cr;
2300  INTSTATUS status;
2301 
2302  if (Argc < 2)
2303  {
2304  ERROR("[ERROR] Invalid number of arguments!\n");
2305  return;
2306  }
2307 
2308  cr = strtoul(Argv[1], NULL, 0);
2309 
2310  status = IntHookCrSetHook(cr, 0, DbgCrWriteTestCallback, NULL, &hook);
2311  if (!INT_SUCCESS(status))
2312  {
2313  ERROR("[ERROR] IntHookCrSetHook failed: 0x%08x\n", status);
2314  }
2315  else
2316  {
2317  LOG("HOOK -> %p\n", hook);
2318  }
2319 }
2320 
2321 
2322 static void
2324  _In_ DWORD Argc,
2325  _In_ const char *Argv[]
2326  )
2327 {
2328  QWORD hook;
2329  INTSTATUS status;
2330 
2331  if (Argc < 2)
2332  {
2333  ERROR("[ERROR] Invalid number of arguments!\n");
2334  return;
2335  }
2336 
2337  hook = strtoull(Argv[1], NULL, 0);
2338 
2339  status = IntHookCrRemoveHook((PHOOK_CR)hook);
2340  if (!INT_SUCCESS(status))
2341  {
2342  ERROR("[ERROR] IntHookCrRemoveHook failed: 0x%08x\n", status);
2343  }
2344 }
2345 
2346 
2347 static void
2349  void
2350  )
2351 {
2353 
2354  LOG("gFailAllocs is now %d\n", gFailAllocs);
2355 }
2356 
2357 
2358 static void
2360  void
2361  )
2362 {
2363  for (QWORD page = 0; page < 8 * 1024 * 1024; page++)
2364  {
2365  BYTE r, w, x;
2366  INTSTATUS status = IntGetEPTPageProtection(gGuest.UntrustedEptIndex, page << 12, &r, &w, &x);
2367  if (INT_SUCCESS(status))
2368  {
2369  if (r && !w)
2370  {
2371  LOG("EPT check failed on: %llx\n", page << 12);
2372  }
2373  }
2374  }
2375 }
2376 
2377 
2378 static void
2380  _In_ DWORD Argc,
2381  _In_ const char *Argv[]
2382  )
2383 {
2384  IG_LOG_LEVEL logLevel;
2385 
2386  if (Argc < 2)
2387  {
2388  ERROR("[ERROR] Invalid number of arguments!\n");
2389  return;
2390  }
2391 
2392  logLevel = (DWORD)strtoull(Argv[1], NULL, 0);
2393  if (logLevel > intLogLevelCritical)
2394  {
2395  ERROR("[ERROR] Invalid log level %d\n", logLevel);
2396  }
2397 
2398  gLogLevel = logLevel;
2399 }
2400 
2401 #include "swapgs.h"
2402 
2404 
2405 static void
2407  _In_ DWORD Argc,
2408  _In_ const char *Argv[]
2409  )
2410 {
2413 
2414  if (!swapgsMit)
2415  {
2417  LOG("Enabled SWAPGS mitigation!\n");
2418  swapgsMit = TRUE;
2419  }
2420  else
2421  {
2422  IntSwapgsUninit();
2423  LOG("Disabled SWAPGS mitigation!\n");
2424  swapgsMit = FALSE;
2425  }
2426 }
2427 
2428 
2429 typedef struct _DEBUGGER_COMMAND
2430 {
2431  const char *Command;
2432  const char *Help;
2433  const char *Parameters;
2434 
2435  union
2436  {
2439  };
2441 
2442 
2444 {
2445  {
2446  .Command = "!help",
2447  .Help = "show help",
2448  .FunctionNoArgs = DbgShowHelp,
2449  },
2450  {
2451  .Command = "!stats",
2452  .Help = "timing statistics for introspection callbacks",
2453  .FunctionNoArgs = IntStatsDumpAll,
2454  },
2455  {
2456  .Command = "!resetstats",
2457  .Help = "reset all the introcore statistics",
2458  .FunctionNoArgs = IntStatsResetAll,
2459  },
2460 #ifdef DEBUG_MEM_ALLOCS
2461  {
2462  .Command = "!allocs",
2463  .Help = "lists active memory allocations",
2464  .FunctionNoArgs = IntDbgDumpAllocs,
2465  },
2466  {
2467  .Command = "!check_allocs",
2468  .Help = "checks the current heap allocations for corruption",
2469  .FunctionNoArgs = IntDbgCheckAllocs,
2470  },
2471 #endif
2472  {
2473  .Command = "!detours",
2474  .Help = "list the detours",
2475  .FunctionNoArgs = IntDetDumpDetours,
2476  },
2477  {
2478  .Command = "!pfnlocks",
2479  .Help = "list the pfn locked pages (windows only)",
2480  .FunctionNoArgs = IntWinPfnDump,
2481  },
2482  {
2483  .Command = "!drivers_intro",
2484  .Help = "lists the drivers list inside the introspection",
2485  .FunctionNoArgs = IntDriverDump,
2486  },
2487  {
2488  .Command = "!drivers_guest",
2489  .Help = "lists the drivers loaded inside the guest",
2490  .FunctionNoArgs = DbgDumpGuestModules,
2491  },
2492  {
2493  .Command = "!gpf",
2494  .Help = "force page fault in guest",
2495  .Parameters = "gva: uint64; cr3: uint64; write: 0|1",
2496  .FunctionArgs = DbgInjectPf,
2497  },
2498  {
2499  .Command = "!pfn",
2500  .Help = "dump the pfn contents of the given virtual/physical address",
2501  .Parameters = "type: char v|p; addr: uint64",
2502  .FunctionArgs = DbgDumpPfn,
2503  },
2504  {
2505  .Command = "!dumpcb",
2506  .Help = "dump codeblocks from the given address",
2507  .Parameters = "gva: uint64; length: uint32 [default=end of page]; "
2508  "rip: uint64 [default=gva]; level: uint32 [default=1]",
2509  .FunctionArgs = DbgDumpCodeblocks,
2510  },
2511  {
2512  .Command = "!exceptions",
2513  .Help = "dump exceptions",
2514  .FunctionNoArgs = DbgDumpExceptions,
2515  },
2516  {
2517  .Command = "!hooks_gpa",
2518  .Help = "dump gpa hooks",
2519  .FunctionNoArgs = IntHookGpaDump,
2520  },
2521  {
2522  .Command = "!hooks_gva",
2523  .Help = "dump gva hooks",
2524  .FunctionNoArgs = DbgDumpHooksGva,
2525  },
2526  {
2527  .Command = "!hooks_check",
2528  .Help = "check hooks",
2529  .FunctionNoArgs = IntDbgCheckHooks,
2530  },
2531  {
2532  .Command = "!processes",
2533  .Help = "dump the list of active processes",
2534  .FunctionNoArgs = DbgDumpProcesses,
2535  },
2536  {
2537  .Command = "!process_tree",
2538  .Help = "dump the list of active processes as a tree (linux only)",
2539  .FunctionNoArgs = IntLixTaskDumpAsTree,
2540  },
2541  {
2542  .Command = "!procadd",
2543  .Help = "adds the process to the protected processes list",
2544  .Parameters = "process: string; protection: uint64",
2545  .FunctionArgs = DbgProcAdd,
2546  },
2547  {
2548  .Command = "!procrem",
2549  .Help = "removes the process from the protected processes",
2550  .Parameters = "process: string",
2551  .FunctionArgs = DbgProcRem,
2552  },
2553  {
2554  .Command = "!procclr",
2555  .Help = "remove all the protected processes",
2556  .FunctionNoArgs = DbgProcClear,
2557  },
2558  {
2559  .Command = "!proclst",
2560  .Help = "dump the list of protected processes",
2561  .FunctionNoArgs = DbgProcList,
2562  },
2563  {
2564  .Command = "!icache",
2565  .Help = "dump the instruction cache",
2566  .FunctionNoArgs = IntIcDumpIcache,
2567  },
2568  {
2569  .Command = "!gpacache",
2570  .Help = "dump the gpa cache",
2571  .FunctionNoArgs = DbgDumpGpaCache,
2572  },
2573  {
2574  .Command = "!disasm",
2575  .Help = "disassembles instructions from the given address",
2576  .Parameters = "gva: uint64; size: uint32",
2577  .FunctionArgs = DbgDisasm,
2578  },
2579  {
2580  .Command = "!integrity",
2581  .Help = "dump the integrity zones",
2582  .FunctionNoArgs = IntIntegrityDump,
2583  },
2584  {
2585  .Command = "!agent_inj",
2586  .Help = "inject an agent with the given name and tag",
2587  .Parameters = "name: string; tag: uint32",
2588  .FunctionArgs = DbgInjectAgent,
2589  },
2590  {
2591  .Command = "!file_inj",
2592  .Help = "inject an file agent with the given name",
2593  .Parameters = "name: string",
2594  .FunctionArgs = DbgInjectFileAgent,
2595  },
2596  {
2597  .Command = "!itva",
2598  .Help = "iterate the given VA space, searching for a specific pml4",
2599  .Parameters = "cr3: uint64; pml4: uint64",
2600  .FunctionArgs = DbgSearchVaSpace,
2601  },
2602  {
2603  .Command = "!itvaall",
2604  .Help = "iterate the VA space of all processes",
2605  .FunctionNoArgs = DbgIterateVaSpace,
2606  },
2607  {
2608  .Command = "!pwalk",
2609  .Help = "dump the GVA -> GPA translation",
2610  .Parameters = "gva: uin64; cr3: uint64",
2611  .FunctionArgs = DbgDumpTranslation,
2612  },
2613  {
2614  .Command = "!pts_hook",
2615  .Help = "place a hook for the given GVA inside the given VA-space",
2616  .Parameters = "cr3: uint64; va: uint64; id: uint64",
2617  .FunctionArgs = DbgPtsHook,
2618  },
2619  {
2620  .Command = "!pts_unhook",
2621  .Help = "remove the given hook",
2622  .Parameters = "pts: HOOK_PTS",
2623  .FunctionArgs = DbgPtsUnhook,
2624  },
2625  {
2626  .Command = "!pts_dump",
2627  .Help = "dump all the PTS hooks",
2628  .FunctionNoArgs = IntHookPtsDump,
2629  },
2630  {
2631  .Command = "!pts_write",
2632  .Help = "simulate a write inside the given pts entry",
2633  .Parameters = "pts: HOOK_PTS_ENTRY; oldvalue: uint64; newvalue: uint64",
2634  .FunctionArgs = DbgPtsWrite,
2635  },
2636  {
2637  .Command = "!cpus",
2638  .Help = "dump the cpu state",
2639  .FunctionNoArgs = DbgDumpCpuState,
2640  },
2641  {
2642  .Command = "!get_options",
2643  .Help = "dump the introcore current options",
2644  .FunctionNoArgs = DbgLogCoreOptions,
2645  },
2646  {
2647  .Command = "!set_options",
2648  .Help = "set the introcore current options",
2649  .Parameters = "options: uint64",
2650  .FunctionArgs = DbgSetCoreOptions,
2651  },
2652  {
2653  .Command = "!curproc",
2654  .Help = "dump the current process (windows only)",
2655  .FunctionNoArgs = DbgLogCurrentProcess,
2656  },
2657  {
2658  .Command = "!findksym",
2659  .Help = "dump the symbol name at the given address or address of the given symbol name",
2660  .Parameters = "gva|name: uint64|string",
2661  .FunctionArgs = DbgFindKsym,
2662  },
2663  {
2664  .Command = "!winpcr",
2665  .Help = "log the KPCR for all cpus (windows only)",
2666  .FunctionNoArgs = DbgLogKpcr,
2667  },
2668  {
2669  .Command = "!ptoken",
2670  .Help = "dump the process token for the given process (windows only)",
2671  .Parameters = "pid: uint32",
2672  .FunctionArgs = DbgDumpProcToken,
2673  },
2674  {
2675  .Command = "!ttoken",
2676  .Help = "dump the process token for the given ethread (windows only)",
2677  .Parameters = "ethread: uint64",
2678  .FunctionArgs = DbgDumpEthreadToken,
2679  },
2680  {
2681  .Command = "!vasdump",
2682  .Help = "dump the whole VA space of the given CR3",
2683  .Parameters = "cr3: uint64",
2684  .FunctionArgs = DbgDumpVaSpace,
2685  },
2686  {
2687  .Command = "!swap",
2688  .Help = "make the given GVA present (injecting a #PF if needed)",
2689  .Parameters = "cr3: uint64; gva: uin64; length: uint32; options: uint32",
2690  .FunctionArgs = DbgSwap,
2691  },
2692  {
2693  .Command = "!transactions",
2694  .Help = "dump the swap transactions",
2695  .FunctionNoArgs = IntSwapMemDump,
2696  },
2697  {
2698  .Command = "!vad",
2699  .Help = "dump all the vads for the given vad root (windows only)",
2700  .Parameters = "vad_root: uint64",
2701  .FunctionArgs = DbgDumpVadRoot,
2702  },
2703  {
2704  .Command = "!dump_vads",
2705  .Help = "dump the vad for the given process (or all process)",
2706  .Parameters = "name: string [optional]",
2707  .FunctionArgs = DbgDumpVads,
2708  },
2709  {
2710  .Command = "!findvad",
2711  .Help = "find and dump the given VAD inside de the given vad root (windows only)",
2712  .Parameters = "vadroot: uint64; startpage: uint64; endpage: uint64",
2713  .FunctionArgs = DbgVadFind,
2714  },
2715  {
2716  .Command = "!showfile",
2717  .Help = "log the file path for the given `struct file` (linux only)",
2718  .Parameters = "struct_file: uint64",
2719  .FunctionArgs = DbgLogFilePath,
2720  },
2721  {
2722  .Command = "!exploitguard",
2723  .Help = "dump the exploit guard mitigation flags for all processes (windows only)",
2724  .FunctionNoArgs = IntWinProcDumpEgFlags,
2725  },
2726  {
2727  .Command = "!netscan",
2728  .Help = "dump all the opened connections (windows only)",
2729  .FunctionNoArgs = IntWinNetDumpConnections,
2730  },
2731  {
2732  .Command = "!dump_clk",
2733  .Help = "dump all memory cloaks",
2734  .FunctionNoArgs = IntMemClkDump,
2735  },
2736  {
2737  .Command = "!pt_load",
2738  .Help = "inject the pt loader",
2739  .FunctionNoArgs = DbgLoadPt,
2740  },
2741  {
2742  .Command = "!pt_unload",
2743  .Help = "inject the pt unloader",
2744  .FunctionNoArgs = DbgUnloadPt,
2745  },
2746  {
2747  .Command = "!ptstatsall",
2748  .Help = "dump the pt stats",
2749  .FunctionNoArgs = IntPtiDumpStats,
2750  },
2751  {
2752  .Command = "!ve_load",
2753  .Help = "inject the ve loader",
2754  .FunctionNoArgs = DbgLoadVe,
2755  },
2756  {
2757  .Command = "!ve_unload",
2758  .Help = "inject the ve unloader",
2759  .FunctionNoArgs = DbgUnloadVe,
2760  },
2761  {
2762  .Command = "!veinfo",
2763  .Help = "dump the ve pages",
2764  .FunctionNoArgs = IntVeDumpVeInfoPages,
2765  },
2766  {
2767  .Command = "!vestats",
2768  .Help = "dump the ve stats",
2769  .FunctionNoArgs = IntVeDumpStats,
2770  },
2771  {
2772  .Command = "!testsse",
2773  .Help = "test sse instructions (access size)",
2774  .Parameters = "instr_bytes: BYTE[]",
2775  .FunctionArgs = DbgTestSse,
2776  },
2777  {
2778  .Command = "!testread",
2779  .Help = "put a memcloak on the given GVA (16 bytes)",
2780  .Parameters = "gva: uint64",
2781  .FunctionArgs = DbgTestRead,
2782  },
2783  {
2784  .Command = "!testcrhookset",
2785  .Help = "set a hook on the given CR",
2786  .Parameters = "cr: uint32",
2787  .FunctionArgs = DbgTestCrHookSet,
2788  },
2789  {
2790  .Command = "!testcrhookrem",
2791  .Help = "remove the given cr hook",
2792  .Parameters = "cr_hook: HOOK_CR",
2793  .FunctionArgs = DbgTestCrHookRem,
2794  },
2795  {
2796  .Command = "!failallocs",
2797  .Help = "fail allocations",
2798  .FunctionNoArgs = DbgFailAllocs,
2799  },
2800  {
2801  .Command = "!checkept",
2802  .Help = "preform an EPT check",
2803  .FunctionNoArgs = DbgCheckEpt,
2804  },
2805  {
2806  .Command = "!setloglevel",
2807  .Help = "sets the log level",
2808  .Parameters = "log_level: IG_LOG_LEVEL",
2809  .FunctionArgs = DbgSetLogLevel,
2810  },
2811  {
2812  .Command = "!swapgsmit",
2813  .Help = "mitigate SWAPGS",
2814  .FunctionArgs = DbgMitigateSwapgs,
2815  },
2816 
2817 
2818 };
2819 
2820 
2821 static void
2823  void
2824  )
2825 {
2826  for (DWORD i = 0; i < ARRAYSIZE(gDbgCommands) - 1; i++)
2827  {
2828  for (DWORD j = i; j < ARRAYSIZE(gDbgCommands); j++)
2829  {
2830  if (strcmp(gDbgCommands[i].Command, gDbgCommands[j].Command) > 0)
2831  {
2832  DEBUGGER_COMMAND cmd = gDbgCommands[i];
2833  gDbgCommands[i] = gDbgCommands[j];
2834  gDbgCommands[j] = cmd;
2835  }
2836  }
2837  }
2838 
2839  for (DWORD i = 0; i < ARRAYSIZE(gDbgCommands); i++)
2840  {
2841  const DEBUGGER_COMMAND *cmd = &gDbgCommands[i];
2842 
2843  NLOG("%-17s %s\n", cmd->Command, cmd->Help);
2844 
2845  if (cmd->Parameters)
2846  {
2847  NLOG(" %s\n", cmd->Parameters);
2848  }
2849  }
2850 }
2851 
2852 
2853 //
2854 // IntDbgProcessCommand
2855 //
2856 INTSTATUS
2858  _In_ DWORD Argc,
2859  _In_ const char *Argv[]
2860  )
2861 {
2862  BOOLEAN found = FALSE;
2863 
2864  if (NULL == Argv)
2865  {
2867  }
2868 
2869  // Ignore empty commands (shouldn't really happen).
2870  if (Argc == 0)
2871  {
2872  return INT_STATUS_SUCCESS;
2873  }
2874 
2876 
2877  for (DWORD i = 0; i < ARRAYSIZE(gDbgCommands); i++)
2878  {
2879  DEBUGGER_COMMAND *pCmd = &gDbgCommands[i];
2880 
2881  if (0 != strcmp(pCmd->Command, Argv[0]))
2882  {
2883  continue;
2884  }
2885 
2886  if (pCmd->Parameters)
2887  {
2888  pCmd->FunctionArgs(Argc, Argv);
2889  }
2890  else
2891  {
2892  pCmd->FunctionNoArgs();
2893  }
2894 
2895  found = TRUE;
2896 
2897  break;
2898  }
2899 
2900  if (!found)
2901  {
2902  ERROR("[ERROR] Invalid command: `%s`\n", Argv[0]);
2903  }
2904 
2906 
2907  return INT_STATUS_SUCCESS;
2908 }
static void DbgDumpUmExceptionGlobMatch(UM_EXCEPTION_GLOB *Exception)
Definition: debugger.c:344
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:419
static QWORD gTargetPML4
Definition: debugger.c:94
#define _In_opt_
Definition: intro_sal.h:16
INTSTATUS IntDecGetAccessedMem(PINSTRUX Instrux, PIG_ARCH_REGS Registers, PIG_XSAVE_AREA XsaveArea, MEMADDR *Gla, DWORD *Count)
Decode each accessed address by an instruction.
Definition: decoder.c:3160
QWORD PhysicalAddress
The physical address to which VirtualAddress translates to.
Definition: introcore.h:107
void IntIcDumpIcache(void)
Dumps the entire contents of the implicit, per guest, instruction cache.
Definition: icache.c:55
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
#define CONTAINING_RECORD(List, Type, Member)
Definition: introlists.h:36
static void DbgLogKpcr(void)
Definition: debugger.c:1883
#define GPA_HOOK_TABLE_SIZE
Size of the GPA hook hash.
Definition: hook_gpa.h:87
HOOK_HEADER Header
Hook header.
Definition: hook_gpa.h:43
long long INT64
Definition: intro_types.h:45
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
Definition: introcore.c:2234
uint16_t * PWORD
Definition: intro_types.h:48
PFUNC_DebuggerFunctionNoArgs FunctionNoArgs
Definition: debugger.c:2438
WORD Length
Definition: hook_gva.h:34
void(* PFUNC_DebuggerFunctionArgs)(DWORD Argc, const char *Argv[])
Definition: debugger.c:37
QWORD MmPfnDatabase
Guest virtual address of the PFN data base.
Definition: winguest.h:837
LIST_HEAD GpaHooksWrite[GPA_HOOK_TABLE_SIZE]
Hash table of write hooks.
Definition: hook_gpa.h:106
BOOLEAN IsPageWritable
True if the page is writable, false otherwise.
Definition: hook_gva.h:40
Handling MSR violation.
Definition: guests.h:23
uint8_t BYTE
Definition: intro_types.h:47
Read-access hook.
Definition: glueiface.h:298
A Windows token structure as reported by Introcore alerts.
Definition: intro_types.h:861
Describe a export signature hash.
Definition: exceptions.h:387
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
Definition: winguest.c:37
static QWORD gPagesDirty
Definition: debugger.c:115
static void DbgSearchVaSpace(DWORD Argc, const char *Argv[])
Definition: debugger.c:1579
Describes a process-creation signature.
Definition: exceptions.h:574
LIST_HEAD ValueCodeSignatures
Linked list used for value-code signatures.
Definition: exceptions.h:133
HOOK_GVA_STATE GvaHooks
GVA hooks state.
Definition: hook.h:93
IG_ARCH_REGS Regs
The current state of the guest registers.
Definition: guests.h:95
DWORD Index
The VCPU number.
Definition: guests.h:172
static void DbgDumpUmException(UM_EXCEPTION *Exception)
Definition: debugger.c:296
static void DbgDumpEthreadToken(DWORD Argc, const char *Argv[])
Definition: debugger.c:1954
#define _In_
Definition: intro_sal.h:21
static void DbgVadFind(DWORD Argc, const char *Argv[])
Definition: debugger.c:2126
QWORD SystemCr3
The Cr3 used to map the kernel.
Definition: guests.h:211
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
LIST_ENTRY64 InLoadOrderLinks
Definition: wddefs.h:203
Up & running.
Definition: guests.h:21
BYTE Score
The number of (minimum) hashes from a list that need to match.
Definition: exceptions.h:404
INTSTATUS IntHookPtsWriteEntry(PHOOK_PTS_ENTRY Entry, QWORD OldValue, QWORD NewValue)
Tests the translation modification handler.
Definition: hook_pts.c:2216
LIST_HEAD NoNameKernelExceptions
Linked list used for kernel-mode exceptions that don&#39;t have a valid originator (-).
Definition: exceptions.h:97
#define PAGE_REMAINING(addr)
Definition: pgtable.h:163
BOOLEAN IsWritable
True if this page is writable.
Definition: introcore.h:132
uint16_t WORD
Definition: intro_types.h:48
Describes a value signature.
Definition: exceptions.h:415
PFUNC_HpFreeWithTagAndInfo MemFreeWithTagAndInfo
Definition: upperiface.h:272
const char * Command
Definition: debugger.c:2431
void IntVeDumpStats(void)
Dump VE statistics.
Definition: vecore.c:2719
#define IC_TAG_CDBK
Code blocks.
Definition: memtags.h:31
static uint8_t _bittestandset64(int64_t *BitBase, int64_t BitPos)
Definition: intrinsics.h:150
static void DbgDumpGpaCache(void)
Definition: debugger.c:1485
LIST_HEAD GenericUserExceptions
Linked list used for user-mode exceptions that have a generic originator(*).
Definition: exceptions.h:91
INTSTATUS IntSwapMemReadData(QWORD Cr3, QWORD VirtualAddress, DWORD Length, DWORD Options, void *Context, DWORD ContextTag, PFUNC_PagesReadCallback Callback, PFUNC_PreInjectCallback PreInject, void **SwapHandle)
Reads a region of guest virtual memory, and calls the indicated callback when all the data is availab...
Definition: swapmem.c:417
struct _LIST_ENTRY * Flink
Definition: introlists.h:20
static void DbgDumpExceptions(void)
Definition: debugger.c:981
LIST_HEAD ExportSignatures
Linked list used for export signatures.
Definition: exceptions.h:131
BOOLEAN gLoadPtDriver
Definition: callbacks.c:31
INTSTATUS IntHookCrSetHook(DWORD Cr, DWORD Flags, PFUNC_CrWriteHookCallback Callback, void *Context, HOOK_CR **Hook)
Set a control register write hook.
Definition: hook_cr.c:11
WORD Object[]
Contains list of opcodes.
Definition: exceptions.h:426
INTSTATUS IntKsymFindByAddress(QWORD Gva, DWORD Length, char *SymName, QWORD *SymStart, QWORD *SymEnd)
Finds the symbol which is located at the given address.
Definition: lixksym.c:1283
Describes a memory address, as used in an instruction.
Definition: decoder.h:39
struct _HOOK_PTS_ENTRY * PHOOK_PTS_ENTRY
void FUNC_RbTreeNodeFree(RBNODE *Node)
Definition: rbtree.h:47
struct _SIG_CODEBLOCK_HASH SIG_CODEBLOCK_HASH
Describe a codeblocks signature hash.
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
static void DbgMitigateSwapgs(DWORD Argc, const char *Argv[])
Definition: debugger.c:2406
BOOLEAN IsIntegrityOn
True if integrity checks are enabled for this page. Integrity checks are enabled if the this is a wri...
Definition: hook_gva.h:39
EXCEPTION_SIGNATURE_ID Id
An unique id (_EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:401
LIST_HEAD gWinProcesses
The list of all the processes inside the guest.
Definition: winprocesshp.c:11
WORD Offset
Offset inside the 4K page, interval [0, 4095].
Definition: hook_gva.h:33
LIST_HEAD RemovedHooksList
IntHookGvaCommitHooks function is called.
Definition: hook_gva.h:50
Definition: rbtree.h:34
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:578
#define ARRAYSIZE(A)
Definition: introdefs.h:101
INTSTATUS IntDepInjectFile(BYTE *FileContent, DWORD FileSize, const CHAR *Name)
Inject a file inside the guest.
Definition: deployer.c:56
LIST_HEAD VersionIntroSignatures
Linked list used for introspection version signatures.
Definition: exceptions.h:136
static void DbgDumpPfn(DWORD Argc, const char *Argv[])
Definition: debugger.c:782
Describe a user-mode glob exception.
Definition: exceptions.h:336
INTSTATUS RbLookupNode(RBTREE *Tree, RBNODE *NodeToSearch, RBNODE **NodeFound)
Definition: rbtree.c:517
INTSTATUS IntVasDump(QWORD Cr3)
Dump the monitored tables for the indicated Cr3.
Definition: vasmonitor.c:1077
IG_LOG_LEVEL gLogLevel
The currently used log level.
Definition: glue.c:68
LIST_HEAD ProcessCreationSignatures
Linked list used for process-creation signatures.
Definition: exceptions.h:137
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:442
INTSTATUS IntWinGetAccesTokenFromThread(QWORD EthreadGva, INTRO_WIN_TOKEN *Token)
Reads the contents of a _TOKEN Windows structure assigned to a thread.
Definition: visibility.c:524
void IntWinProcDumpVads(const char *ProcessName)
Prints information about the VADs loaded in a process.
Definition: winprocesshp.c:977
BYTE EptHookType
The type of the hook in EPT (see IG_EPT_HOOK_TYPE)
Definition: hook.h:69
static void DbgFindKsym(DWORD Argc, const char *Argv[])
Definition: debugger.c:1835
LIST_HEAD IdtSignatures
Linked list used for IDT signatures.
Definition: exceptions.h:134
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:437
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
#define ERROR(fmt,...)
Definition: glue.h:62
#define ONE_MEGABYTE
Definition: introdefs.h:90
BYTE Entry
The number of the IDT entry.
Definition: exceptions.h:477
INTSTATUS IntWinNetDumpConnections(void)
Dump all active guest connections.
Definition: winnet.c:1824
static void DbgLoadPt(void)
Definition: debugger.c:2165
Handling a CR load.
Definition: guests.h:25
LIST_ENTRY32 InLoadOrderLinks
Definition: wddefs.h:174
BOOLEAN gInjectVeUnloader
Definition: callbacks.c:30
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
INTSTATUS IntWinGetAccessTokenFromProcess(DWORD ProcessId, QWORD EprocessGva, INTRO_WIN_TOKEN *Token)
Reads the contents of a _TOKEN Windows structure assigned to a process.
Definition: visibility.c:458
DWORD Buffer
The guest virtual address at which the wide-character string is located.
Definition: wddefs.h:129
#define PHYS_PAGE_MASK
Definition: pgtable.h:38
LIST_HEAD UserExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for user-mode exceptions.
Definition: exceptions.h:109
int INTSTATUS
The status data type.
Definition: introstatus.h:24
QWORD GvaPage
Guest virtual page base address, aligned to 4K.
Definition: hook_gva.h:32
static void DbgSetLogLevel(DWORD Argc, const char *Argv[])
Definition: debugger.c:2379
Shows only critical logs.
Definition: glueiface.h:395
int FUNC_RbTreeNodeCompare(RBNODE *Left, RBNODE *Right)
Definition: rbtree.h:59
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
void IntStatsResetAll(void)
Resets all the stats.
Definition: stats.c:299
HOOK_STATE * gHooks
Global hooks state.
Definition: hook.c:8
static void DbgProcAdd(DWORD Argc, const char *Argv[])
Definition: debugger.c:1317
void IntSwapgsUninit(void)
Uninit the SWAPGS mitigation.
Definition: swapgs.c:446
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:456
void IntSwapMemDump(void)
Dump all active transactions & pages.
Definition: swapmem.c:1066
BOOLEAN IsExecutable
True if this page is executable.
Definition: introcore.h:136
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
Definition: introcore.c:2264
#define TRFLG_NONE
No special options.
Definition: introcore.h:82
UNICODE_STRING32 DriverPath
Definition: wddefs.h:180
#define MAX_PATH
The maximum size of a path (260 characters on windows).
Definition: winpe.h:579
union _SIG_VERSION_INTRO::@38 Minimum
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
Definition: guests.h:372
#define __FILE_TAG__
Definition: introdefs.h:86
static void DbgDumpHooksGva(void)
Definition: debugger.c:1250
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:278
static void DbgLogCoreOptions(void)
Definition: debugger.c:1786
DWORD Flink
Definition: wddefs.h:155
void * gIntHandle
The guest handle provided by the integrator at initialization.
Definition: glue.c:49
INTSTATUS IntIterateVirtualAddressSpace(QWORD Cr3, PFUNC_VirtualAddressSpaceCallback Callback)
Iterate an entire virtual address space.
Definition: kernvm.c:327
static QWORD gPagesWrite
Definition: debugger.c:115
static INTSTATUS DbgCrWriteTestCallback(void *Context, DWORD Cr, QWORD OldValue, QWORD NewValue, INTRO_ACTION *Action)
Definition: debugger.c:392
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:460
static void DbgProcClear(void)
Definition: debugger.c:1460
#define LOG(fmt,...)
Definition: glue.h:61
Describes a value signature.
Definition: exceptions.h:452
32-bit selector.
Definition: glueiface.h:187
INTSTATUS IntHookPtsSetHook(QWORD Cr3, QWORD VirtualAddress, PFUNC_SwapCallback Callback, void *Context, void *Parent, DWORD Flags, PHOOK_PTS *Hook)
Start monitoring translation modifications for the given VirtualAddress.
Definition: hook_pts.c:1535
void IntLixTaskDumpProtected(void)
Dumps the list with processes that Introcore should protect.
Definition: lixprocess.c:4869
INTSTATUS IntFragDumpBlocks(PBYTE Buffer, QWORD StartAddress, DWORD MaxBufferSize, IG_CS_TYPE CsType, CB_EXTRACT_LEVEL ExtractLevel, QWORD Rip, BOOLEAN ReturnRip)
Dumps code-blocks that can then be used to generate an exception signature.
Definition: codeblocks.c:1293
static void DbgSetCoreOptions(DWORD Argc, const char *Argv[])
Definition: debugger.c:1795
static INTSTATUS DbgSwapCallback(void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
Definition: debugger.c:48
INTSTATUS IntAddRemoveProtectedProcessUtf8(void *GuestHandle, const CHAR *FullPath, DWORD ProtectionMask, BOOLEAN Add, QWORD Context)
Toggles protection options for a process.
Definition: introapi.c:299
static void DbgPtsHook(DWORD Argc, const char *Argv[])
Definition: debugger.c:1676
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:579
QWORD Cr3
Process PDBR. Includes PCID.
Definition: winprocess.h:98
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
Definition: introcore.h:123
static void DbgDumpProcesses(void)
Definition: debugger.c:1301
static QWORD gPagesRead
Definition: debugger.c:115
The _LDR_DATA_TABLE_ENTRY structure used by 64-bit guests.
Definition: wddefs.h:201
static void DbgDumpVads(DWORD Argc, const char *Argv[])
Definition: debugger.c:2107
LIST_HEAD CbSignatures
Linked list used for codeblocks signatures.
Definition: exceptions.h:130
void IntLixTaskDump(void)
Dumps the process list.
Definition: lixprocess.c:4797
LIST_HEAD GpaHooksRead[GPA_HOOK_TABLE_SIZE]
Hash table of read hooks.
Definition: hook_gpa.h:107
static void DbgTestSse(DWORD Argc, const char *Argv[])
Definition: debugger.c:2201
#define PT_RW
Definition: pgtable.h:84
#define _Inout_
Definition: intro_sal.h:20
INTSTATUS IntDbgProcessCommand(DWORD Argc, const char *Argv[])
Definition: debugger.c:2857
static void DbgPtsUnhook(DWORD Argc, const char *Argv[])
Definition: debugger.c:1710
INTSTATUS IntKernVirtMemFetchDword(QWORD GuestVirtualAddress, DWORD *Data)
Reads 4 bytes from the guest kernel memory.
Definition: introcore.c:829
INTSTATUS IntFindKernelPcr(DWORD CpuNumber, QWORD *Pcr)
Finds the address of the Windows kernel _KPCR.
Definition: introcpu.c:1116
void IntWinProcDumpProtected(void)
Log all the protected processes.
Definition: winprocess.c:3912
EXCEPTIONS * Exceptions
The exceptions that are currently loaded.
Definition: guests.h:392
INTSTATUS IntRemoveAllProtectedProcesses(void *GuestHandle)
Removes the protection policies for all processes.
Definition: introapi.c:522
void IntHookGpaDump(void)
Dump the entire contents of the GPA hook system, listing each hook.
Definition: hook_gpa.c:1156
QWORD PsLoadedModuleList
Guest virtual address of the PsLoadedModuleList kernel variable.
Definition: winguest.h:836
static void IntDbgCheckHooks(void)
Definition: debugger.c:182
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
Definition: introcore.c:811
DWORD LibraryNameHash
The name-hash of the modified library.
Definition: exceptions.h:440
uint8_t * PBYTE
Definition: intro_types.h:47
BOOLEAN PaeEnabled
True if Physical Address Extension is enabled.
Definition: guests.h:295
QWORD MappingsEntries[MAX_TRANSLATION_DEPTH]
Contains the entry in which paging table.
Definition: introcore.h:115
static INTSTATUS DbgVaModificationHandler(void *Context, QWORD VirtualAddress, QWORD OldEntry, QWORD NewEntry, QWORD OldPageSize, QWORD NewPageSize)
Definition: debugger.c:69
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:475
struct _DEBUGGER_COMMAND DEBUGGER_COMMAND
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
Definition: introlists.h:87
static void DbgDumpGuestModules(void)
Definition: debugger.c:652
QWORD Flink
Definition: wddefs.h:164
CPU_STATE State
The state of this VCPU. Describes what action is the VCPU currently doing.
Definition: guests.h:173
UINT16 Length
The length, in bytes, of the string in Buffer, not including the NULL terminator, if any...
Definition: wddefs.h:123
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
CHAR Object[]
Contains lists of (SIG_EXPORT_HASH).
Definition: exceptions.h:445
unsigned long long QWORD
Definition: intro_types.h:53
CHAR Name[IMAGE_BASE_NAME_LEN]
Process base name.
Definition: winprocess.h:108
QWORD Current
The currently used options.
Definition: guests.h:236
Handling a LIDT or LGDT.
Definition: guests.h:26
static void DbgDumpCpuState(void)
Definition: debugger.c:1766
QWORD IdtBase
Original IDT base.
Definition: guests.h:110
void IntDetDumpDetours(void)
Prints all the detours in the gDetours list of detours.
Definition: detours.c:1895
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:474
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
Definition: introcore.c:1999
static void DbgLoadVe(void)
Definition: debugger.c:2183
HOOK_HEADER Header
The hook header.
Definition: hook_gva.h:20
void * GpaCache
The currently used GPA cache.
Definition: guests.h:403
QWORD GpaPage
The page where the hook is set.
Definition: hook_gpa.h:46
#define TRUE
Definition: intro_types.h:30
void IntWinDumpToken(INTRO_WIN_TOKEN const *Token)
Prints a INTRO_WIN_TOKEN structure.
Definition: visibility.c:626
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
Definition: decoder.c:308
static void DbgTestCrHookRem(DWORD Argc, const char *Argv[])
Definition: debugger.c:2323
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
Definition: wddefs.h:76
#define __must_check
Definition: introtypes.h:48
Describe a value signature hash.
Definition: exceptions.h:376
Describes a introspection version signature.
Definition: exceptions.h:531
INTSTATUS IntDepInjectProcess(DWORD AgentTag, BYTE *AgentContent, DWORD AgentSize, const CHAR *Name, const CHAR *Args)
Injects a process inside the guest.
Definition: deployer.c:12
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
This includes instructions until codeInsBt.
Definition: codeblocks.h:16
BOOLEAN swapgsMit
Definition: debugger.c:2403
INTSTATUS IntHookPtsRemoveHook(HOOK_PTS **Hook, DWORD Flags)
Remove a PTS hook.
Definition: hook_pts.c:1944
const char * Help
Definition: debugger.c:2432
static void DbgDumpKmException(KM_EXCEPTION *Exception)
Definition: debugger.c:249
INTSTATUS IntMemClkCloakRegion(QWORD VirtualAddress, QWORD Cr3, DWORD Size, DWORD Options, PBYTE OriginalData, PBYTE PatchedData, PFUNC_IntMemCloakWriteHandle WriteHandler, void **CloakHandle)
Hides a memory zone from the guest.
Definition: memcloak.c:548
INTSTATUS IntHookCrRemoveHook(HOOK_CR *Hook)
Remove a control register hook.
Definition: hook_cr.c:135
Describes the internal exceptions data.
Definition: exceptions.h:86
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:438
static void DbgProcRem(DWORD Argc, const char *Argv[])
Definition: debugger.c:1389
static void DbgDisasm(DWORD Argc, const char *Argv[])
Definition: debugger.c:1494
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:490
The _LDR_DATA_TABLE_ENTRY structure used by 32-bit guests.
Definition: wddefs.h:172
static void DbgInjectFileAgent(DWORD Argc, const char *Argv[])
Definition: debugger.c:1553
LIST_HEAD GvaHooks
The list of GVA hooks.
Definition: hook_gva.h:49
Describes a export signature.
Definition: exceptions.h:433
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:135
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
Definition: introcore.c:1863
size_t strlcpy(char *dst, const char *src, size_t dest_size)
Definition: introcrt.c:1093
Handling XSETBV.
Definition: guests.h:28
static INTSTATUS DbgVaSpaceIterationCallback(QWORD Cr3, QWORD VirtualAddress, QWORD Entry, QWORD PageSize)
Definition: debugger.c:98
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:420
static void DbgDumpTranslation(DWORD Argc, const char *Argv[])
Definition: debugger.c:1639
#define WARNING(fmt,...)
Definition: glue.h:60
DWORD Pid
Process ID (the one used by Windows).
Definition: winprocess.h:100
HOOK_GPA_STATE GpaHooks
GPA hooks state.
Definition: hook.h:92
static void DbgUnloadPt(void)
Definition: debugger.c:2174
#define LIX_SYMBOL_NAME_LEN
The max length of the ksym as defined by Linux kernel.
Definition: lixguest.h:585
DWORD CpuCount
The number of logical CPUs.
Definition: guests.h:279
static void DbgTestCrHookSet(DWORD Argc, const char *Argv[])
Definition: debugger.c:2293
void IntWinProcDump(void)
Prints information about all the processes in the system.
Definition: winprocesshp.c:864
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
static INTSTATUS DbgVaSpaceIterationCallbackCount(QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, QWORD PageSize)
Definition: debugger.c:120
void IntMemClkDump(void)
Dumps all the active cloak regions.
Definition: memcloak.c:1218
void IntStatsDumpAll(void)
Prints all the non-zero stats.
Definition: stats.c:220
BOOLEAN gUnloadPtDriver
Definition: callbacks.c:31
void IntWinPfnDump(void)
Prints all the PFN locks.
Definition: winpfn.c:901
Describe a kernel-mode exception.
Definition: exceptions.h:253
union _SIG_VERSION_INTRO::@39 Maximum
Describe a user-mode exception.
Definition: exceptions.h:308
PHOOK_GPA GpaHook
The actual guest physical page hook. Valid as long as the page is mapped.
Definition: hook_gva.h:30
uint16_t WCHAR
Definition: intro_types.h:63
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
Definition: winguest.h:740
static void DbgShowHelp(void)
Definition: debugger.c:2822
#define WIN_PFN_GET_STRUCT_VA(MmPfn, Gpa)
Get the address of a guest _MMPFN structure.
Definition: winpfn.h:60
uint32_t DWORD
Definition: intro_types.h:49
#define IC_TAG_DEBUG
Debugger stuff.
Definition: memtags.h:27
#define EXCEPTION_TABLE_SIZE
Definition: exceptions.h:49
DWORD Hashes[]
The list of hashes.
Definition: exceptions.h:369
void IntPtiDumpStats(void)
Dump PT filtering statistics.
Definition: ptfilter.c:907
static DEBUGGER_COMMAND gDbgCommands[]
Definition: debugger.c:2443
static void DbgSwap(DWORD Argc, const char *Argv[])
Definition: debugger.c:2021
LIST_HEAD GlobUserExceptions
Linked list used for user-mode exceptions that contains glob content.
Definition: exceptions.h:105
BYTE Count
The number of hashes from the list.
Definition: exceptions.h:368
enum _INTRO_ACTION INTRO_ACTION
Event actions.
#define _At_(expr, arg)
Definition: intro_sal.h:23
#define _In_reads_bytes_(expr)
Definition: intro_sal.h:25
static void DbgInjectAgent(DWORD Argc, const char *Argv[])
Definition: debugger.c:1526
Definition: rbtree.h:84
LIST_HEAD GenericKernelExceptions
Linked list used for kernel-mode exceptions that have a generic originator (*).
Definition: exceptions.h:89
UINT64 __cdecl strtoull(const INT8 *nptr, INT8 **endptr, INT32 ibase)
Definition: conv.c:154
INTSTATUS IntGetEPTPageProtection(DWORD EptIndex, QWORD Gpa, BYTE *Read, BYTE *Write, BYTE *Execute)
Definition: glue.c:659
static void DbgIterateVaSpace(void)
Definition: debugger.c:1604
static void DbgCheckEpt(void)
Definition: debugger.c:2359
static void DbgInjectPf(DWORD Argc, const char *Argv[])
Definition: debugger.c:755
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
Definition: introcore.c:2134
UNICODE_STRING64 DriverPath
Definition: wddefs.h:209
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Definition: guests.h:374
void IntGpaCacheDump(PGPA_CACHE Cache)
Dumps the entire contents of the GPA cache.
Definition: gpacache.c:65
QWORD EprocessAddress
This will be the address of the ActiveProcess field.
Definition: winprocess.h:90
LIST_HEAD ValueSignatures
Linked list used for value signatures.
Definition: exceptions.h:132
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:457
void IntLixTaskDumpAsTree(void)
Dump the process tree.
Definition: lixprocess.c:4784
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:491
UINT32 __cdecl strtoul(const INT8 *nptr, INT8 **endptr, INT32 ibase)
Definition: conv.c:122
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
void IntIntegrityDump(void)
Dumps all the INTEGRITY_REGION structures from gIntegrityRegions. Used mainly for debugging...
Definition: integrity.c:486
BOOLEAN gInjectVeLoader
Definition: callbacks.c:30
#define _Function_class_(expr)
Definition: intro_sal.h:40
static void DbgUnloadVe(void)
Definition: debugger.c:2192
static void DbgPtsWrite(DWORD Argc, const char *Argv[])
Definition: debugger.c:1736
#define FIX_GUEST_POINTER(is64, x)
Masks the unused part of a Windows guest virtual address.
Definition: wddefs.h:87
LIST_HEAD GpaHooksExecute[GPA_HOOK_TABLE_SIZE]
Hash table of execute hooks.
Definition: hook_gpa.h:108
#define IC_TAG_ALLOC
Memory allocation.
Definition: memtags.h:28
static void DbgDumpCodeblocks(DWORD Argc, const char *Argv[])
Definition: debugger.c:881
enum _IG_LOG_LEVEL IG_LOG_LEVEL
Controls the verbosity of the logs.
void(* PFUNC_DebuggerFunctionNoArgs)(void)
Definition: debugger.c:42
#define PT_D
Definition: pgtable.h:89
Handling a timer event.
Definition: guests.h:27
struct _HOOK_PTS * PHOOK_PTS
QWORD MappingsTrace[MAX_TRANSLATION_DEPTH]
Contains the physical address of each entry within the translation tables.
Definition: introcore.h:111
BYTE Score
The number of (minimum) hashes from a list that need to match.
Definition: exceptions.h:459
void RbDeleteNode(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:710
DWORD Flags
Contains any flags from SIGNATURE_FLG.
Definition: exceptions.h:536
static void DbgLogFilePath(DWORD Argc, const char *Argv[])
Definition: debugger.c:2152
static void DbgLogCurrentProcess(void)
Definition: debugger.c:1817
WORD Length
The length of the opcode pattern.
Definition: exceptions.h:423
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
Definition: introcore.c:674
LIST_HEAD KernelExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for kernel-mode exceptions.
Definition: exceptions.h:107
BYTE ListsCount
The number of the list of hashes.
Definition: exceptions.h:405
#define VECTOR_PF
Definition: processor.h:116
INTSTATUS IntSwapgsStartMitigation(void)
Scan the kernel for vulnerable SWAPGS gadgets, and mitigate CVE-2019-1125, when such gadgets are foun...
Definition: swapgs.c:190
#define NLOG(fmt,...)
Definition: glue.h:43
INTSTATUS IntWinVadInOrderRecursiveTraversal(QWORD VadNodeGva, DWORD Level, PFUNC_WinVadTraversalCallback Callback, void *Context)
Traverses a guest VAD tree.
Definition: winvad.c:1920
#define LIST_HEAD_INIT(Name)
Definition: introlists.h:39
INTSTATUS RbInsertNode(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:606
BOOLEAN gFailAllocs
Definition: debugger.c:27
WORD Length
The length, in bytes, of the string in Buffer, not including the NULL terminator, if any...
Definition: wddefs.h:139
const char * Parameters
Definition: debugger.c:2433
QWORD Value
Contains the minimum build number of the operating system (used for windows).
Definition: exceptions.h:507
Describes a idt signature.
Definition: exceptions.h:470
Encapsulates information about a virtual to physical memory translation.
Definition: introcore.h:102
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
Definition: introcore.c:2845
DWORD Value
Contains an unique value.
Definition: exceptions.h:242
static UPPER_IFACE gUpIface
The instance of UPPER_IFACE that is being used.
Definition: glue.c:44
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:59
#define _next(_var, _member)
Definition: introlists.h:48
DWORD CreateMask
Contains the DPI mask.
Definition: exceptions.h:583
64-bit selector.
Definition: glueiface.h:188
static void DbgDumpProcToken(DWORD Argc, const char *Argv[])
Definition: debugger.c:1916
void IntGuestUpdateCoreOptions(QWORD NewOptions)
Updates Introcore options.
Definition: guests.c:1426
void IntDriverDump(void)
Prints all the currently loaded drivers.
Definition: drivers.c:391
INT16 Offset
The displacement from the beginning of the modified zone.
Definition: exceptions.h:422
void IntDisasmGva(QWORD Gva, DWORD Length)
This function disassembles a code buffer (given its GVA) and then dumps the instructions (textual dis...
Definition: dumper.c:432
DWORD Flags
Generic flags. Check out EPT Hook flags.
Definition: hook.h:67
INTSTATUS IntWinVadShortDump(QWORD VadNodeGva, DWORD Level, void *Context)
Prints a _MMVAD_SHORT structure.
Definition: winvad.c:1659
CHAR Object[]
Contains list of (SIG_CODEBLOCK_HASH).
Definition: exceptions.h:408
#define UNREFERENCED_LOCAL_VARIABLE(V)
Definition: introdefs.h:30
void IntWinProcDumpEgFlags(void)
Prints the mitigation flags of a process.
Execute-access hook.
Definition: glueiface.h:300
static void DbgTestRead(DWORD Argc, const char *Argv[])
Definition: debugger.c:2257
#define RB_TREE_INIT(Name, Free, Compare)
Initializes a RBTREE structure.
Definition: introcore.h:39
union _SIG_VERSION_OS::@33 Maximum
char CHAR
Definition: intro_types.h:56
#define IntWinGetCurrentProcess()
Definition: winprocesshp.h:20
PFUNC_DebuggerFunctionArgs FunctionArgs
Definition: debugger.c:2437
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
Definition: lixksym.c:1399
static void DbgFailAllocs(void)
Definition: debugger.c:2348
CHAR Object[]
Contains lists of (SIG_VALUE_HASH).
Definition: exceptions.h:463
EXCEPTION_SIGNATURE_ID Id
An unique id (EXCEPTION_SIGNATURE_ID).
Definition: exceptions.h:535
Write-access hook.
Definition: glueiface.h:299
static void DbgDumpVadRoot(DWORD Argc, const char *Argv[])
Definition: debugger.c:2052
Describes a codeblocks signature.
Definition: exceptions.h:397
DWORD Flags
Contains any flags from _SIGNATURE_FLG.
Definition: exceptions.h:402
BOOLEAN IsUser
True if this page is accessible to user mode code.
Definition: introcore.h:128
DWORD UntrustedEptIndex
The EPTP index of the untrusted EPT.
Definition: guests.h:397
QWORD Buffer
The guest virtual address at which the wide-character string is located.
Definition: wddefs.h:146
void IntVeDumpVeInfoPages(void)
Dumps the VE info pages on all VCPUs.
Definition: vecore.c:2698
#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
union _SIG_VERSION_OS::@32 Minimum
static BYTE * gPagesBitmap
Definition: debugger.c:116
static void DbgDumpVaSpace(DWORD Argc, const char *Argv[])
Definition: debugger.c:1996
LIST_HEAD NoNameUserExceptions
Linked list used for user-mode exceptions that don&#39;t have a valid originator (-). ...
Definition: exceptions.h:99
Describe a codeblocks signature hash.
Definition: exceptions.h:366
Describes a operating system version signature.
Definition: exceptions.h:486
void IntHookPtsDump(void)
Prints all the page table hooks.
Definition: hook_pts.c:2452
BOOLEAN gInsideDebugger
Set to True when introcore is inside a debugger.
Definition: debugger.c:28
static void DbgProcList(void)
Definition: debugger.c:1469
Handling a VMCALL.
Definition: guests.h:24
#define FALSE
Definition: intro_types.h:34
This structure describes a running process inside the guest.
Definition: winprocess.h:83
LIST_HEAD VersionOsSignatures
Linked list used for operating system version signatures.
Definition: exceptions.h:135
QWORD IntWinVadFindNodeInGuestSpace(QWORD VadRoot, QWORD StartPage, QWORD EndPage, DWORD Level, QWORD OldStartPage, BOOLEAN LastBranchRight)
Searches for a VAD node inside a guest VAD tree.
Definition: winvad.c:1825
Handling EPT violation.
Definition: guests.h:22