Esempio n. 1
0
static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
#ifdef _WIN32
	static HANDLE stack_process_handle = NULL;
	DWORD64 index;
	IMAGEHLP_LINEW64 line;
	struct {
		SYMBOL_INFOW sym;
		uchar buffer[256];
	} data;
	data.sym.SizeOfStruct = sizeof(data.sym);
	data.sym.MaxNameLen = 255;
	if( !stack_process_handle ) {
		stack_process_handle = GetCurrentProcess();
		SymSetOptions(SYMOPT_LOAD_LINES);
		SymInitialize(stack_process_handle,NULL,TRUE);
	}
	if( SymFromAddrW(stack_process_handle,(DWORD64)(int_val)addr,&index,&data.sym) ) {
		DWORD offset = 0;
		line.SizeOfStruct = sizeof(line);
		line.FileName = USTR("\\?");
		line.LineNumber = 0;
		SymGetLineFromAddrW64(stack_process_handle, (DWORD64)(int_val)addr, &offset, &line);
		*outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
		return out;
	}
#endif
	return NULL;
}
Esempio n. 2
0
	void CException::FillStackTrace(void) {
		//	This must be loaded upon apps start
		//	SymSetOptions(SYMOPT_LOAD_LINES);

		UINT			i;
		LPVOID			stack[1024];
		USHORT			frames;
		PSYMBOL_INFOW 	symbol;
		HANDLE			process = GetCurrentProcess();

		SymInitialize(process, NULL, TRUE);

		frames = CaptureStackBackTrace(0, 1024, stack, NULL);
		symbol = (PSYMBOL_INFOW) malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * sizeof(TCHAR));
		ZeroMemory(symbol, sizeof(SYMBOL_INFOW) + MAX_PATH * sizeof(TCHAR));

		symbol->MaxNameLen = MAX_PATH;
		symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);

		for (i = 0; i < frames; i++)
		{
			SymFromAddrW(process, (DWORD64)(stack[i]), 0, symbol);

			printf("%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address);
		}

		free(symbol);
	}
