29 LOG(
"Registers state:\n");
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);
81 const unsigned char *buf = Buffer;
88 if (0 == ElementLength)
93 if (1 != ElementLength && 2 != ElementLength && 4 != ElementLength && 8 != ElementLength)
95 WARNING(
"[WARNING] Only 1, 2, 4 or 8 element length are supported!\n");
101 WARNING(
"[ERROR] Maximum 16 elements per row are supported!\n");
105 #define IS_ASCII(x) ((x) >= 0x20 && (x) < 0x7f) 109 LOG(
"[DUMPER] Dumping buffer from GVA %016llx with size %d\n", Gva, Length);
112 for (
size_t i = 0; i < Length; i += (size_t)RowLength * ElementLength)
115 int ret, rem =
sizeof(line);
116 char rest[
sizeof(
QWORD)];
118 ret = snprintf(l,
sizeof(line),
"%016llx:", Gva + i);
119 if (ret < 0 || ret >= rem)
121 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
128 for (
size_t j = 0; j < (size_t)RowLength * ElementLength; j += ElementLength)
130 BOOLEAN over = (i + j + ElementLength) > Length;
132 if (ElementLength != 1 && over)
134 memset(rest,
'x',
sizeof(rest));
138 memcpy(rest, buf + i + j, (i + j + ElementLength) - Length);
142 switch (ElementLength)
145 ret = snprintf(l, rem,
" %02x",
146 over ?
'x' : buf[i + j]);
149 ret = snprintf(l, rem,
" %04x",
150 over ? * (
WORD *)rest : * (
const WORD *)(buf + i + j));
153 ret = snprintf(l, rem,
" %08x",
154 over ? * (
DWORD *)rest : * (
const DWORD *)(buf + i + j));
157 ret = snprintf(l, rem,
" %016llx",
158 over ? * (
QWORD *)rest : * (
const QWORD *)(buf + i + j));
162 if (ret < 0 || ret >= rem)
164 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
174 ret = snprintf(l, rem,
" ");
175 if (ret < 0 || ret >= rem)
177 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
184 for (
size_t j = 0; j < (size_t)RowLength * ElementLength; j++)
186 ret = snprintf(l, rem,
"%c", (i + j >= Length) ?
'x' :
IS_ASCII(buf[i + j]) ? buf[i + j] :
'.');
187 if (ret < 0 || ret >= rem)
189 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
247 ERROR(
"[ERROR] IntCr3Read failed: %08x\n", status);
261 ERROR(
"[ERROR] IntVirtMemRead failed for GVA 0x%016llx and length 0x%x: 0x%08x\n", Gva, Length, status);
265 IntDumpBuffer(buf, Gva, retLen, RowLength, ElementLength, LogHeader, DumpAscii);
315 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
319 for (
QWORD rip = Rip; rip < Rip + Length;)
321 char temp[ND_MIN_BUF_SIZE];
322 char _line[ND_MIN_BUF_SIZE * 2];
324 int ret, rem =
sizeof(_line);
329 LOG(
"0x%llx db %02x\n", rip, *p);
337 NdToText(&instrux, rip,
sizeof(temp), temp);
339 ret = snprintf(line, rem,
"0x%llx ", rip);
340 if (ret < 0 || ret >= rem)
342 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
349 for (
DWORD i = 0; i < 14; i++)
351 if (i < instrux.Length)
353 ret = snprintf(line, rem,
"%02x", instrux.InstructionBytes[i]);
357 ret = snprintf(line, rem,
" ");
360 if (ret < 0 || ret >= rem)
362 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
370 ret = snprintf(line, rem,
" %s", temp);
371 if (ret < 0 || ret >= rem)
373 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
382 switch (instrux.Instruction)
387 ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
405 ret = snprintf(line, rem,
" (%s + 0x%llx)", temp, ptr - symStart);
409 ret = snprintf(line, rem,
" (%s)", temp);
412 if (ret < 0 || ret >= rem)
414 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
425 rip += instrux.Length;
447 QWORD rip = Gva, functionEnd = 0;
452 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
456 LOG(
"[DUMPER] Dumping first 0x%x bytes of instructions:\n", Length);
458 while (rip < Gva + Length)
460 char temp[ND_MIN_BUF_SIZE];
461 char _line[ND_MIN_BUF_SIZE * 2];
463 int ret, rem =
sizeof(_line);
483 LOG(
"0x%llx db %02x\n", rip, b);
489 NdToText(&instrux, rip,
sizeof(temp), temp);
491 ret = snprintf(line, rem,
"0x%llx ", rip);
492 if (ret < 0 || ret >= rem)
494 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
501 for (
DWORD i = 0; i < 14; i++)
503 if (i < instrux.Length)
505 ret = snprintf(line, rem,
"%02x", instrux.InstructionBytes[i]);
509 ret = snprintf(line, rem,
" ");
512 if (ret < 0 || ret >= rem)
514 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
522 ret = snprintf(line, rem,
" %s", temp);
523 if (ret < 0 || ret >= rem)
525 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
534 switch (instrux.Instruction)
539 ptr = rip + instrux.Length + instrux.Operands[0].Info.RelativeOffset.Rel;
557 ret = snprintf(line, rem,
" (%s + 0x%llx)", temp, ptr - symStart);
561 ret = snprintf(line, rem,
" (%s)", temp);
564 if (ret < 0 || ret >= rem)
566 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
577 rip += instrux.Length;
584 _In_ INSTRUX *Instruction,
594 char nd[ND_MIN_BUF_SIZE] = {0};
597 if (NULL == Instruction)
602 status = NdToText(Instruction, Rip,
sizeof(nd), nd);
603 if (!ND_SUCCESS(status))
605 snprintf(nd,
sizeof(nd),
"<invalid: %08x>", status);
608 LOG(
"[DUMPER] Dumping instruction at %llx: %s\n", Rip, nd);
615 _In_ const char *FunctionName
628 WARNING(
"[WARNING] IntKsymFindByName could not find %s\n", FunctionName);
654 INSTRUX instrux = { 0 };
655 char text[ND_MIN_BUF_SIZE];
659 LOG(
"First 256 instructions:\n");
661 while ((Offset + i <
PAGE_SIZE) && (insCount++ < 256))
670 NdToText(&instrux, Registers->Rip + i, ND_MIN_BUF_SIZE, text);
672 LOG(
" %llx: %s\n", Registers->Rip + i, text);
678 LOG(
"Raw page dump:\n");
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]);
708 DWORD offset, csType;
716 ERROR(
"[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
726 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
750 LOG(
"R15 = %016llx R14 = %016llx R13 = %016llx R12 = %016llx Rbp = %016llx\n",
751 TrapFrame->R15, TrapFrame->R14, TrapFrame->R13, TrapFrame->R12, TrapFrame->Rbp);
753 LOG(
"Rbx = %016llx R11 = %016llx R10 = %016llx R9 = %016llx R8 = %016llx \n",
754 TrapFrame->Rbx, TrapFrame->R11, TrapFrame->R10, TrapFrame->R9, TrapFrame->R8);
756 LOG(
"Rax = %016llx Rcx = %016llx Rdx = %016llx Rsi = %016llx Rdi = %016llx\n",
757 TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->Rsi, TrapFrame->Rdi);
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);
774 LOG(
"RAX = %016llx RCX = %016llx RDX = %016llx R8 = %016llx R9 = %016llx\n",
775 TrapFrame->Rax, TrapFrame->Rcx, TrapFrame->Rdx, TrapFrame->R8, TrapFrame->R9);
777 LOG(
"R10 = %016llx GsSwap = %016llx DS = %04x ES = %04x FS = %04x \n",
778 TrapFrame->R10, TrapFrame->GsSwap, TrapFrame->SegDs, TrapFrame->SegEs, TrapFrame->SegFs);
780 LOG(
"GS = %04x RBX = %016llx RDI = %016llx RSI = %016llx RBP = %016llx\n",
781 TrapFrame->SegGs, TrapFrame->Rbx, TrapFrame->Rdi, TrapFrame->Rsi, TrapFrame->Rbp);
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);
798 LOG(
"GS = %08x ES = %08x DS = %08x EDX = %08x ECX = %08x\n",
799 TrapFrame->SegGs, TrapFrame->SegEs, TrapFrame->SegDs, TrapFrame->Edx, TrapFrame->Ecx);
801 LOG(
"EAX = %08x FS = %08x EDI = %08x ESI = %08x EBX = %08x \n",
802 TrapFrame->Eax, TrapFrame->SegFs, TrapFrame->Edi, TrapFrame->Esi, TrapFrame->Ebx);
804 LOG(
"EBP = %08x EIP = %08x CS = %08x FLAGS = %08x ESP = %08x SS = %08x\n",
809 TrapFrame->HardwareEsp,
810 TrapFrame->HardwareSegSs);
Exposes the functions used to used to dump (log) code and registers.
DWORD Index
The VCPU number.
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...
#define INT_STATUS_SUCCESS
DWORD KernelSize
The size of the kernel.
void IntDumpWinTrapFrame32(KTRAP_FRAME32 *TrapFrame)
This function dumps a windows 64 guest trap frame.
INTSTATUS IntKsymFindByAddress(QWORD Gva, DWORD Length, char *SymName, QWORD *SymStart, QWORD *SymEnd)
Finds the symbol which is located at the given address.
#define INT_SUCCESS(Status)
TIMER_FRIENDLY void IntDumpArchRegs(IG_ARCH_REGS const *Registers)
This function dumps the register values in a user friendly format.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
TIMER_FRIENDLY void IntDumpInstruction(INSTRUX *Instruction, QWORD Rip)
This function dumps a given instruction (textual disassembly).
void IntDisasmGva(QWORD Gva, DWORD Length)
This function disassembles a code buffer (given its GVA) and then dumps the instructions (textual dis...
INTRO_GUEST_TYPE OSType
The type of the guest.
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.
void IntDumpWinTrapFrame64(KTRAP_FRAME64 *TrapFrame)
This function dumps a windows 64 guest trap frame.
IG_CS_TYPE
The type of the code segment.
INTSTATUS IntGetCurrentMode(DWORD CpuNumber, DWORD *Mode)
Read the current CS type.
#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...
#define IN_RANGE_LEN(x, start, len)
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
#define HpFreeAndNullWithTag(Add, Tag)
void IntDisasmBuffer(void *Buffer, DWORD Length, QWORD Rip)
This function disassembles a given code buffer and then dumps the instructions (textual disassembly)...
QWORD KernelVa
The guest virtual address at which the kernel image.
void IntDisasmLixFunction(const char *FunctionName)
This function dumps a Linux function (textual disassembly) given its name.
TIMER_FRIENDLY void IntDumpGva(QWORD Gva, DWORD Length, QWORD Cr3)
This function is a wrapper over IntDumpGvaEx (it uses RowLength = 16, ElementLength = 1...
#define _In_reads_bytes_(expr)
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...
void IntDumpLixUmTrapFrame(LIX_TRAP_FRAME *TrapFrame)
This function dumps a Linux UM trap frame.
GUEST_STATE gGuest
The current guest state.
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
INTSTATUS IntCr3Read(DWORD CpuNumber, QWORD *Cr3Value)
Reads the value of the guest CR3.
void IntDumpCode(BYTE *Page, DWORD Offset, IG_CS_TYPE CsType, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes).
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
VCPU_STATE * gVcpu
The state of the current VCPU.
VE_CACHE_LINE * Page
Mapped page inside Introspection virtual address space.
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
INTSTATUS IntDecDecodeInstruction(IG_CS_TYPE CsType, QWORD Gva, void *Instrux)
Decode an instruction from the provided guest linear address.