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