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) 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  rem -= ret;
120  l += ret;
121 
122  for (size_t j = 0; j < (size_t)RowLength * ElementLength; j += ElementLength)
123  {
124  BOOLEAN over = (i + j + ElementLength) > Length;
125 
126  if (ElementLength != 1 && over)
127  {
128  memset(rest, 'x', sizeof(rest));
129 
130  if (i + j < Length)
131  {
132  memcpy(rest, buf + i + j, (i + j + ElementLength) - Length);
133  }
134  }
135 
136  switch (ElementLength)
137  {
138  case 1:
139  ret = snprintf(l, rem, " %02x",
140  over ? 'x' : buf[i + j]);
141  break;
142  case 2:
143  ret = snprintf(l, rem, " %04x",
144  over ? * (WORD *)rest : * (const WORD *)(buf + i + j));
145  break;
146  case 4:
147  ret = snprintf(l, rem, " %08x",
148  over ? * (DWORD *)rest : * (const DWORD *)(buf + i + j));
149  break;
150  case 8:
151  ret = snprintf(l, rem, " %016llx",
152  over ? * (QWORD *)rest : * (const QWORD *)(buf + i + j));
153  break;
154  }
155 
156  rem -= ret;
157  l += ret;
158  }
159 
160  if (DumpAscii)
161  {
162  ret = snprintf(l, rem, " ");
163  rem -= ret;
164  l += ret;
165 
166  for (size_t j = 0; j < (size_t)RowLength * ElementLength; j++)
167  {
168  ret = snprintf(l, rem, "%c", (i + j >= Length) ? 'x' : IS_ASCII(buf[i + j]) ? buf[i + j] : '.');
169  rem -= ret;
170  l += ret;
171  }
172  }
173 
174  LOG("%s\n", line);
175  }
176 }
177 
178 
179 TIMER_FRIENDLY void
181  _In_ QWORD Gva,
182  _In_ DWORD Length,
183  _In_opt_ QWORD Cr3,
184  _In_opt_ DWORD RowLength,
185  _In_opt_ DWORD ElementLength,
186  _In_opt_ BOOLEAN LogHeader,
187  _In_opt_ BOOLEAN DumpAscii
188  )
205 {
206  BYTE *buf;
207  INTSTATUS status;
208  DWORD retLen;
209  QWORD cr3;
210 
211  if (0 == Length)
212  {
213  return;
214  }
215 
216  cr3 = Cr3;
217 
218  if (0 == cr3)
219  {
220  status = IntCr3Read(IG_CURRENT_VCPU, &cr3);
221  if (!INT_SUCCESS(status))
222  {
223  ERROR("[ERROR] IntCr3Read failed: %08x\n", status);
224  return;
225  }
226  }
227 
228  buf = HpAllocWithTag(Length, IC_TAG_ALLOC);
229  if (NULL == buf)
230  {
231  return;
232  }
233 
234  status = IntVirtMemRead(Gva, Length, cr3, buf, &retLen);
235  if (!INT_SUCCESS(status))
236  {
237  ERROR("[ERROR] IntVirtMemRead failed for GVA 0x%016llx and length 0x%x: 0x%08x\n", Gva, Length, status);
238  goto _clean_leave;
239  }
240 
241  IntDumpBuffer(buf, Gva, retLen, RowLength, ElementLength, LogHeader, DumpAscii);
242 
243 _clean_leave:
245 }
246 
247 
248 TIMER_FRIENDLY void
250  _In_ QWORD Gva,
251  _In_ DWORD Length,
252  _In_opt_ QWORD Cr3
253  )
264 {
265  IntDumpGvaEx(Gva, Length, Cr3, 16, sizeof(BYTE), TRUE, TRUE);
266 }
267 
268 
269 void
271  _In_ void *Buffer,
272  _In_ DWORD Length,
273  _In_opt_ QWORD Rip
274  )
282 {
283  INSTRUX instrux;
284  INTSTATUS status;
285  DWORD csType;
286  BYTE *p = Buffer;
287 
288  status = IntGetCurrentMode(IG_CURRENT_VCPU, &csType);
289  if (!INT_SUCCESS(status))
290  {
291  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
292  return;
293  }
294 
295  for (QWORD rip = Rip; rip < Rip + Length;)
296  {
297  char temp[ND_MIN_BUF_SIZE];
298  char _line[ND_MIN_BUF_SIZE * 2];
299  char *line = _line;
300  int ret, rem = sizeof(_line);
301 
302  status = IntDecDecodeInstructionFromBuffer(p, Length - (rip - Rip), csType, &instrux);
303  if (!INT_SUCCESS(status))
304  {
305  LOG("0x%llx db %02x\n", rip, *p);
306 
307  rip++;
308  p++;
309 
310  continue;
311  }
312 
313  NdToText(&instrux, rip, sizeof(temp), temp);
314 
315  ret = snprintf(line, rem, "0x%llx ", rip);
316  rem -= ret;
317  line += ret;
318 
319  for (DWORD i = 0; i < 14; i++)
320  {
321  if (i < instrux.Length)
322  {
323  ret = snprintf(line, rem, "%02x", instrux.InstructionBytes[i]);
324  rem -= ret;
325  line += ret;
326  }
327  else
328  {
329  ret = snprintf(line, rem, " ");
330  rem -= ret;
331  line += ret;
332  }
333  }
334 
335  ret = snprintf(line, rem, " %s", temp);
336  rem -= ret;
337  line += ret;
338 
339  QWORD ptr;
340 
341  switch (instrux.Instruction)
342  {
343  case ND_INS_CALLNR:
344  case ND_INS_Jcc:
345  case ND_INS_JMPNR:
346  ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
347 
348  break;
349 
350  default:
351  ptr = 0;
352  }
353 
354  if (ptr &&
357  {
358  QWORD symStart = 0;
359  status = IntKsymFindByAddress(ptr, sizeof(temp), temp, &symStart, NULL);
360  if (INT_SUCCESS(status))
361  {
362  if (symStart != ptr)
363  {
364  ret = snprintf(line, rem, " (%s + 0x%llx)", temp, ptr - symStart);
365  }
366  else
367  {
368  ret = snprintf(line, rem, " (%s)", temp);
369  }
370 
371  line += ret;
372  rem -= ret;
373  }
374  }
375 
376  LOG("%s\n", _line);
377 
378  rip += instrux.Length;
379  p += instrux.Length;
380  }
381 }
382 
383 
384 void
386  _In_ QWORD Gva,
387  _In_ DWORD Length
388  )
396 {
397  INSTRUX instrux;
398  INTSTATUS status;
399  DWORD csType;
400  QWORD rip = Gva, functionEnd = 0;
401 
402  status = IntGetCurrentMode(IG_CURRENT_VCPU, &csType);
403  if (!INT_SUCCESS(status))
404  {
405  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
406  return;
407  }
408 
409  LOG("[DUMPER] Dumping first 0x%x bytes of instructions:\n", Length);
410 
411  while (rip < Gva + Length)
412  {
413  char temp[ND_MIN_BUF_SIZE];
414  char _line[ND_MIN_BUF_SIZE * 2];
415  char *line = _line;
416  int ret, rem = sizeof(_line);
417 
418  if (gGuest.OSType == introGuestLinux &&
419  rip > functionEnd &&
421  {
422  status = IntKsymFindByAddress(rip, sizeof(temp), temp, NULL, &functionEnd);
423  if (INT_SUCCESS(status))
424  {
425  LOG("%s\n", temp);
426  }
427  }
428 
429  status = IntDecDecodeInstruction(csType, rip, &instrux);
430  if (!INT_SUCCESS(status))
431  {
432  BYTE b = 0xbd;
433 
434  IntVirtMemRead(Gva, 1, 0, &b, NULL);
435 
436  LOG("0x%llx db %02x\n", rip, b);
437 
438  rip++;
439  continue;
440  }
441 
442  NdToText(&instrux, rip, sizeof(temp), temp);
443 
444  ret = snprintf(line, rem, "0x%llx ", rip);
445  rem -= ret;
446  line += ret;
447 
448  for (DWORD i = 0; i < 14; i++)
449  {
450  if (i < instrux.Length)
451  {
452  ret = snprintf(line, rem, "%02x", instrux.InstructionBytes[i]);
453  rem -= ret;
454  line += ret;
455  }
456  else
457  {
458  ret = snprintf(line, rem, " ");
459  rem -= ret;
460  line += ret;
461  }
462  }
463 
464  ret = snprintf(line, rem, " %s", temp);
465  rem -= ret;
466  line += ret;
467 
468  QWORD ptr;
469 
470  switch (instrux.Instruction)
471  {
472  case ND_INS_CALLNR:
473  case ND_INS_Jcc:
474  case ND_INS_JMPNR:
475  ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
476 
477  break;
478 
479  default:
480  ptr = 0;
481  }
482 
483  if (ptr &&
486  {
487  QWORD symStart = 0;
488  status = IntKsymFindByAddress(ptr, sizeof(temp), temp, &symStart, NULL);
489  if (INT_SUCCESS(status))
490  {
491  if (symStart != ptr)
492  {
493  ret = snprintf(line, rem, " (%s + 0x%llx)", temp, ptr - symStart);
494  }
495  else
496  {
497  ret = snprintf(line, rem, " (%s)", temp);
498  }
499 
500  line += ret;
501  rem -= ret;
502  }
503  }
504 
505  LOG("%s\n", _line);
506 
507  rip += instrux.Length;
508  }
509 }
510 
511 
512 TIMER_FRIENDLY void
514  _In_ INSTRUX *Instruction,
515  _In_opt_ QWORD Rip
516  )
523 {
524  char nd[ND_MIN_BUF_SIZE] = {0};
525  NDSTATUS status;
526 
527  if (NULL == Instruction)
528  {
529  return;
530  }
531 
532  status = NdToText(Instruction, Rip, sizeof(nd), nd);
533  if (!ND_SUCCESS(status))
534  {
535  snprintf(nd, sizeof(nd), "<invalid: %08x>", status);
536  }
537 
538  LOG("[DUMPER] Dumping instruction at %llx: %s\n", Rip, nd);
539  IntDumpBuffer(Instruction->InstructionBytes, Rip, Instruction->Length, 16, 1, TRUE, FALSE);
540 }
541 
542 
543 void
545  _In_ const char *FunctionName
546  )
552 {
553  QWORD start, end;
554 
555  start = IntKsymFindByName(FunctionName, &end);
556  if (!start)
557  {
558  WARNING("[WARNING] IntKsymFindByName could not find %s\n", FunctionName);
559  return;
560  }
561 
562  IntDisasmGva(start, (DWORD)(end - start));
563 }
564 
565 
566 void
568  _In_ BYTE *Page,
569  _In_ DWORD Offset,
570  _In_ IG_CS_TYPE CsType,
571  _In_ IG_ARCH_REGS *Registers
572  )
581 {
582  DWORD insCount, i;
583  INTSTATUS status;
584  INSTRUX instrux = { 0 };
585  char text[ND_MIN_BUF_SIZE];
586 
587  i = insCount = 0;
588 
589  LOG("First 256 instructions:\n");
590 
591  while ((Offset + i < PAGE_SIZE) && (insCount++ < 256))
592  {
593  status = IntDecDecodeInstructionFromBuffer(Page + Offset + i, PAGE_SIZE - Offset - i, CsType, &instrux);
594  if (!INT_SUCCESS(status))
595  {
596  i++;
597  }
598  else
599  {
600  NdToText(&instrux, Registers->Rip + i, ND_MIN_BUF_SIZE, text);
601 
602  LOG(" %llx: %s\n", Registers->Rip + i, text);
603 
604  i += instrux.Length;
605  }
606  }
607 
608  LOG("Raw page dump:\n");
609 
610  for (i = 0; i < PAGE_SIZE / 16; i++)
611  {
612  LOG("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
613  Page[i * 16 + 0x0], Page[i * 16 + 0x1], Page[i * 16 + 0x2], Page[i * 16 + 0x3],
614  Page[i * 16 + 0x4], Page[i * 16 + 0x5], Page[i * 16 + 0x6], Page[i * 16 + 0x7],
615  Page[i * 16 + 0x8], Page[i * 16 + 0x9], Page[i * 16 + 0xA], Page[i * 16 + 0xB],
616  Page[i * 16 + 0xC], Page[i * 16 + 0xD], Page[i * 16 + 0xE], Page[i * 16 + 0xF]);
617  }
618 }
619 
620 
621 INTSTATUS
623  _In_ QWORD Gva,
624  _In_ QWORD Gpa,
625  _In_ IG_ARCH_REGS *Registers
626  )
635 {
636  INTSTATUS status;
637  PBYTE pPage;
638  DWORD offset, csType;
639 
640  pPage = NULL;
641  csType = 0;
642 
643  status = IntPhysMemMap(Gpa & PHYS_PAGE_MASK, PAGE_SIZE, 0, &pPage);
644  if (!INT_SUCCESS(status))
645  {
646  ERROR("[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
647  return status;
648  }
649 
650  offset = Gva & PAGE_OFFSET;
651 
652  // 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).
653  status = IntGetCurrentMode(gVcpu->Index, &csType);
654  if (!INT_SUCCESS(status))
655  {
656  ERROR("[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
657  return status;
658  }
659 
660  IntDumpCode(pPage, offset, csType, Registers);
661  IntDumpArchRegs(Registers);
662 
663  IntPhysMemUnmap(&pPage);
664 
665  return INT_STATUS_SUCCESS;
666 }
667 
668 
669 void
671  _In_ LIX_TRAP_FRAME *TrapFrame
672  )
678 {
679  LOG("R15 = %016llx R14 = %016llx R13 = %016llx R12 = %016llx Rbp = %016llx\n",
680  TrapFrame->R15, TrapFrame->R14, TrapFrame->R13, TrapFrame->R12, TrapFrame->Rbp);
681 
682  LOG("Rbx = %016llx R11 = %016llx R10 = %016llx R9 = %016llx R8 = %016llx \n",
683  TrapFrame->Rbx, TrapFrame->R11, TrapFrame->R10, TrapFrame->R9, TrapFrame->R8);
684 
685  LOG("Rax = %016llx Rcx = %016llx Rdx = %016llx Rsi = %016llx Rdi = %016llx\n",
686  TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->Rsi, TrapFrame->Rdi);
687 
688  LOG("Oax = %016llx Rip = %016llx Cs = %016llx Flg = %016llx Rsp = %016llx Ss = %016llx\n",
689  TrapFrame->OrigRax, TrapFrame->Rip, TrapFrame->Cs, TrapFrame->Rflags, TrapFrame->Rsp, TrapFrame->Ss);
690 }
691 
692 
693 void
695  _In_ KTRAP_FRAME64 *TrapFrame
696  )
702 {
703  LOG("RAX = %016llx RCX = %016llx RDX = %016llx R8 = %016llx R9 = %016llx\n",
704  TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->R8, TrapFrame->R9);
705 
706  LOG("R10 = %016llx GsSwap = %016llx DS = %04x ES = %04x FS = %04x \n",
707  TrapFrame->R10, TrapFrame->GsSwap, TrapFrame->SegDs, TrapFrame->SegEs, TrapFrame->SegFs);
708 
709  LOG("GS = %04x RBX = %016llx RDI = %016llx RSI = %016llx RBP = %016llx\n",
710  TrapFrame->SegGs, TrapFrame->Rbx, TrapFrame->Rdi, TrapFrame->Rsi, TrapFrame->Rbp);
711 
712  LOG("TrapFrame = 0x%016llx RIP = %016llx CS = %04x FLAGS = %08x RSP = %016llx SS = %04x\n",
713  TrapFrame->TrapFrame, TrapFrame->Rip, TrapFrame->SegCs, TrapFrame->EFlags, TrapFrame->Rsp, TrapFrame->SegSs);
714 }
715 
716 
717 void
719  _In_ KTRAP_FRAME32 *TrapFrame
720  )
726 {
727  LOG("GS = %08x ES = %08x DS = %08x EDX = %08x ECX = %08x\n",
728  TrapFrame->SegGs, TrapFrame->SegEs, TrapFrame->SegDs, TrapFrame->Edx, TrapFrame->Ecx);
729 
730  LOG("EAX = %08x FS = %08x EDI = %08x ESI = %08x EBX = %08x \n",
731  TrapFrame->Eax, TrapFrame->SegFs, TrapFrame->Edi, TrapFrame->Esi, TrapFrame->Ebx);
732 
733  LOG("EBP = %08x EIP = %08x CS = %08x FLAGS = %08x ESP = %08x SS = %08x\n",
734  TrapFrame->Ebp,
735  TrapFrame->Eip,
736  TrapFrame->SegCs,
737  TrapFrame->EFlags,
738  TrapFrame->HardwareEsp,
739  TrapFrame->HardwareSegSs);
740 }
#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:622
#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:280
void IntDumpWinTrapFrame32(KTRAP_FRAME32 *TrapFrame)
This function dumps a windows 64 guest trap frame.
Definition: dumper.c:718
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
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
TIMER_FRIENDLY void IntDumpBuffer(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
#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:513
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
INTRO_GUEST_TYPE OSType
The type of the guest.
Definition: guests.h:274
void IntDumpWinTrapFrame64(KTRAP_FRAME64 *TrapFrame)
This function dumps a windows 64 guest trap frame.
Definition: dumper.c:694
#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:270
QWORD KernelVa
The guest virtual address at which the kernel image.
Definition: guests.h:279
#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:544
#define WARNING(fmt,...)
Definition: glue.h:60
#define PAGE_SIZE
Definition: common.h:53
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:249
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:180
void IntDumpLixUmTrapFrame(LIX_TRAP_FRAME *TrapFrame)
This function dumps a Linux UM trap frame.
Definition: dumper.c:670
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:48
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:567
__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:57
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:1361
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