1
0
Fork 0

GUI: Added new function GetCallStackByThread

This commit is contained in:
morsisko 2020-10-23 15:06:40 +02:00
parent f6c0faf201
commit 9311752b74
4 changed files with 107 additions and 0 deletions

View File

@ -107,6 +107,12 @@ static void _getcallstack(DBGCALLSTACK* callstack)
stackgetcallstack(GetContextDataEx(hActiveThread, UE_CSP), (CALLSTACK*)callstack);
}
static void _getcallstackbythread(HANDLE thread, DBGCALLSTACK* callstack)
{
if(thread)
stackgetcallstackbythread(thread, (CALLSTACK*)callstack);
}
static void _getsehchain(DBGSEHCHAIN* sehchain)
{
std::vector<duint> SEHList;
@ -532,4 +538,5 @@ void dbgfunctionsinit()
_dbgfunctions.RefreshModuleList = _refreshmodulelist;
_dbgfunctions.GetAddrFromLineEx = _getaddrfromlineex;
_dbgfunctions.ModSymbolStatus = _modsymbolstatus;
_dbgfunctions.GetCallStackByThread = _getcallstackbythread;
}

View File

@ -207,6 +207,7 @@ typedef int(*SYMAUTOCOMPLETE)(const char* Search, char** Buffer, int MaxSymbols)
typedef void(*REFRESHMODULELIST)();
typedef duint(*GETADDRFROMLINEEX)(duint mod, const char* szSourceFile, int line);
typedef MODULESYMBOLSTATUS(*MODSYMBOLSTATUS)(duint mod);
typedef void(*GETCALLSTACKBYTHREAD)(HANDLE thread, DBGCALLSTACK* callstack);
//The list of all the DbgFunctions() return value.
//WARNING: This list is append only. Do not insert things in the middle or plugins would break.
@ -285,6 +286,7 @@ typedef struct DBGFUNCTIONS_
REFRESHMODULELIST RefreshModuleList;
GETADDRFROMLINEEX GetAddrFromLineEx;
MODSYMBOLSTATUS ModSymbolStatus;
GETCALLSTACKBYTHREAD GetCallStackByThread;
} DBGFUNCTIONS;
#ifdef BUILD_DBG

View File

@ -360,6 +360,103 @@ void stackgetcallstack(duint csp, std::vector<CALLSTACKENTRY> & callstackVector,
CallstackCache[csp] = callstackVector;
}
void stackgetcallstackbythread(HANDLE thread, CALLSTACK* callstack)
{
std::vector<CALLSTACKENTRY> callstackVector;
duint csp = GetContextDataEx(thread, UE_CSP);
// Gather context data
CONTEXT context;
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if(SuspendThread(thread) == -1)
return;
if(!GetThreadContext(thread, &context))
return;
if(ResumeThread(thread) == -1)
return;
if(ShowSuspectedCallStack)
{
stackgetsuspectedcallstack(csp, callstackVector);
}
else
{
// Set up all frame data
STACKFRAME64 frame;
ZeroMemory(&frame, sizeof(STACKFRAME64));
#ifdef _M_IX86
DWORD machineType = IMAGE_FILE_MACHINE_I386;
frame.AddrPC.Offset = context.Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = csp;
frame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
frame.AddrPC.Offset = context.Rip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Rsp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = csp;
frame.AddrStack.Mode = AddrModeFlat;
#endif
const int MaxWalks = 50;
// Container for each callstack entry (50 pre-allocated entries)
callstackVector.clear();
callstackVector.reserve(MaxWalks);
for(auto i = 0; i < MaxWalks; i++)
{
if(!SafeStackWalk64(
machineType,
fdProcessInfo->hProcess,
thread,
&frame,
&context,
StackReadProcessMemoryProc64,
StackSymFunctionTableAccess64,
StackGetModuleBaseProc64,
StackTranslateAddressProc64))
{
// Maybe it failed, maybe we have finished walking the stack
break;
}
if(frame.AddrPC.Offset != 0)
{
// Valid frame
CALLSTACKENTRY entry;
memset(&entry, 0, sizeof(CALLSTACKENTRY));
StackEntryFromFrame(&entry, (duint)frame.AddrFrame.Offset + sizeof(duint), (duint)frame.AddrPC.Offset, (duint)frame.AddrReturn.Offset);
callstackVector.push_back(entry);
}
else
{
// Base reached
break;
}
}
}
callstack->total = (int)callstackVector.size();
if(callstack->total > 0)
{
callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY));
// Copy data directly from the vector
memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY));
}
}
void stackgetcallstack(duint csp, CALLSTACK* callstack)
{
std::vector<CALLSTACKENTRY> callstackVector;

View File

@ -22,6 +22,7 @@ bool stackcommentget(duint addr, STACK_COMMENT* comment);
void stackupdatecallstack(duint csp);
void stackgetcallstack(duint csp, CALLSTACK* callstack);
void stackgetcallstack(duint csp, std::vector<CALLSTACKENTRY> & callstack, bool cache);
void stackgetcallstackbythread(HANDLE thread, CALLSTACK* callstack);
void stackupdatesettings();
#endif //_STACKINFO_H