Esempio n. 3
0
/* static */
BOOL
wxDbgHelpDLL::CallSymFromAddr(HANDLE hProcess,
                              DWORD64 Address,
                              size_t* offset,
                              wxString* name)
{
    DWORD64 dwDisplacement;

#ifdef UNICODE
    if ( SymFromAddrW )
    {
        VarSizedStruct<SYMBOL_INFOW> infoW;
        if ( SymFromAddrW(hProcess, Address, &dwDisplacement, infoW) )
        {
            *offset = dwDisplacement;
            *name = infoW->Name;
            return TRUE;
        }
    }
#endif // UNICODE

    if ( SymFromAddr )
    {
        VarSizedStruct<SYMBOL_INFO> info;
        if ( SymFromAddr(hProcess, Address, &dwDisplacement, info) )
        {
            *offset = dwDisplacement;
            *name = info->Name;
            return TRUE;
        }
    }

    return FALSE;
}
Esempio n. 4
0
static void print_stack_from_context(CONTEXT c) {
  STACKFRAME s;  // in/out stackframe
  memset(&s, 0, sizeof(s));
  DWORD imageType;
#ifdef _M_IX86
  // normally, call ImageNtHeader() and use machine info from PE header
  imageType = IMAGE_FILE_MACHINE_I386;
  s.AddrPC.Offset = c.Eip;
  s.AddrPC.Mode = AddrModeFlat;
  s.AddrFrame.Offset = c.Ebp;
  s.AddrFrame.Mode = AddrModeFlat;
  s.AddrStack.Offset = c.Esp;
  s.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
  imageType = IMAGE_FILE_MACHINE_AMD64;
  s.AddrPC.Offset = c.Rip;
  s.AddrPC.Mode = AddrModeFlat;
  s.AddrFrame.Offset = c.Rsp;
  s.AddrFrame.Mode = AddrModeFlat;
  s.AddrStack.Offset = c.Rsp;
  s.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
  imageType = IMAGE_FILE_MACHINE_IA64;
  s.AddrPC.Offset = c.StIIP;
  s.AddrPC.Mode = AddrModeFlat;
  s.AddrFrame.Offset = c.IntSp;
  s.AddrFrame.Mode = AddrModeFlat;
  s.AddrBStore.Offset = c.RsBSP;
  s.AddrBStore.Mode = AddrModeFlat;
  s.AddrStack.Offset = c.IntSp;
  s.AddrStack.Mode = AddrModeFlat;
#else
#error "Platform not supported!"
#endif

  HANDLE process = GetCurrentProcess();
  HANDLE thread = GetCurrentThread();

  SYMBOL_INFOW *symbol =
      (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
  symbol->MaxNameLen = 255;
  symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);

  while (StackWalk(imageType, process, thread, &s, &c, 0,
                   SymFunctionTableAccess, SymGetModuleBase, 0)) {
    BOOL has_symbol =
        SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol);
    fwprintf(
        stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset),
        has_symbol ? symbol->Name : L"<<no symbol>>", (DWORD64)symbol->Address);
    fflush(stderr);
  }

  free(symbol);
}
const Symbol * const SymEngine::GetSymbol(DWORD64 dwAddress)
{
	if (dwAddress == 0)
		return nullptr;

	Symbol& symbol = cache[dwAddress];

	if (symbol.address != 0)
		return &symbol;

	if (!isInitialized)
		return nullptr;

	symbol.address = dwAddress;

	// Module Name
	IMAGEHLP_MODULEW64 moduleInfo;
	memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULEW64));
	moduleInfo.SizeOfStruct = sizeof(moduleInfo);
	if (SymGetModuleInfoW64(hProcess, dwAddress, &moduleInfo))
	{
		symbol.module = moduleInfo.ImageName;
	}


	// FileName and Line
	IMAGEHLP_LINEW64 lineInfo;
	memset(&lineInfo, 0, sizeof(IMAGEHLP_LINEW64));
	lineInfo.SizeOfStruct = sizeof(lineInfo);
	DWORD dwDisp;
	if (SymGetLineFromAddrW64(hProcess, dwAddress, &dwDisp, &lineInfo))
	{
		symbol.file = lineInfo.FileName;
		symbol.line = lineInfo.LineNumber;
	}

	const size_t length = (sizeof(SYMBOL_INFOW) + MAX_SYM_NAME*sizeof(WCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64) + 1;

	// Function Name
	ULONG64 buffer[length];
	PSYMBOL_INFOW dbgSymbol = (PSYMBOL_INFOW)buffer;
	memset(dbgSymbol, 0, sizeof(buffer));
	dbgSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
	dbgSymbol->MaxNameLen = MAX_SYM_NAME;
	if (SymFromAddrW(hProcess, dwAddress, &symbol.offset, dbgSymbol))
	{
		symbol.function.resize(dbgSymbol->NameLen);
		memcpy(&symbol.function[0], &dbgSymbol->Name[0], sizeof(WCHAR) * dbgSymbol->NameLen);
	}

	return &symbol;
}
Esempio n. 6
0
static void print_current_stack() {
  typedef USHORT(WINAPI * CaptureStackBackTraceType)(
      __in ULONG, __in ULONG, __out PVOID *, __out_opt PULONG);
  CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(
      LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace"));

  if (func == NULL) return;  // WOE 29.SEP.2010

// Quote from Microsoft Documentation:
// ## Windows Server 2003 and Windows XP:
// ## The sum of the FramesToSkip and FramesToCapture parameters must be less
// than 63.
#define MAX_CALLERS 62

  void *callers_stack[MAX_CALLERS];
  unsigned short frames;
  SYMBOL_INFOW *symbol;
  HANDLE process;
  process = GetCurrentProcess();
  SymInitialize(process, NULL, TRUE);
  frames = (func)(0, MAX_CALLERS, callers_stack, NULL);
  symbol =
      (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
  symbol->MaxNameLen = 255;
  symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);

  const unsigned short MAX_CALLERS_SHOWN = 32;
  frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN;
  for (unsigned int i = 0; i < frames; i++) {
    SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol);
    fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i,
             (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address);
    fflush(stderr);
  }

  free(symbol);
}
// Resolve - Creates a nicely formatted rendition of the CallStack, including
//   symbolic information (function names and line numbers) if available. and 
//   saves it for later retrieval. This is almost identical to Callstack::dump above.
//
//   Note: The symbol handler must be initialized prior to calling this
//     function.
//
//  - showInternalFrames (IN): If true, then all frames in the CallStack will be
//      dumped. Otherwise, frames internal to the heap will not be dumped.
//
//  Return Value:
//
//    None.
//
void CallStack::resolve(BOOL showInternalFrames)
{
    if (m_resolved)
    {
        // already resolved, no need to do it again
        // resolving twice may report an incorrect module for the stack frames
        // if the memory was leaked in a dynamic library that was already unloaded.
        return;
    }
    if (m_status & CALLSTACK_STATUS_INCOMPLETE) {
        // This call stack appears to be incomplete. Using StackWalk64 may be
        // more reliable.
        Report(L"    HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n"
            L"      in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n"
            L"      complete stack trace.\n");
    }

    IMAGEHLP_LINE64  sourceInfo = { 0 };
    sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 };
    
    WCHAR callingModuleName [MAX_PATH] = L"";
    WCHAR lowerCaseName [MAX_PATH];

    const size_t max_line_length = MAXREPORTLENGTH + 1;
    m_resolvedCapacity = m_size * max_line_length;
    m_resolved = new WCHAR[m_resolvedCapacity];
    const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR);
    ZeroMemory(m_resolved, allocedBytes);
    
    // Iterate through each frame in the call stack.
    for (UINT32 frame = 0; frame < m_size; frame++)
    {
        // Try to get the source file and line number associated with
        // this program counter address.
        SIZE_T programCounter = (*this)[frame];
        g_symbolLock.Enter();
        BOOL             foundline = FALSE;
        DWORD            displacement = 0;

        // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here
        // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. 
        // When that happens there is nothing we can do except crash.
        DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId());
        foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo);
        assert(m_resolved != NULL);

        if (foundline && !showInternalFrames) {
            wcscpy_s(lowerCaseName, sourceInfo.FileName);
            _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1);
            if (isInternalModule(lowerCaseName)) {
                // Don't show frames in files internal to the heap.
                g_symbolLock.Leave();
                continue;
            }
        }

        // Initialize structures passed to the symbol handler.
        SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer;
        functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH;

        // Try to get the name of the function containing this program
        // counter address.
        DWORD64          displacement64 = 0;
        LPWSTR           functionName;
        DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId());
        if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) {
            functionName = functionInfo->Name;
        }
        else {
            // GetFormattedMessage( GetLastError() );
            functionName = L"(Function name unavailable)";
            displacement64 = 0;
        }
        g_symbolLock.Leave();

        HMODULE hCallingModule = GetCallingModule(programCounter);
        LPWSTR moduleName = L"(Module name unavailable)";
        if (hCallingModule && 
            GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0)
        {
            moduleName = wcsrchr(callingModuleName, L'\\');
            if (moduleName == NULL)
                moduleName = wcsrchr(callingModuleName, L'/');
            if (moduleName != NULL)
                moduleName++;
            else
                moduleName = callingModuleName;
        }

        // Use static here to increase performance, and avoid heap allocs. Hopefully this won't
        // prove to be an issue in thread safety. If it does, it will have to be simply non-static.
        static WCHAR stack_line[max_line_length] = L"";
        int NumChars = -1;
        // Display the current stack frame's information.
        if (foundline) {
            // Just truncate anything that is too long.
            if (displacement == 0)
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    %s (%d): %s!%s\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    %s (%d): %s!%s + 0x%X bytes\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement);
        }
        else {
            if (displacement64 == 0)
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", 
                programCounter, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", 
                programCounter, moduleName, functionName, (DWORD)displacement64);
        }

        if (NumChars >= 0) {
            assert(m_resolved != NULL);
            m_resolvedLength += NumChars;
            wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars);
        }
    } // end for loop
}
// dump - Dumps a nicely formatted rendition of the CallStack, including
//   symbolic information (function names and line numbers) if available.
//
//   Note: The symbol handler must be initialized prior to calling this
//     function.
//
//  - showinternalframes (IN): If true, then all frames in the CallStack will be
//      dumped. Otherwise, frames internal to the heap will not be dumped.
//
//  Return Value:
//
//    None.
//
void CallStack::dump(BOOL showInternalFrames, UINT start_frame) const
{
    // The stack was dumped already
    if (m_resolved)
    {
        dumpResolved();
        return;
    }

    if (m_status & CALLSTACK_STATUS_INCOMPLETE) {
        // This call stack appears to be incomplete. Using StackWalk64 may be
        // more reliable.
        Report(L"    HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n"
            L"      in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n"
            L"      complete stack trace.\n");
    }

    IMAGEHLP_LINE64  sourceInfo = { 0 };
    sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 };

    WCHAR lowerCaseName [MAX_PATH];
    WCHAR callingModuleName [MAX_PATH];

    const size_t max_size = MAXREPORTLENGTH + 1;

    // Iterate through each frame in the call stack.
    for (UINT32 frame = start_frame; frame < m_size; frame++)
    {
        // Try to get the source file and line number associated with
        // this program counter address.
        SIZE_T programCounter = (*this)[frame];
        g_symbolLock.Enter();
        BOOL             foundline = FALSE;
        DWORD            displacement = 0;
        DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId());
        foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo);
        if (foundline && !showInternalFrames) {
            wcscpy_s(lowerCaseName, sourceInfo.FileName);
            _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1);
            if (isInternalModule(lowerCaseName)) {
                // Don't show frames in files internal to the heap.
                g_symbolLock.Leave();
                continue;
            }
        }

        // Initialize structures passed to the symbol handler.
        SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer;
        functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH;

        // Try to get the name of the function containing this program
        // counter address.
        DWORD64          displacement64 = 0;
        LPWSTR           functionName;
        DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId());
        if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) {
            functionName = functionInfo->Name;
        }
        else {
            // GetFormattedMessage( GetLastError() );
            functionName = L"(Function name unavailable)";
            displacement64 = 0;
        }
        g_symbolLock.Leave();

        HMODULE hCallingModule = GetCallingModule(programCounter);
        LPWSTR moduleName = L"(Module name unavailable)";
        if (hCallingModule && 
            GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0)
        {
            moduleName = wcsrchr(callingModuleName, L'\\');
            if (moduleName == NULL)
                moduleName = wcsrchr(callingModuleName, L'/');
            if (moduleName != NULL)
                moduleName++;
            else
                moduleName = callingModuleName;
        }

        // Use static here to increase performance, and avoid heap allocs. Hopefully this won't
        // prove to be an issue in thread safety. If it does, it will have to be simply non-static.
        static WCHAR stack_line[MAXREPORTLENGTH + 1] = L"";
        int NumChars = -1;
        // Display the current stack frame's information.
        if (foundline) {
            if (displacement == 0)
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    %s (%d): %s!%s\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    %s (%d): %s!%s + 0x%X bytes\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement);
        }
        else {
            if (displacement64 == 0)
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", 
                programCounter, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", 
                programCounter, moduleName, functionName, (DWORD)displacement64);	
        }

        Print(stack_line);
    }
}
Esempio n. 9
0
void qtDLGCallstack::ShowCallStack()
{
	clsDebugger *pDebugger = qtDLGNanomite::GetInstance()->coreDebugger;
	
	HANDLE	hProc = pDebugger->GetCurrentProcessHandle(),
			hThread = OpenThread(THREAD_GETSET_CONTEXT,false,pDebugger->GetCurrentTID());
	PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
	DWORD dwMaschineMode = NULL;
	LPVOID pContext;
	STACKFRAME64 stackFr = {0};
	stackFr.AddrPC.Mode = AddrModeFlat;
	stackFr.AddrFrame.Mode = AddrModeFlat;
	stackFr.AddrStack.Mode = AddrModeFlat;

	QString sFuncName,
		sFuncMod,
		sReturnToFunc,
		sReturnToMod;
	quint64 dwStackAddr,
		dwReturnTo,
		dwEIP,
		dwDisplacement;
	IMAGEHLP_LINEW64 imgSource = {0};
	IMAGEHLP_MODULEW64 imgMod = {0};

#ifdef _AMD64_
	BOOL bIsWOW64 = false;

	if(clsAPIImport::pIsWow64Process)
		clsAPIImport::pIsWow64Process(hProc,&bIsWOW64);

	if(bIsWOW64)
	{
		dwMaschineMode = IMAGE_FILE_MACHINE_I386;
		WOW64_CONTEXT cTT = pDebugger->wowProcessContext;
		pContext = &cTT;

		stackFr.AddrPC.Offset = cTT.Eip;
		stackFr.AddrFrame.Offset = cTT.Ebp;
		stackFr.AddrStack.Offset = cTT.Esp;	
	}
	else
	{
		dwMaschineMode = IMAGE_FILE_MACHINE_AMD64;
		CONTEXT cTT = pDebugger->ProcessContext;
		pContext = &cTT;

		stackFr.AddrPC.Offset = cTT.Rip;
		stackFr.AddrFrame.Offset = cTT.Rbp;
		stackFr.AddrStack.Offset = cTT.Rsp;	
	}
#else
	dwMaschineMode = IMAGE_FILE_MACHINE_I386;
	CONTEXT cTT = pDebugger->ProcessContext;
	pContext = &cTT;

	stackFr.AddrPC.Offset = cTT.Eip;
	stackFr.AddrFrame.Offset = cTT.Ebp;
	stackFr.AddrStack.Offset = cTT.Esp;	

#endif

	tblCallstack->setRowCount(0);

	do
	{
		if(!StackWalk64(dwMaschineMode,hProc,hThread,&stackFr,pContext,NULL,SymFunctionTableAccess64,SymGetModuleBase64,0))        
			break;

		memset(&imgSource,0,sizeof(IMAGEHLP_LINEW64));
		imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);

		dwStackAddr = stackFr.AddrStack.Offset;
		dwEIP = stackFr.AddrPC.Offset;
		dwReturnTo = stackFr.AddrReturn.Offset;


		memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64));
		imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
		memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
		pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
		pSymbol->MaxNameLen = MAX_PATH;

		SymGetModuleInfoW64(hProc,dwEIP,&imgMod);
		SymFromAddrW(hProc,dwEIP,&dwDisplacement,pSymbol);
		sFuncName = QString::fromWCharArray(pSymbol->Name);
		sFuncMod = QString::fromWCharArray(imgMod.ModuleName);


		memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64));
		imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
		memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
		pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
		pSymbol->MaxNameLen = MAX_PATH;

		SymGetModuleInfoW64(hProc,dwReturnTo,&imgMod);
		SymFromAddrW(hProc,dwReturnTo,&dwDisplacement,pSymbol);
		sReturnToMod = QString::fromWCharArray(imgMod.ModuleName);
		sReturnToFunc = QString::fromWCharArray(pSymbol->Name);

		if(SymGetLineFromAddrW64(hProc,dwEIP,(PDWORD)&dwDisplacement,&imgSource))
		{
			OnCallStack(dwStackAddr,
				dwReturnTo,sReturnToFunc,sReturnToMod,
				dwEIP,sFuncName,sFuncMod,
				QString::fromWCharArray(imgSource.FileName),imgSource.LineNumber);
		}
		else
		{
			OnCallStack(dwStackAddr,
				dwReturnTo,sReturnToFunc,sReturnToMod,
				dwEIP,sFuncName,sFuncMod,
				QString(""),0);
		}

	}while(stackFr.AddrReturn.Offset != 0);

	free(pSymbol);
	CloseHandle(hThread);
}
Esempio n. 10
0
void clsCallstackWorker::run()
{
    HANDLE hThread = OpenThread(THREAD_GETSET_CONTEXT, false, m_processingData.threadID);
    PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
    DWORD dwMaschineMode = NULL;
    quint64 dwDisplacement = NULL;
    LPVOID pContext;
    QList<callstackDisplay> callstackDisplayData;
    callstackDisplay newDisplayData = { 0 };
    STACKFRAME64 stackFr = { 0 };
    IMAGEHLP_LINEW64 imgSource = { 0 };
    IMAGEHLP_MODULEW64 imgMod = { 0 };

    stackFr.AddrPC.Mode = AddrModeFlat;
    stackFr.AddrFrame.Mode = AddrModeFlat;
    stackFr.AddrStack.Mode = AddrModeFlat;

#ifdef _AMD64_
    if(m_processingData.isWOW64)
    {
        dwMaschineMode = IMAGE_FILE_MACHINE_I386;
        WOW64_CONTEXT cTT = m_processingData.wowProcessContext;
        pContext = &cTT;

        stackFr.AddrPC.Offset = cTT.Eip;
        stackFr.AddrFrame.Offset = cTT.Ebp;
        stackFr.AddrStack.Offset = cTT.Esp;
    }
    else
    {
        dwMaschineMode = IMAGE_FILE_MACHINE_AMD64;
        CONTEXT cTT = m_processingData.processContext;
        pContext = &cTT;

        stackFr.AddrPC.Offset = cTT.Rip;
        stackFr.AddrFrame.Offset = cTT.Rbp;
        stackFr.AddrStack.Offset = cTT.Rsp;
    }
#else
    dwMaschineMode = IMAGE_FILE_MACHINE_I386;
    CONTEXT cTT = m_processingData.processContext;
    pContext = &cTT;

    stackFr.AddrPC.Offset = cTT.Eip;
    stackFr.AddrFrame.Offset = cTT.Ebp;
    stackFr.AddrStack.Offset = cTT.Esp;

#endif

    do
    {
        if(!StackWalk64(dwMaschineMode, m_processingData.processHandle, hThread, &stackFr, pContext, NULL, SymFunctionTableAccess64, SymGetModuleBase64, 0))
            break;

        memset(&imgSource, 0, sizeof(IMAGEHLP_LINEW64));
        imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);

        newDisplayData.stackAddress		= stackFr.AddrStack.Offset;
        newDisplayData.currentOffset	= stackFr.AddrPC.Offset;
        newDisplayData.returnOffset		= stackFr.AddrReturn.Offset;


        memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64));
        imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
        memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
        pSymbol->MaxNameLen = MAX_PATH;

        SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.currentOffset, &imgMod);
        SymFromAddrW(m_processingData.processHandle, newDisplayData.currentOffset, &dwDisplacement, pSymbol);
        newDisplayData.currentFunctionName = QString::fromWCharArray(pSymbol->Name);
        newDisplayData.currentModuleName = QString::fromWCharArray(imgMod.ModuleName);


        memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64));
        imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
        memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
        pSymbol->MaxNameLen = MAX_PATH;

        SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.returnOffset, &imgMod);
        SymFromAddrW(m_processingData.processHandle, newDisplayData.returnOffset , &dwDisplacement, pSymbol);
        newDisplayData.returnModuleName = QString::fromWCharArray(imgMod.ModuleName);
        newDisplayData.returnFunctionName = QString::fromWCharArray(pSymbol->Name);

        if(SymGetLineFromAddrW64(m_processingData.processHandle, newDisplayData.currentOffset, (PDWORD)&dwDisplacement, &imgSource))
        {

            newDisplayData.sourceFilePath		= QString::fromWCharArray(imgSource.FileName);
            newDisplayData.sourceLineNumber		= imgSource.LineNumber;
        }
        else
        {
            newDisplayData.sourceFilePath		= "";
            newDisplayData.sourceLineNumber		= 0;
        }

        callstackDisplayData.append(newDisplayData);

    } while(stackFr.AddrReturn.Offset != 0);

    free(pSymbol);
    CloseHandle(hThread);

    emit OnCallstackFinished(callstackDisplayData);
}