47 PBYTE pOriginalStackMap, pStack;
60 if (NULL == StackTrace || NULL == StackTrace->Traces)
67 StackTrace->NumberOfTraces = 0;
68 pStack = pOriginalStackMap = NULL;
69 StackTrace->StartRip = Rip;
72 interationsTry = MaxNumberOfTraces * 2ull;
77 while (StackTrace->NumberOfTraces < MaxNumberOfTraces && interationsTry-- > 0)
79 QWORD nextStackFrame, currentStackFrame, retAddress;
87 ERROR(
"[ERROR] Failed mapping VA 0x%016llx to host: 0x%08x\n", stackFrame, status);
91 pStack = pOriginalStackMap + (stackFrame &
PAGE_OFFSET);
104 ERROR(
"[ERROR] Failed getting the return address for stack frame 0x%016llx: 0x%08x\n",
111 retAddress = *(
QWORD *)(pStack + 8);
117 goto _next_stack_frame;
125 if (StackTrace->NumberOfTraces > 0)
127 if (StackTrace->Traces[StackTrace->NumberOfTraces - 1].ReturnAddress == retAddress)
134 StackTrace->Traces[StackTrace->NumberOfTraces].ReturnAddress = retAddress;
135 StackTrace->Traces[StackTrace->NumberOfTraces].ReturnModule = pRetMod;
136 StackTrace->Traces[StackTrace->NumberOfTraces].RetAddrPointer = stackFrame +
gGuest.
WordSize;
137 StackTrace->Traces[StackTrace->NumberOfTraces].CurrentRip = currentRip;
138 StackTrace->NumberOfTraces++;
140 currentRip = retAddress;
144 nextStackFrame = *(
QWORD *)pStack;
146 currentStackFrame = stackFrame;
155 while ((nextStackFrame - currentStackFrame >= 4 *
PAGE_SIZE) ||
157 (nextStackFrame % 8 != 0))
166 if (0 == searchLimit)
176 if (StackTrace->NumberOfTraces > 0)
182 TRACE(
"[WARNING] Got to the beginning of stack and no frame was found. Status = 0x%08x\n",
189 pStack = pOriginalStackMap + (stackFrame &
PAGE_OFFSET);
192 nextStackFrame = *(
QWORD *)pStack;
195 if (nextStackFrame == currentStackFrame || nextStackFrame % 8 != 0)
208 stackFrame = nextStackFrame;
209 pStack = pOriginalStackMap + (stackFrame &
PAGE_OFFSET);
215 if (NULL != pOriginalStackMap)
251 stackFrame = Registers->Rbp;
262 if ((stackFrame > Registers->Rsp &&
263 stackFrame - Registers->Rsp > 32 *
PAGE_SIZE) ||
264 (stackFrame < Registers->Rsp &&
265 Registers->Rsp - stackFrame > 32 *
PAGE_SIZE))
271 stackFrame = Registers->Rsp;
273 StackTrace->NumberOfTraces = 1;
278 ERROR(
"[ERROR] RSP 0x%016llx is not present: %08x\n", stackFrame, status);
287 return IntLixStackTraceGet(Cr3, stackFrame, Registers->Rip, MaxNumberOfTraces, Flags, StackTrace);
322 for (
DWORD i = 0; i < size / 8; i++)
348 LOG(
"[STACK-TRACE] <0x%llx> %s\n", pStack[i], funcName);
359 LOG(
"[STACK-TRACE] <0x%llx> (symbol not found)\n", pStack[i]);
364 LOG(
"[STACK-TRACE] <0x%llx> (symbol not found) in mod %s\n", pStack[i], (
char *)pMod->
Name);
367 if (++trace >= MaxTraces)
376 }
while (trace < MaxTraces);
398 CHAR *pFileName = NULL;
403 ERROR(
"[ERROR] IntLixTaskGetUmTrapFrame failed: %08x\n", status);
410 ERROR(
"[ERROR] IntLixMmFetchVad failed for RIP %llx: %08x\n", trapFrame.
Rip, status);
417 ERROR(
"[ERROR] IntLixGetFileName failed with status: %x\n", status);
423 ERROR(
"[ERROR] IntLixMmFetchVad failed for RIP %llx: %08x\n", trapFrame.
Rsp, status);
427 TRACE(
"[UM STACK-TRACE] Task : '%s' (%d/%d) -> '%s' RIP: 0x%llx",
428 Task->ProcName, Task->Pid, Task->Tgid, pFileName != NULL ? pFileName :
"<no file>", trapFrame.
Rip);
429 TRACE(
"[UM STACK-TRACE] Stack [0x%llx - 0x%llx] - Stack pointer: 0x%llx\n", stackVma.
Start, stackVma.
End,
432 if (pFileName != NULL)
441 for (
QWORD crtRsp = trapFrame.
Rsp; crtRsp < stackVma.
End; crtRsp += 8)
444 CHAR *pTmpFile = NULL;
463 LOG(
"[UM STACK-TRACE] Return = 0x%016llx : Stack = 0x%016llx, File '%s'",
464 value, crtRsp, pTmpFile == NULL ?
"<invalid file>" : pTmpFile);
467 if (pTmpFile != NULL)
#define STACK_FLG_FAST_GET
Flag that tells to only get return addresses (no drivers).
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
IG_ARCH_REGS Regs
The current state of the guest registers.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
#define PAGE_REMAINING(addr)
#define MAX_FUNC_NAME
The maximum number of characters allowed for a function name.
void IntDumpLixUmTrapFrame(LIX_TRAP_FRAME *TrapFrame)
This function dumps a Linux UM 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)
INTSTATUS IntVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD Cr3, QWORD *Data)
Reads 8 bytes from the guest memory.
Structure that describes a stack trace element.
void IntLixDumpStacktrace(DWORD MaxTraces)
Logs a Kernel stack backtrace.
int INTSTATUS
The status data type.
QWORD CodeEnd
The guest virtual address where the code ends.
QWORD CodeStart
The guest virtual address where the code starts.
INTSTATUS IntLixStackTraceGetReg(QWORD Cr3, PIG_ARCH_REGS Registers, DWORD MaxNumberOfTraces, QWORD Flags, STACK_TRACE *StackTrace)
Retrieves a Kernel stack backtrace based on the register values.
LIX_MODULE_LAYOUT CoreLayout
The layout of the core section.
LIX_MODULE_LAYOUT InitLayout
The layout of the init section.
#define INT_STATUS_NOT_FOUND
QWORD Start
Start of the memory described by the VMA.
Describes a kernel driver.
void IntLixStackDumpUmStackTrace(LIX_TASK_OBJECT *Task)
Logs the libraries found in the user mode stacktrace.
INTSTATUS IntLixStackTraceGet(QWORD Cr3, QWORD Stack, QWORD Rip, DWORD MaxNumberOfTraces, QWORD Flags, STACK_TRACE *StackTrace)
Retrieves a Kernel stack trace.
INTSTATUS IntLixMmFetchVma(LIX_TASK_OBJECT *Task, QWORD Address, LIX_VMA *Vma)
Retrieve information about a VMA structure containing a user mode address.
#define IS_KERNEL_POINTER_LIX(p)
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
struct _LINUX_GUEST::@126 Layout
#define IN_RANGE(x, start, end)
QWORD End
End of the memory described by the VMA.
#define IN_RANGE_LEN(x, start, len)
#define INT_STATUS_INVALID_PARAMETER_4
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
#define HpFreeAndNullWithTag(Add, Tag)
void * Name
The name of the driver.
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
LIX_KERNEL_MODULE Lix
Valid only for Linux guests.
#define UNREFERENCED_PARAMETER(P)
QWORD Flags
Flags for the VMA.
INTSTATUS IntLixTaskGetTrapFrame(const LIX_TASK_OBJECT *Task, LIX_TRAP_FRAME *TrapFrame)
Retrieves the trap frame for a Linux task.
INTSTATUS IntLixGetFileName(QWORD FileStruct, char **FileName, DWORD *NameLength, QWORD *DentryGva)
Gets the file-name that corresponds to the provided FileStruct (guest virtual address).
__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.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
GUEST_STATE gGuest
The current guest state.
KERNEL_DRIVER * IntDriverFindByAddress(QWORD Gva)
Returns the driver in which Gva resides.
KERNEL_DRIVER * KernelDriver
Points to the driver object that describes the kernel image.
VCPU_STATE * gVcpu
The state of the current VCPU.
BOOLEAN Initialized
This means that the init section is discarded.
QWORD Base
The base GVA of the section.
void IntDisasmGva(QWORD Gva, DWORD Length)
This function disassembles a code buffer (given its GVA) and then dumps the instructions (textual dis...
Structure that describes a stack trace.
#define INT_STATUS_INVALID_PARAMETER_2
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
QWORD File
The Gva of the file this VMA maps to. Can be 0 which means this VMA is not a memory mapped file...
DWORD TextSize
The size of the .text (code usually).