Bitdefender Hypervisor Memory Introspection
dumper.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "dumper.h"
6 #include "decoder.h"
7 #include "guests.h"
8 #include "introcpu.h"
9 #include "lixprocess.h"
10 #include "lixksym.h"
11 
17 
19 __nonnull() void
21  _In_ IG_ARCH_REGS const *Registers
22  )
28 {
29  LOG("Registers state:\n");
30 
31  LOG("RAX = 0x%016llx, RCX = 0x%016llx, RDX = 0x%016llx, RBX = 0x%016llx\n",
32  Registers->Rax, Registers->Rcx, Registers->Rdx, Registers->Rbx);
33  LOG("RSP = 0x%016llx, RBP = 0x%016llx, RSI = 0x%016llx, RDI = 0x%016llx\n",
34  Registers->Rsp, Registers->Rbp, Registers->Rsi, Registers->Rdi);
35  LOG("R8 = 0x%016llx, R9 = 0x%016llx, R10 = 0x%016llx, R11 = 0x%016llx\n",
36  Registers->R8, Registers->R9, Registers->R10, Registers->R11);
37  LOG("R12 = 0x%016llx, R13 = 0x%016llx, R14 = 0x%016llx, R15 = 0x%016llx\n",
38  Registers->R12, Registers->R13, Registers->R14, Registers->R15);
39  LOG("RIP = 0x%016llx, RFLAGS = 0x%016llx\n",
40  Registers->Rip, Registers->Flags);
41  LOG("CR0 = 0x%016llx, CR2 = 0x%016llx, CR3 = 0x%016llx, CR4 = 0x%016llx\n",
42  Registers->Cr0, Registers->Cr2, Registers->Cr3, Registers->Cr4);
43 }
44 
45 
47 __nonnull() void
49  _In_reads_bytes_(Length) const void *Buffer,
50  _In_opt_ QWORD Gva,
51  _In_ DWORD Length,
52  _In_opt_ DWORD RowLength,
53  _In_opt_ DWORD ElementLength,
54  _In_opt_ BOOLEAN LogHeader,
55  _In_opt_ BOOLEAN DumpAscii
56  )
79 {
80  char line[256] = {0};
81  const unsigned char *buf = Buffer;
82 
83  if (0 == RowLength)
84  {
85  RowLength = 8;
86  }
87 
88  if (0 == ElementLength)
89  {
90  ElementLength = 1;
91  }
92 
93  if (1 != ElementLength && 2 != ElementLength && 4 != ElementLength && 8 != ElementLength)
94  {
95  WARNING("[WARNING] Only 1, 2, 4 or 8 element length are supported!\n");
96  return;
97  }
98 
99  if (RowLength > 16)
100  {
101  WARNING("[ERROR] Maximum 16 elements per row are supported!\n");
102  return;
103  }
104 
105 #define IS_ASCII(x) ((x) >= 0x20 && (x) < 0x7f)
106 
107  if (LogHeader)
108  {
109  LOG("[DUMPER] Dumping buffer from GVA %016llx with size %d\n", Gva, Length);
110  }
111 
112  for (size_t i = 0; i < Length; i += (size_t)RowLength * ElementLength)
113  {
114  char *l = line;
115  int ret, rem = sizeof(line);
116  char rest[sizeof(QWORD)];
117 
118  ret = snprintf(l, sizeof(line), "%016llx:", Gva + i);
119  if (ret < 0 || ret >= rem)
120  {
121  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
122  break;
123  }
124 
125  rem -= ret;
126  l += ret;
127 
128  for (size_t j = 0; j < (size_t)RowLength * ElementLength; j += ElementLength)
129  {
130  BOOLEAN over = (i + j + ElementLength) > Length;
131 
132  if (ElementLength != 1 && over)
133  {
134  memset(rest, 'x', sizeof(rest));
135 
136  if (i + j < Length)
137  {
138  memcpy(rest, buf + i + j, (i + j + ElementLength) - Length);
139  }
140  }
141 
142  switch (ElementLength)
143  {
144  case 1:
145  ret = snprintf(l, rem, " %02x",
146  over ? 'x' : buf[i + j]);
147  break;
148  case 2:
149  ret = snprintf(l, rem, " %04x",
150  over ? * (WORD *)rest : * (const WORD *)(buf + i + j));
151  break;
152  case 4:
153  ret = snprintf(l, rem, " %08x",
154  over ? * (DWORD *)rest : * (const DWORD *)(buf + i + j));
155  break;
156  case 8:
157  ret = snprintf(l, rem, " %016llx",
158  over ? * (QWORD *)rest : * (const QWORD *)(buf + i + j));
159  break;
160  }
161 
162  if (ret < 0 || ret >= rem)
163  {
164  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
165  break;
166  }
167 
168  rem -= ret;
169  l += ret;
170  }
171 
172  if (DumpAscii)
173  {
174  ret = snprintf(l, rem, " ");
175  if (ret < 0 || ret >= rem)
176  {
177  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
178  break;
179  }
180 
181  rem -= ret;
182  l += ret;
183 
184  for (size_t j = 0; j < (size_t)RowLength * ElementLength; j++)
185  {
186  ret = snprintf(l, rem, "%c", (i + j >= Length) ? 'x' : IS_ASCII(buf[i + j]) ? buf[i + j] : '.');
187  if (ret < 0 || ret >= rem)
188  {
189  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
190  break;
191  }
192 
193  rem -= ret;
194  l += ret;
195  }
196  }
197 
198  LOG("%s\n", line);
199  }
200 }
201 
202 
203 TIMER_FRIENDLY void
205  _In_ QWORD Gva,
206  _In_ DWORD Length,
207  _In_opt_ QWORD Cr3,
208  _In_opt_ DWORD RowLength,
209  _In_opt_ DWORD ElementLength,
210  _In_opt_ BOOLEAN LogHeader,
211  _In_opt_ BOOLEAN DumpAscii
212  )
229 {
230  BYTE *buf;
231  INTSTATUS status;
232  DWORD retLen;
233  QWORD cr3;
234 
235  if (0 == Length)
236  {
237  return;
238  }
239 
240  cr3 = Cr3;
241 
242  if (0 == cr3)
243  {
244  status = IntCr3Read(IG_CURRENT_VCPU, &cr3);
245  if (!INT_SUCCESS(status))
246  {
247  ERROR("[ERROR] IntCr3Read failed: %08x\n", status);
248  return;
249  }
250  }
251 
252  buf = HpAllocWithTag(Length, IC_TAG_ALLOC);
253  if (NULL == buf)
254  {
255  return;
256  }
257 
258  status = IntVirtMemRead(Gva, Length, cr3, buf, &retLen);
259  if (!INT_SUCCESS(status))
260  {
261  ERROR("[ERROR] IntVirtMemRead failed for GVA 0x%016llx and length 0x%x: 0x%08x\n", Gva, Length, status);
262  goto _clean_leave;
263  }
264 
265  IntDumpBuffer(buf, Gva, retLen, RowLength, ElementLength, LogHeader, DumpAscii);
266 
267 _clean_leave:
269 }
270 
271 
272 TIMER_FRIENDLY void
274  _In_ QWORD Gva,
275  _In_ DWORD Length,
276  _In_opt_ QWORD Cr3
277  )
288 {
289  IntDumpGvaEx(Gva, Length, Cr3, 16, sizeof(BYTE), TRUE, TRUE);
290 }
291 
292 
293 void
295  _In_ void *Buffer,
296  _In_ DWORD Length,
297  _In_opt_ QWORD Rip
298  )
306 {
307  INSTRUX instrux;
308  INTSTATUS status;
309  DWORD csType;
310  BYTE *p = Buffer;
311 
312  status = IntGetCurrentMode(IG_CURRENT_VCPU, &csType);
313  if (!INT_SUCCESS(status))
314  {
315  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
316  return;
317  }
318 
319  for (QWORD rip = Rip; rip < Rip + Length;)
320  {
321  char temp[ND_MIN_BUF_SIZE];
322  char _line[ND_MIN_BUF_SIZE * 2];
323  char *line = _line;
324  int ret, rem = sizeof(_line);
325 
326  status = IntDecDecodeInstructionFromBuffer(p, Length - (rip - Rip), csType, &instrux);
327  if (!INT_SUCCESS(status))
328  {
329  LOG("0x%llx db %02x\n", rip, *p);
330 
331  rip++;
332  p++;
333 
334  continue;
335  }
336 
337  NdToText(&instrux, rip, sizeof(temp), temp);
338 
339  ret = snprintf(line, rem, "0x%llx ", rip);
340  if (ret < 0 || ret >= rem)
341  {
342  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
343  break;
344  }
345 
346  rem -= ret;
347  line += ret;
348 
349  for (DWORD i = 0; i < 14; i++)
350  {
351  if (i < instrux.Length)
352  {
353  ret = snprintf(line, rem, "%02x", instrux.InstructionBytes[i]);
354  }
355  else
356  {
357  ret = snprintf(line, rem, " ");
358  }
359 
360  if (ret < 0 || ret >= rem)
361  {
362  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
363  break;
364  }
365 
366  rem -= ret;
367  line += ret;
368  }
369 
370  ret = snprintf(line, rem, " %s", temp);
371  if (ret < 0 || ret >= rem)
372  {
373  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
374  break;
375  }
376 
377  rem -= ret;
378  line += ret;
379 
380  QWORD ptr;
381 
382  switch (instrux.Instruction)
383  {
384  case ND_INS_CALLNR:
385  case ND_INS_Jcc:
386  case ND_INS_JMPNR:
387  ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
388 
389  break;
390 
391  default:
392  ptr = 0;
393  }
394 
395  if (ptr &&
398  {
399  QWORD symStart = 0;
400  status = IntKsymFindByAddress(ptr, sizeof(temp), temp, &symStart, NULL);
401  if (INT_SUCCESS(status))
402  {
403  if (symStart != ptr)
404  {
405  ret = snprintf(line, rem, " (%s + 0x%llx)", temp, ptr - symStart);
406  }
407  else
408  {
409  ret = snprintf(line, rem, " (%s)", temp);
410  }
411 
412  if (ret < 0 || ret >= rem)
413  {
414  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
415  break;
416  }
417 
418  line += ret;
419  rem -= ret;
420  }
421  }
422 
423  LOG("%s\n", _line);
424 
425  rip += instrux.Length;
426  p += instrux.Length;
427  }
428 }
429 
430 
431 void
433  _In_ QWORD Gva,
434  _In_ DWORD Length
435  )
443 {
444  INSTRUX instrux;
445  INTSTATUS status;
446  DWORD csType;
447  QWORD rip = Gva, functionEnd = 0;
448 
449  status = IntGetCurrentMode(IG_CURRENT_VCPU, &csType);
450  if (!INT_SUCCESS(status))
451  {
452  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
453  return;
454  }
455 
456  LOG("[DUMPER] Dumping first 0x%x bytes of instructions:\n", Length);
457 
458  while (rip < Gva + Length)
459  {
460  char temp[ND_MIN_BUF_SIZE];
461  char _line[ND_MIN_BUF_SIZE * 2];
462  char *line = _line;
463  int ret, rem = sizeof(_line);
464 
465  if (gGuest.OSType == introGuestLinux &&
466  rip > functionEnd &&
468  {
469  status = IntKsymFindByAddress(rip, sizeof(temp), temp, NULL, &functionEnd);
470  if (INT_SUCCESS(status))
471  {
472  LOG("%s\n", temp);
473  }
474  }
475 
476  status = IntDecDecodeInstruction(csType, rip, &instrux);
477  if (!INT_SUCCESS(status))
478  {
479  BYTE b = 0xbd;
480 
481  IntVirtMemRead(Gva, 1, 0, &b, NULL);
482 
483  LOG("0x%llx db %02x\n", rip, b);
484 
485  rip++;
486  continue;
487  }
488 
489  NdToText(&instrux, rip, sizeof(temp), temp);
490 
491  ret = snprintf(line, rem, "0x%llx ", rip);
492  if (ret < 0 || ret >= rem)
493  {
494  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
495  break;
496  }
497 
498  rem -= ret;
499  line += ret;
500 
501  for (DWORD i = 0; i < 14; i++)
502  {
503  if (i < instrux.Length)
504  {
505  ret = snprintf(line, rem, "%02x", instrux.InstructionBytes[i]);
506  }
507  else
508  {
509  ret = snprintf(line, rem, " ");
510  }
511 
512  if (ret < 0 || ret >= rem)
513  {
514  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
515  break;
516  }
517 
518  rem -= ret;
519  line += ret;
520  }
521 
522  ret = snprintf(line, rem, " %s", temp);
523  if (ret < 0 || ret >= rem)
524  {
525  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
526  break;
527  }
528 
529  rem -= ret;
530  line += ret;
531 
532  QWORD ptr;
533 
534  switch (instrux.Instruction)
535  {
536  case ND_INS_CALLNR:
537  case ND_INS_Jcc:
538  case ND_INS_JMPNR:
539  ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
540 
541  break;
542 
543  default:
544  ptr = 0;
545  }
546 
547  if (ptr &&
550  {
551  QWORD symStart = 0;
552  status = IntKsymFindByAddress(ptr, sizeof(temp), temp, &symStart, NULL);
553  if (INT_SUCCESS(status))
554  {
555  if (symStart != ptr)
556  {
557  ret = snprintf(line, rem, " (%s + 0x%llx)", temp, ptr - symStart);
558  }
559  else
560  {
561  ret = snprintf(line, rem, " (%s)", temp);
562  }
563 
564  if (ret < 0 || ret >= rem)
565  {
566  ERROR("[ERROR] snprintf error: %d, size %d\n", ret, rem);
567  break;
568  }
569 
570  line += ret;
571  rem -= ret;
572  }
573  }
574 
575  LOG("%s\n", _line);
576 
577  rip += instrux.Length;
578  }
579 }
580 
581 
582 TIMER_FRIENDLY void
584  _In_ INSTRUX *Instruction,
585  _In_opt_ QWORD Rip
586  )
593 {
594  char nd[ND_MIN_BUF_SIZE] = {0};
595  NDSTATUS status;
596 
597  if (NULL == Instruction)
598  {
599  return;
600  }
601 
602  status = NdToText(Instruction, Rip, sizeof(nd), nd);
603  if (!ND_SUCCESS(status))
604  {
605  snprintf(nd, sizeof(nd), "<invalid: %08x>", status);
606  }
607 
608  LOG("[DUMPER] Dumping instruction at %llx: %s\n", Rip, nd);
609  IntDumpBuffer(Instruction->InstructionBytes, Rip, Instruction->Length, 16, 1, TRUE, FALSE);
610 }
611 
612 
613 void
615  _In_ const char *FunctionName
616  )
622 {
623  QWORD start, end;
624 
625  start = IntKsymFindByName(FunctionName, &end);
626  if (!start)
627  {
628  WARNING("[WARNING] IntKsymFindByName could not find %s\n", FunctionName);
629  return;
630  }
631 
632  IntDisasmGva(start, (DWORD)(end - start));
633 }
634 
635 
636 void
638  _In_ BYTE *Page,
639  _In_ DWORD Offset,
640  _In_ IG_CS_TYPE CsType,
641  _In_ IG_ARCH_REGS *Registers
642  )
651 {
652  DWORD insCount, i;
653  INTSTATUS status;
654  INSTRUX instrux = { 0 };
655  char text[ND_MIN_BUF_SIZE];
656 
657  i = insCount = 0;
658 
659  LOG("First 256 instructions:\n");
660 
661  while ((Offset + i < PAGE_SIZE) && (insCount++ < 256))
662  {
663  status = IntDecDecodeInstructionFromBuffer(Page + Offset + i, PAGE_SIZE - Offset - i, CsType, &instrux);
664  if (!INT_SUCCESS(status))
665  {
666  i++;
667  }
668  else
669  {
670  NdToText(&instrux, Registers->Rip + i, ND_MIN_BUF_SIZE, text);
671 
672  LOG(" %llx: %s\n", Registers->Rip + i, text);
673 
674  i += instrux.Length;
675  }
676  }
677 
678  LOG("Raw page dump:\n");
679 
680  for (i = 0; i < PAGE_SIZE / 16; i++)
681  {
682  LOG("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
683  Page[i * 16 + 0x0], Page[i * 16 + 0x1], Page[i * 16 + 0x2], Page[i * 16 + 0x3],
684  Page[i * 16 + 0x4], Page[i * 16 + 0x5], Page[i * 16 + 0x6], Page[i * 16 + 0x7],
685  Page[i * 16 + 0x8], Page[i * 16 + 0x9], Page[i * 16 + 0xA], Page[i * 16 + 0xB],
686  Page[i * 16 + 0xC], Page[i * 16 + 0xD], Page[i * 16 + 0xE], Page[i * 16 + 0xF]);
687  }
688 }
689 
690 
691 INTSTATUS
693  _In_ QWORD Gva,
694  _In_ QWORD Gpa,
695  _In_ IG_ARCH_REGS *Registers
696  )
705 {
706  INTSTATUS status;
707  PBYTE pPage;
708  DWORD offset, csType;
709 
710  pPage = NULL;
711  csType = 0;
712 
713  status = IntPhysMemMap(Gpa & PHYS_PAGE_MASK, PAGE_SIZE, 0, &pPage);
714  if (!INT_SUCCESS(status))
715  {
716  ERROR("[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
717  return status;
718  }
719 
720  offset = Gva & PAGE_OFFSET;
721 
722  // Get the CS type for this cpu (we need it in order to see if it's in 16 bit, 32 bit or 64 bit).
723  status = IntGetCurrentMode(gVcpu->Index, &csType);
724  if (!INT_SUCCESS(status))
725  {
726  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
727  IntPhysMemUnmap(&pPage);
728  return status;
729  }
730 
731  IntDumpCode(pPage, offset, csType, Registers);
732  IntDumpArchRegs(Registers);
733 
734  IntPhysMemUnmap(&pPage);
735 
736  return INT_STATUS_SUCCESS;
737 }
738 
739 
740 void
742  _In_ LIX_TRAP_FRAME *TrapFrame
743  )
749 {
750  LOG("R15 = %016llx R14 = %016llx R13 = %016llx R12 = %016llx Rbp = %016llx\n",
751  TrapFrame->R15, TrapFrame->R14, TrapFrame->R13, TrapFrame->R12, TrapFrame->Rbp);
752 
753  LOG("Rbx = %016llx R11 = %016llx R10 = %016llx R9 = %016llx R8 = %016llx \n",
754  TrapFrame->Rbx, TrapFrame->R11, TrapFrame->R10, TrapFrame->R9, TrapFrame->R8);
755 
756  LOG("Rax = %016llx Rcx = %016llx Rdx = %016llx Rsi = %016llx Rdi = %016llx\n",
757  TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->Rsi, TrapFrame->Rdi);
758 
759  LOG("Oax = %016llx Rip = %016llx Cs = %016llx Flg = %016llx Rsp = %016llx Ss = %016llx\n",
760  TrapFrame->OrigRax, TrapFrame->Rip, TrapFrame->Cs, TrapFrame->Rflags, TrapFrame->Rsp, TrapFrame->Ss);
761 }
762 
763 
764 void
766  _In_ KTRAP_FRAME64 *TrapFrame
767  )
773 {
774  LOG("RAX = %016llx RCX = %016llx RDX = %016llx R8 = %016llx R9 = %016llx\n",
775  TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->R8, TrapFrame->R9);
776 
777  LOG("R10 = %016llx GsSwap = %016llx DS = %04x ES = %04x FS = %04x \n",
778  TrapFrame->R10, TrapFrame->GsSwap, TrapFrame->SegDs, TrapFrame->SegEs, TrapFrame->SegFs);
779 
780  LOG("GS = %04x RBX = %016llx RDI = %016llx RSI = %016llx RBP = %016llx\n",
781  TrapFrame->SegGs, TrapFrame->Rbx, TrapFrame->Rdi, TrapFrame->Rsi, TrapFrame->Rbp);
782 
783  LOG("TrapFrame = 0x%016llx RIP = %016llx CS = %04x FLAGS = %08x RSP = %016llx SS = %04x\n",
784  TrapFrame->TrapFrame, TrapFrame->Rip, TrapFrame->SegCs, TrapFrame->EFlags, TrapFrame->Rsp, TrapFrame->SegSs);
785 }
786 
787 
788 void
790  _In_ KTRAP_FRAME32 *TrapFrame
791  )
797 {
798  LOG("GS = %08x ES = %08x DS = %08x EDX = %08x ECX = %08x\n",
799  TrapFrame->SegGs, TrapFrame->SegEs, TrapFrame->SegDs, TrapFrame->Edx, TrapFrame->Ecx);
800 
801  LOG("EAX = %08x FS = %08x EDI = %08x ESI = %08x EBX = %08x \n",
802  TrapFrame->Eax, TrapFrame->SegFs, TrapFrame->Edi, TrapFrame->Esi, TrapFrame->Ebx);
803 
804  LOG("EBP = %08x EIP = %08x CS = %08x FLAGS = %08x ESP = %08x SS = %08x\n",
805  TrapFrame->Ebp,
806  TrapFrame->Eip,
807  TrapFrame->SegCs,
808  TrapFrame->EFlags,
809  TrapFrame->HardwareEsp,
810  TrapFrame->HardwareSegSs);
811 }
#define _In_opt_
Definition: intro_sal.h:16
_Bool BOOLEAN
Definition: intro_types.h:58
Exposes the functions used to used to dump (log) code and registers.
uint8_t BYTE
Definition: intro_types.h:47
DWORD Index
The VCPU number.
Definition: guests.h:172
#define _In_
Definition: intro_sal.h:21
INTSTATUS IntDumpCodeAndRegs(QWORD Gva, QWORD Gpa, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes) as well as the values of the reg...
Definition: dumper.c:692
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
uint16_t WORD
Definition: intro_types.h:48
DWORD KernelSize
The size of the kernel.
Definition: guests.h:284
void IntDumpWinTrapFrame32(KTRAP_FRAME32 *TrapFrame)
This function dumps a windows 64 guest trap frame.
Definition: dumper.c:789
INTSTATUS IntKsymFindByAddress(QWORD Gva, DWORD Length, char *SymName, QWORD *SymStart, QWORD *SymEnd)
Finds the symbol which is located at the given address.
Definition: lixksym.c:1283
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
#define PAGE_OFFSET
Definition: pgtable.h:32
#define ERROR(fmt,...)
Definition: glue.h:62
TIMER_FRIENDLY void IntDumpArchRegs(IG_ARCH_REGS const *Registers)
This function dumps the register values in a user friendly format.
Definition: dumper.c:20
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
#define PHYS_PAGE_MASK
Definition: pgtable.h:38
int INTSTATUS
The status data type.
Definition: introstatus.h:24
TIMER_FRIENDLY void IntDumpInstruction(INSTRUX *Instruction, QWORD Rip)
This function dumps a given instruction (textual disassembly).
Definition: dumper.c:583
void IntDisasmGva(QWORD Gva, DWORD Length)
This function disassembles a code buffer (given its GVA) and then dumps the instructions (textual dis...
Definition: dumper.c:432
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:278
TIMER_FRIENDLY void IntDumpBuffer(const void *Buffer, QWORD Gva, DWORD Length, DWORD RowLength, DWORD ElementLength, BOOLEAN LogHeader, BOOLEAN DumpAscii)
This function dumps a given buffer in a user friendly format.
Definition: dumper.c:48
void IntDumpWinTrapFrame64(KTRAP_FRAME64 *TrapFrame)
This function dumps a windows 64 guest trap frame.
Definition: dumper.c:765
#define LOG(fmt,...)
Definition: glue.h:61
#define IS_ASCII(x)
IG_CS_TYPE
The type of the code segment.
Definition: glueiface.h:183
INTSTATUS IntGetCurrentMode(DWORD CpuNumber, DWORD *Mode)
Read the current CS type.
Definition: introcpu.c:977
#define IG_CURRENT_VCPU
For APIs that take a VCPU number as a parameter, this can be used to specify that the current VCPU sh...
Definition: glueiface.h:324
uint8_t * PBYTE
Definition: intro_types.h:47
unsigned long long QWORD
Definition: intro_types.h:53
#define IN_RANGE_LEN(x, start, len)
Definition: introdefs.h:175
#define TRUE
Definition: intro_types.h:30
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
Definition: decoder.c:308
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
void IntDisasmBuffer(void *Buffer, DWORD Length, QWORD Rip)
This function disassembles a given code buffer and then dumps the instructions (textual disassembly)...
Definition: dumper.c:294
QWORD KernelVa
The guest virtual address at which the kernel image.
Definition: guests.h:283
#define TIMER_FRIENDLY
Definition: introdefs.h:83
void IntDisasmLixFunction(const char *FunctionName)
This function dumps a Linux function (textual disassembly) given its name.
Definition: dumper.c:614
#define WARNING(fmt,...)
Definition: glue.h:60
#define PAGE_SIZE
Definition: common.h:70
TIMER_FRIENDLY void IntDumpGva(QWORD Gva, DWORD Length, QWORD Cr3)
This function is a wrapper over IntDumpGvaEx (it uses RowLength = 16, ElementLength = 1...
Definition: dumper.c:273
uint32_t DWORD
Definition: intro_types.h:49
#define _In_reads_bytes_(expr)
Definition: intro_sal.h:25
TIMER_FRIENDLY void IntDumpGvaEx(QWORD Gva, DWORD Length, QWORD Cr3, DWORD RowLength, DWORD ElementLength, BOOLEAN LogHeader, BOOLEAN DumpAscii)
This function dumps a given GVA in a user friendly format. This function uses IntDumpBuffer to perfor...
Definition: dumper.c:204
void IntDumpLixUmTrapFrame(LIX_TRAP_FRAME *TrapFrame)
This function dumps a Linux UM trap frame.
Definition: dumper.c:741
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
Definition: introcore.c:627
#define IC_TAG_ALLOC
Memory allocation.
Definition: memtags.h:28
INTSTATUS IntCr3Read(DWORD CpuNumber, QWORD *Cr3Value)
Reads the value of the guest CR3.
Definition: introcpu.c:415
void IntDumpCode(BYTE *Page, DWORD Offset, IG_CS_TYPE CsType, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes).
Definition: dumper.c:637
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
Definition: glue.c:338
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:59
VE_CACHE_LINE * Page
Mapped page inside Introspection virtual address space.
Definition: vecore.c:120
Holds register state.
Definition: glueiface.h:30
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
Definition: lixksym.c:1399
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
Definition: glue.c:396
INTSTATUS IntDecDecodeInstruction(IG_CS_TYPE CsType, QWORD Gva, void *Instrux)
Decode an instruction from the provided guest linear address.
Definition: decoder.c:180
#define FALSE
Definition: intro_types.h:34