Esempio n. 1
0
bool KImageModule::Load(char * filename, char *sympath)
{
	_tcscpy(m_modulename, filename);

	memset(& m_image, 0, sizeof(m_image));
	
	m_imagebase_loaded = (DWORD) GetModuleHandle(filename);

	if ( m_imagebase_loaded ) // module is already loaded, for example GDI32.DLL
	{
		m_imagebase_default = m_imagebase_loaded;
		m_bLoaded			= false;

		PIMAGE_NT_HEADERS pNTHeader = ImageNtHeader((void *)m_imagebase_loaded);

		Output("%s already loaded at 0x%x %s\n", filename, m_imagebase_loaded,
			ctime( (time_t *) & pNTHeader->FileHeader.TimeDateStamp));
	}
	else
	{
		if ( MapAndLoad(filename, NULL, & m_image, FALSE, TRUE) )
			Output("%s loaded at 0x%x %s\n", m_image.ModuleName, m_image.MappedAddress, 
				ctime( (time_t *) & m_image.FileHeader->FileHeader.TimeDateStamp));
		else
		{
			Output("Unable to load %s\n", filename);

			return false;
		}

		m_imagebase_loaded  = (DWORD) m_image.MappedAddress;
		m_imagebase_default = m_image.FileHeader->OptionalHeader.ImageBase;
		m_bLoaded           = true;
    }

    
	if ( !SymInitialize(m_hProcess, sympath, FALSE) ) 
	{
		Output("SymInitialize failed\n\n");
        return false;
	}

	
	m_symbolbase = SymLoadModule(m_hProcess, NULL, filename, 0, m_imagebase_loaded, 0 );
	
	if ( m_symbolbase==0 )
	{
		Output("SymLoadModule failed\n\n");
        return false;
	}

    IMAGEHLP_MODULE im;
    im.SizeOfStruct = sizeof(im);

    SymGetModuleInfo( m_hProcess, m_symbolbase, &im );
	
	Output("""%s"" loaded. %s\n", im.LoadedImageName, ctime((time_t *) & im.TimeDateStamp));
	
	return true;
}
Esempio n. 2
0
BOOL CMemLeakDetect::symModuleNameFromAddress( ADDR address, TCHAR* lpszModule )
{
	BOOL              ret = FALSE;
	IMAGEHLP_MODULE   moduleInfo;
	::ZeroMemory( &moduleInfo, sizeof(IMAGEHLP_MODULE) );
	moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
	if ( SymGetModuleInfo( m_hProcess, (ADDR)address, &moduleInfo ) )
	{
		// Note. IMAGEHLP_MODULE::ModuleName seems to be hardcoded as 32 char/wchar_t (VS2008).
#ifdef UNICODE
		int len = (int)_tcslen(lpszModule) + 1 ;
		char dest[1024] ;
		WideCharToMultiByte( CP_ACP, 0, lpszModule, -1, dest, len, NULL, NULL );
		strcpy_s(moduleInfo.ModuleName, 32, dest);	// bloody ANSI!
#else
		strcpy_s(moduleInfo.ModuleName, 32, lpszModule);
#endif
		ret = TRUE;
	}
	else
	{
		_tcscpy_s( lpszModule, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);
	}
	
	return ret;
}
Esempio n. 3
0
/******************************************************************
 *		SymGetModuleInfoW (DBGHELP.@)
 *
 */
BOOL  WINAPI SymGetModuleInfoW(HANDLE hProcess, DWORD dwAddr, 
                               PIMAGEHLP_MODULEW ModuleInfo)
{
    IMAGEHLP_MODULE     mi;
    IMAGEHLP_MODULEW    miw;

    if (sizeof(miw) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");

    mi.SizeOfStruct = sizeof(mi);
    if (!SymGetModuleInfo(hProcess, dwAddr, &mi)) return FALSE;

    miw.SizeOfStruct  = mi.SizeOfStruct;
    miw.BaseOfImage   = mi.BaseOfImage;
    miw.ImageSize     = mi.ImageSize;
    miw.TimeDateStamp = mi.TimeDateStamp;
    miw.CheckSum      = mi.CheckSum;
    miw.NumSyms       = mi.NumSyms;
    miw.SymType       = mi.SymType;
    MultiByteToWideChar(CP_ACP, 0, mi.ModuleName, -1,   
                        miw.ModuleName, sizeof(miw.ModuleName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, mi.ImageName, -1,   
                        miw.ImageName, sizeof(miw.ImageName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, mi.LoadedImageName, -1,   
                        miw.LoadedImageName, sizeof(miw.LoadedImageName) / sizeof(WCHAR));
    memcpy(ModuleInfo, &miw, ModuleInfo->SizeOfStruct);

    return TRUE;
}
Esempio n. 4
0
static BOOL CALLBACK symbols_info_cb(PSYMBOL_INFO sym, ULONG size, PVOID ctx)
{
    struct dbg_type     type;
    IMAGEHLP_MODULE     mi;

    mi.SizeOfStruct = sizeof(mi);

    if (!SymGetModuleInfo(dbg_curr_process->handle, sym->ModBase, &mi))
        mi.ModuleName[0] = '\0';
    else
    {
        size_t  len = strlen(mi.ModuleName);
        if (len > 5 && !strcmp(mi.ModuleName + len - 5, "<elf>"))
            mi.ModuleName[len - 5] = '\0';
    }

    dbg_printf("%08lx: %s!%s", (ULONG_PTR)sym->Address, mi.ModuleName, sym->Name);
    type.id = sym->TypeIndex;
    type.module = sym->ModBase;

    if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0)
    {
        dbg_printf(" ");
        types_print_type(&type, FALSE);
    }
    dbg_printf("\n");
    return TRUE;
}
Esempio n. 5
0
/***********************************************************************
 *           print_address
 *
 * Print an 16- or 32-bit address, with the nearest symbol if any.
 */
void print_address(const ADDRESS64* addr, BOOLEAN with_line)
{
    char                buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*        si = (SYMBOL_INFO*)buffer;
    void*               lin = memory_to_linear_addr(addr);
    DWORD64             disp64;
    DWORD               disp;

    print_bare_address(addr);

    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen   = 256;
    if (!SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si)) return;
    dbg_printf(" %s", si->Name);
    if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
    if (with_line)
    {
        IMAGEHLP_LINE               il;
        IMAGEHLP_MODULE             im;

        il.SizeOfStruct = sizeof(il);
        if (SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il))
            dbg_printf(" [%s:%lu]", il.FileName, il.LineNumber);
        im.SizeOfStruct = sizeof(im);
        if (SymGetModuleInfo(dbg_curr_process->handle, (DWORD_PTR)lin, &im))
            dbg_printf(" in %s", im.ModuleName);
    }
}
Esempio n. 6
0
static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress)
{
	IMAGEHLP_MODULE moduleInfo;

	if (SymGetModuleInfo(hProcess, dwReturnAddress, &moduleInfo))
		return moduleInfo.BaseOfImage;
	else
	{
		MEMORY_BASIC_INFORMATION memoryBasicInfo;

		if (::VirtualQueryEx(hProcess, (LPVOID) dwReturnAddress,
			&memoryBasicInfo, sizeof(memoryBasicInfo)))
		{
			DWORD cch = 0;
			char szFile[MAX_PATH] = { 0 };

		 cch = GetModuleFileNameA((HINSTANCE)memoryBasicInfo.AllocationBase,
										 szFile, MAX_PATH);

		 // Ignore the return code since we can't do anything with it.
		 if (!SymLoadModule(hProcess,
			   NULL, ((cch) ? szFile : NULL),
			   NULL, (DWORD) memoryBasicInfo.AllocationBase, 0))
			{
				DWORD dwError = GetLastError();
				TRACE1("Error: %d\n", dwError);
			}
		 return (DWORD) memoryBasicInfo.AllocationBase;
	  }
		else
			TRACE1("Error is %d\n", GetLastError());
	}

	return 0;
}
Esempio n. 7
0
BOOL CallStack::symModuleNameFromAddress( UINT address, TCHAR* lpszModule, UINT BufSizeTCHARs)
{
    BOOL              ret = FALSE;
    IMAGEHLP_MODULE   moduleInfo;

    ::ZeroMemory( &moduleInfo, sizeof(IMAGEHLP_MODULE) );
    moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

    if ( SymGetModuleInfo( m_hProcess, (DWORD)address, &moduleInfo ) )
    {
        // Note. IMAGEHLP_MODULE::ModuleName seems to be hardcoded as 32 char/wchar_t (VS2008).
#ifdef UNICODE
        int len = _tcslen(lpszModule) + 1 ;
        char dest[1024] ;
        WideCharToMultiByte( CP_ACP, 0, lpszModule, -1, dest, len, NULL, NULL );

        strcpy_s(moduleInfo.ModuleName, 32, dest);  //  ANSI!
#else
        strcpy_s(moduleInfo.ModuleName, 32, lpszModule);
#endif
        ret = TRUE;
    }
    else
    {
        _tcscpy_s( lpszModule, BufSizeTCHARs, MLD_TRACEINFO_NOSYMBOL);
    }

    return ret;
}
Esempio n. 8
0
VOID
DumpSymbols(
    PDEBUGPACKET dp
    )
{
    IMAGEHLP_MODULE   mi;


    if (SymGetModuleInfo( dp->hProcess, 0, &mi )) {
        lprintf( MSG_SYMBOL_TABLE );
        do {
            lprintfs( "%s\r\n\r\n", mi.ImageName );
            SymEnumerateSymbols( dp->hProcess, mi.BaseOfImage, SymbolEnumFunc, NULL );
        } while( SymGetModuleInfo( dp->hProcess, (DWORD)-1, &mi ));
    }
}
Esempio n. 9
0
BOOL
ProcessModuleLoad ( PDEBUGPACKET dp, LPDEBUG_EVENT de )

/*++

Routine Description:

    Process all module load debug events, create process & dll load.
    The purpose is to allocate a MODULEINFO structure, fill in the
    necessary values, and load the symbol table.

Arguments:

    dp      - pointer to a debug packet
    de      - pointer to a debug event structure

Return Value:

    TRUE    - everything worked
    FALSE   - we're hosed

--*/

{
    HANDLE      hFile;
    DWORD       dwBaseOfImage;
    LPSTR       SymbolPath;

    if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
        hFile = de->u.CreateProcessInfo.hFile;
        dwBaseOfImage = (DWORD)de->u.CreateProcessInfo.lpBaseOfImage;
        dp->hProcess = de->u.CreateProcessInfo.hProcess;
        dp->dwProcessId = de->dwProcessId;
        SymInitialize( dp->hProcess, NULL, FALSE );
        SymbolPath = GetSymbolSearchPath();
        SymSetSearchPath( dp->hProcess, SymbolPath );
        free( SymbolPath );
    } else if (de->dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) {
        hFile = de->u.LoadDll.hFile;
        dwBaseOfImage = (DWORD)de->u.LoadDll.lpBaseOfDll;
    }

    if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) {
        return FALSE;
    }

    if (!SymLoadModule( dp->hProcess, hFile, NULL, NULL, dwBaseOfImage, 0 )) {
        return FALSE;
    } else {
        if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
            IMAGEHLP_MODULE   mi;
            if (SymGetModuleInfo( dp->hProcess, dwBaseOfImage, &mi )) {
                strcpy( szApp, mi.ImageName );
            }
        }
    }

    return TRUE;
}
Esempio n. 10
0
static BOOL CALLBACK mod_loader_cb(PSTR mod_name, DWORD base, void* ctx)
{
    struct mod_loader_info*     mli = (struct mod_loader_info*)ctx;

    if (!strcmp(mod_name, "<wine-loader>"))
    {
        if (SymGetModuleInfo(mli->handle, base, mli->imh_mod))
            return FALSE; /* stop enum */
    }
    return TRUE;
}
Esempio n. 11
0
DWORD CCallStackTrace::ConvertAddress(HANDLE hProcess, DWORD address, LPSTR output_buffer)
{
	char* current_pointer = output_buffer;
	IMAGEHLP_MODULE imagehlp_module;
	memset(&imagehlp_module, 0, sizeof(imagehlp_module));
	imagehlp_module.SizeOfStruct = sizeof(imagehlp_module);

	if ( SymGetModuleInfo(hProcess, address, &imagehlp_module) != FALSE )
	{
		char * image_name = strrchr(imagehlp_module.ImageName, '\\');

		if ( image_name != NULL )
			image_name += 1;
		else
			image_name = imagehlp_module.ImageName;

		current_pointer += sprintf(current_pointer, "%s : ", image_name);
	}
	else
	{
		current_pointer += sprintf(current_pointer, "<unknown module> : ");
	}

	DWORD displacement;
	char temp[0x11c];
	IMAGEHLP_SYMBOL * imagehlp_symbol = (IMAGEHLP_SYMBOL *)temp;
	memset(imagehlp_symbol, 0, sizeof(temp));
	imagehlp_symbol->SizeOfStruct = 24;
	imagehlp_symbol->Address = address;
	imagehlp_symbol->MaxNameLength = 0x104;

	if ( SymGetSymFromAddr(hProcess, address, &displacement, imagehlp_symbol) != FALSE )
	{
		current_pointer += sprintf(current_pointer, "%s() ", imagehlp_symbol->Name);

		IMAGEHLP_LINE imagehlp_line;
		memset(&imagehlp_line, 0, sizeof(imagehlp_line));
		imagehlp_line.SizeOfStruct = sizeof(IMAGEHLP_LINE);

		if ( SymGetLineFromAddr(hProcess, address, &displacement, &imagehlp_line) != FALSE )
		{
			current_pointer += sprintf(current_pointer, "// %s(%i)", imagehlp_line.FileName, imagehlp_line.LineNumber);
		}
	}
	else
	{
		current_pointer += sprintf(current_pointer, "<unknown symbol>");
	}
	
	current_pointer += sprintf(current_pointer, "\r\n");
	return current_pointer - output_buffer;
}
Esempio n. 12
0
DWORD __stdcall CCallStackTrace::GetModuleBase(HANDLE hProcess, DWORD address)
{
	IMAGEHLP_MODULE imagehlp_module;
	MEMORY_BASIC_INFORMATION memory_basic_information;
	char module_file_name[260];
	DWORD module_file_name_length;
	HANDLE file_handle;
	char * image_name;

	imagehlp_module.SizeOfStruct = sizeof(imagehlp_module);

	if ( SymGetModuleInfo(hProcess, address, &imagehlp_module) == TRUE )
	{
		return imagehlp_module.BaseOfImage;
	}

	if ( VirtualQueryEx(hProcess, (LPCVOID)address, &memory_basic_information, sizeof(memory_basic_information)) == FALSE )
	{
		return 0;
	}

	module_file_name_length = GetModuleFileName((HMODULE)memory_basic_information.AllocationBase, module_file_name, sizeof(module_file_name));

	if ( module_file_name_length )
	{
		file_handle = CreateFile(module_file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	}
	else
	{
		file_handle = NULL;
	}

	image_name = NULL;

	if ( module_file_name_length > 0 )
	{
		image_name = module_file_name;
	}
	else
	{
		image_name = NULL;
	}

	SymLoadModule(hProcess, file_handle, image_name, 0, (DWORD)memory_basic_information.AllocationBase, 0);

	return (DWORD)memory_basic_information.AllocationBase;
}
Esempio n. 13
0
static void stack_print_addr_and_args(int nf)
{
    char                        buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*                si = (SYMBOL_INFO*)buffer;
    IMAGEHLP_STACK_FRAME        ihsf;
    IMAGEHLP_LINE64             il;
    IMAGEHLP_MODULE             im;
    DWORD64                     disp64;

    print_bare_address(&dbg_curr_thread->frames[nf].addr_pc);

    stack_get_frame(nf, &ihsf);

    /* grab module where symbol is. If we don't have a module, we cannot print more */
    im.SizeOfStruct = sizeof(im);
    if (!SymGetModuleInfo(dbg_curr_process->handle, ihsf.InstructionOffset, &im))
        return;

    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen   = 256;
    if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
    {
        struct sym_enum se;
        DWORD           disp;

        dbg_printf(" %s", si->Name);
        if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);

        SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
        se.first = TRUE;
        se.frame = ihsf.FrameOffset;
        dbg_printf("(");
        SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
        dbg_printf(")");

        il.SizeOfStruct = sizeof(il);
        if (SymGetLineFromAddr64(dbg_curr_process->handle,
                                 ihsf.InstructionOffset, &disp, &il))
            dbg_printf(" [%s:%u]", il.FileName, il.LineNumber);
        dbg_printf(" in %s", im.ModuleName);
    }
    else dbg_printf(" in %s (+0x%lx)",
                        im.ModuleName, (DWORD_PTR)(ihsf.InstructionOffset - im.BaseOfImage));
}
Esempio n. 14
0
void StackTraceUtils::Impl::getSymbolName(
		StackTraceHandler &handler, void *address) {
#ifdef _WIN64
	typedef DWORD64 DWORDX;
#else
	typedef DWORD DWORDX;
#endif

	HANDLE process = ::GetCurrentProcess();
	if (!process) {
		handler("", -1);
		return;
	}

	IMAGEHLP_MODULE imageModule = { sizeof(IMAGEHLP_MODULE) };
	IMAGEHLP_LINE line ={ sizeof(IMAGEHLP_LINE) };
	DWORDX dispSym = 0;
	DWORD dispLine = 0;

	char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + MAX_PATH] = {0};
	IMAGEHLP_SYMBOL * imageSymbol = (IMAGEHLP_SYMBOL*) symbolBuffer;
	imageSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	imageSymbol->MaxNameLength = MAX_PATH;

	const DWORDX intAddress =
			static_cast<DWORDX>(reinterpret_cast<uintptr_t>(address));
	if(!SymGetModuleInfo(process, intAddress, &imageModule)) {
		util::detail::RawNumberFormatter formatter;
		handler(formatter(static_cast<uint64_t>(intAddress)), -1);
	}
	else if(!SymGetSymFromAddr(process, intAddress, &dispSym, imageSymbol)) {
		
		util::detail::RawNumberFormatter formatter;
		handler(formatter(static_cast<uint64_t>(intAddress)), -1);
	}
	else if(!SymGetLineFromAddr(process, intAddress, &dispLine, &line)) {
		handler(imageSymbol->Name, -1);
	}
	else {
		handler(imageSymbol->Name, line.LineNumber);
	}
}
Esempio n. 15
0
// Get the module name from a given address
static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule )
{
	BOOL              ret = FALSE;
	IMAGEHLP_MODULE   moduleInfo;

	::ZeroMemory( &moduleInfo, sizeof(moduleInfo) );
	moduleInfo.SizeOfStruct = sizeof(moduleInfo);

	if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) )
	{
		// Got it!
		PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule );
		ret = TRUE;
	}
	else
		// Not found :(
		_tcscpy( lpszModule, _T("?") );

	return ret;
}
Esempio n. 16
0
size_t GetModuleNameFromAddress(void* address, char* moduleName, size_t size)
{
	if (size) *moduleName = 0;
	{
		const char* sourceName;
		IMAGEHLP_MODULE moduleInfo = { sizeof (moduleInfo) };
		if (!SymGetModuleInfo(GetSymHandle(), CheckAddress(address), &moduleInfo)) {
			return 0;
		}
		sourceName = strrchr(moduleInfo.ImageName, '\\');
		if (sourceName) {
			sourceName++;
		} else {
			sourceName = moduleInfo.ImageName;
		}
		if (size) {
			strncpy(moduleName, sourceName, size)[size - 1] = 0;
		}
		return strlen(sourceName);
	}
}
Esempio n. 17
0
	static DWORD __stdcall GetModBase( HANDLE hProcess, DWORD dwAddr )
#endif
	{
		// Check in the symbol engine first.
		IMAGEHLP_MODULE stIHM;

		// This is what the MFC stack trace routines forgot to do so their
		//  code will not get the info out of the symbol engine.
		stIHM.SizeOfStruct = sizeof( IMAGEHLP_MODULE );

		if( SymGetModuleInfo( hProcess, dwAddr, &stIHM ) )
		{
			return ( stIHM.BaseOfImage );
		}
		else
		{
			// Let's go fishing.
			MEMORY_BASIC_INFORMATION stMBI;

			if( 0 != VirtualQueryEx( hProcess, (LPCVOID) dwAddr, &stMBI, sizeof( stMBI ) ) )
			{
				// Try and load it.
				DWORD dwNameLen = 0;
				TCHAR szFile[MAX_PATH];
				memset( szFile, 0, sizeof( szFile ) );
				HANDLE hFile = NULL;

				dwNameLen = GetModuleFileName( (HINSTANCE) stMBI.AllocationBase, szFile, MAX_PATH );
				if( 0 != dwNameLen )
				{
					hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
					SymLoadModule( hProcess, hFile, (PSTR) ( dwNameLen ? szFile : NULL ), NULL, (ULONG_PTR) stMBI.AllocationBase, 0 );
					CloseHandle( hFile );
				}
				return ( (ULONG_PTR) stMBI.AllocationBase );
			}
		}

		return ( 0 );
	}
Esempio n. 18
0
BOOL
CmdDisplayModules(
    LPSTR             CmdBuf,
    HANDLE            hProcess,
    HANDLE            hThread,
    PEXCEPTION_RECORD ExceptionRecord
    )
{
    IMAGEHLP_MODULE ModuleInfo;


    printf( "\n" );
    printf( "Address    Size                   Name  Symbol Status\n" );
    printf( "------------------------------------------------------------------\n" );
    for (ULONG i=0; i<MAX_DLLS; i++) {
        if (DllList[i].BaseAddress && !DllList[i].Unloaded) {
            printf( "0x%08x 0x%08x %16s\t",
                DllList[i].BaseAddress,
                DllList[i].Size,
                DllList[i].Name
                );
            if (SymGetModuleInfo( hProcess, DllList[i].BaseAddress, &ModuleInfo )) {
                if (ModuleInfo.SymType != SymNone) {
                    printf( "(symbols loaded)\t" );
                } else {
                    printf( "(symbols *NOT* loaded)\t" );
                }
                printf( "%s\t", ModuleInfo.LoadedImageName );
            } else {
                printf( "(symbols *NOT* loaded)\t" );
            }
            printf( "\n" );
        }
    }
    printf( "\n" );

    return TRUE;
}
Esempio n. 19
0
void StackTrace::trace(ProfileData &data){
	CaptureStackBackTrace(0, backtraceSize, backtrace, &hash);
	auto stk = data.stacks.find(hash);
	if (stk != data.stacks.end()) { idx = stk->second; return; };
	HANDLE process = GetCurrentProcess();

	const int MAXSYMBOLNAME = 128 - sizeof(IMAGEHLP_SYMBOL);
	char symbol64_buf[sizeof(IMAGEHLP_SYMBOL) + MAXSYMBOLNAME] = { 0 };
	IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(symbol64_buf);
	symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	symbol->MaxNameLength = MAXSYMBOLNAME - 1;
	IMAGEHLP_MODULE module;
	module.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	for (size_t i = backtraceSize - 1; i > 0; --i){
		int fileidx = 0;
		int linenum = 0;
		int symidx = 0;
		int modidx = 0;

		if (backtrace[i]){
			// Output stack frame symbols if available.
			if (SymGetSymFromAddr(process, (DWORD64)backtrace[i], 0, symbol)){
				std::string symbol_name = symbol->Name;
				if (strncmp("mallocHook<", symbol->Name, 11) == 0)
				{
					symbol_name = "malloc";
				}
				if (strncmp("freeHook<", symbol->Name, 9) == 0)
				{
					symbol_name = "free";
				}

				symidx =  data.intern(symbol_name);

				if (SymGetModuleInfo(process, (DWORD64)backtrace[i], &module))
				{
					modidx = data.intern(module.ModuleName);
				}
				
				// Output filename + line info if available.
				IMAGEHLP_LINE lineSymbol = { 0 };
				lineSymbol.SizeOfStruct = sizeof(IMAGEHLP_LINE);
				DWORD displacement;
				if (SymGetLineFromAddr(process, (DWORD64)backtrace[i], &displacement, &lineSymbol)){
					fileidx = data.intern(lineSymbol.FileName);
					linenum = lineSymbol.LineNumber;
				}
			}
			fprintf(data.output, "i %lx %lx", symbol->Address, modidx);
			if (symidx || fileidx)
			{
				fprintf(data.output, " %lx", symidx);
				if (fileidx) fprintf(data.output, " %lx %lx", fileidx, linenum);
			}
			fprintf(data.output, "\n");
		}
		else{
			continue;
		}
	}
	idx = data.instGraph.index((intptr_t*)backtrace, data.output);
	data.stacks.insert(std::make_pair(hash, idx));
}
Esempio n. 20
0
static BOOL ResolveSymbol(HANDLE hProcess, DWORD dwAddress,
	SYMBOL_INFO &siSymbol)
{
	BOOL fRetval = TRUE;

	siSymbol.dwAddress = dwAddress;

	union {
		CHAR rgchSymbol[sizeof(IMAGEHLP_SYMBOL) + 255];
		IMAGEHLP_SYMBOL  sym;
	};

	CHAR szUndec[256];
	CHAR szWithOffset[256];
	LPSTR pszSymbol = NULL;
	IMAGEHLP_MODULE mi;

	memset(&siSymbol, 0, sizeof(SYMBOL_INFO));
	mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	if (!SymGetModuleInfo(hProcess, dwAddress, &mi))
		lstrcpyA(siSymbol.szModule, "<no module>");
	else
	{
		LPSTR pszModule = strchr(mi.ImageName, '\\');
		if (pszModule == NULL)
			pszModule = mi.ImageName;
		else
			pszModule++;

		lstrcpynA(siSymbol.szModule, pszModule, _countof(siSymbol.szModule));
	   lstrcatA(siSymbol.szModule, "! ");
	}

	__try
	{
		sym.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		sym.Address = dwAddress;
		sym.MaxNameLength = 255;

		if (SymGetSymFromAddr(hProcess, dwAddress, &(siSymbol.dwOffset), &sym))
		{
			pszSymbol = sym.Name;

			if (UnDecorateSymbolName(sym.Name, szUndec, _countof(szUndec),
				UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS))
			{
				pszSymbol = szUndec;
			}
			else if (SymUnDName(&sym, szUndec, _countof(szUndec)))
			{
				pszSymbol = szUndec;
			}

			if (siSymbol.dwOffset != 0)
			{
				wsprintfA(szWithOffset, "%s + %d bytes", pszSymbol, siSymbol.dwOffset);
				pszSymbol = szWithOffset;
			}
	  }
	  else
		  pszSymbol = "<no symbol>";
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		pszSymbol = "<EX: no symbol>";
		siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
	}

	lstrcpynA(siSymbol.szSymbol, pszSymbol, _countof(siSymbol.szSymbol));
	return fRetval;
}
Esempio n. 21
0
void StackDumper::ShowStackCore( HANDLE hThread, CONTEXT& c )
{
	// This makes this code custom for 32-bit windows. There is a technique to find out what
	// machine type we are running on, but this should do us for a good while.
	DWORD imageType = IMAGE_FILE_MACHINE_I386;

	HANDLE hProcess = GetCurrentProcess();
	int frameNum; // counts walked frames
	DWORD offsetFromSymbol; // tells us how far from the symbol we were
	DWORD symOptions; // symbol handler settings
	IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *) malloc( IMGSYMLEN + MAXNAMELEN );
	IMAGEHLP_MODULE Module;
	IMAGEHLP_LINE Line;
	StrApp strSearchPath; // path to search for symbol tables (I think...JT)
	achar *tt = 0;

	STACKFRAME s; // in/out stackframe
	memset( &s, '\0', sizeof s );

	tt = new achar[TTBUFLEN];
	if (!tt)
		return;

	// Build symbol search path.
	// Add current directory
	if (::GetCurrentDirectory( TTBUFLEN, tt ) )
		AppendToStaWithSep(strSearchPath, tt);
	// Add directory containing executable or DLL we are running in.
	if (::GetModuleFileName( 0, tt, TTBUFLEN ) )
	{
		StrUni stuPath = tt; // convert to Unicode if necessary, allows use of wchars
		const OLECHAR * pchPath =  stuPath.Chars();

		const OLECHAR * pch;
		for (pch = pchPath + wcslen(pchPath) - 1; pch >= pchPath; -- pch )
		{
			// locate the rightmost path separator
			if ( *pch == L'\\' || *pch == L'/' || *pch == L':' )
				break;
		}
		// if we found one, p is pointing at it; if not, tt only contains
		// an exe name (no path), and p points before its first byte
		if ( pch != pchPath ) // path sep found?
		{
			if ( *pch == L':' ) // we leave colons in place
				++ pch;
			if (strSearchPath.Length())
				strSearchPath.Append(";");
			strSearchPath.Append(pchPath, (pch - pchPath));
		}
	}
	// environment variable _NT_SYMBOL_PATH
	if (::GetEnvironmentVariable( _T("_NT_SYMBOL_PATH"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);
	// environment variable _NT_ALTERNATE_SYMBOL_PATH
	if (::GetEnvironmentVariable( _T("_NT_ALTERNATE_SYMBOL_PATH"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);
	// environment variable SYSTEMROOT
	if (::GetEnvironmentVariable( _T("SYSTEMROOT"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);

	// Why oh why does SymInitialize() want a writeable string? Surely it doesn't modify it...
	// The doc clearly says it is an [in] parameter.
	// Also, there is not a wide character version of this function!
	StrAnsi staT(strSearchPath);
	if ( !::SymInitialize( hProcess, const_cast<char *>(staT.Chars()), false ) )
		goto LCleanup;

	// SymGetOptions()
	symOptions = SymGetOptions();
	symOptions |= SYMOPT_LOAD_LINES;
	symOptions &= ~SYMOPT_UNDNAME;
	SymSetOptions( symOptions ); // SymSetOptions()

	// Enumerate modules and tell imagehlp.dll about them.
	// On NT, this is not necessary, but it won't hurt.
	EnumAndLoadModuleSymbols( hProcess, GetCurrentProcessId() );

	// init STACKFRAME for first call
	// Notes: AddrModeFlat is just an assumption. I hate VDM debugging.
	// Notes: will have to be #ifdef-ed for Alphas; MIPSes are dead anyway,
	// and good riddance.
	s.AddrPC.Offset = c.Eip;
	s.AddrPC.Mode = AddrModeFlat;
	s.AddrFrame.Offset = c.Ebp;
	s.AddrFrame.Mode = AddrModeFlat;

	memset( pSym, '\0', IMGSYMLEN + MAXNAMELEN );
	pSym->SizeOfStruct = IMGSYMLEN;
	pSym->MaxNameLength = MAXNAMELEN;

	memset( &Line, '\0', sizeof Line );
	Line.SizeOfStruct = sizeof Line;

	memset( &Module, '\0', sizeof Module );
	Module.SizeOfStruct = sizeof Module;

	offsetFromSymbol = 0;

	if (!m_pstaDump)
	{
		try
		{
			m_pstaDump = NewObj StrAnsiBufHuge;
		}
		catch (...)
		{
			goto LCleanup;
		}
	}

	// If the stack dump gets too big, we remove some entries from near the
	// middle, and insert a marker. This counts the characters up to the
	// end of the marker.
	int ichEndLowHalf;
	ichEndLowHalf = 0;

	m_pstaDump->FormatAppend( "\r\n--# FV EIP----- RetAddr- FramePtr StackPtr Symbol\r\n" );
	// EberhardB: a stack of 1.000 frames should be enough in most cases; limiting it
	// prevents a mysterious infinite(?) loop on our build machine.
	for ( frameNum = 0; frameNum < 1000; ++ frameNum )
	{
		// get next stack frame (StackWalk(), SymFunctionTableAccess(), SymGetModuleBase())
		// if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
		// assume that either you are done, or that the stack is so hosed that the next
		// deeper frame could not be found.
		if ( ! StackWalk( imageType, hProcess, hThread, &s, &c, NULL,
			SymFunctionTableAccess, SymGetModuleBase, NULL ) )
			break;

		// display its contents
		m_pstaDump->FormatAppend( "%3d %c%c %08x %08x %08x %08x ",
			frameNum, s.Far? 'F': '.', s.Virtual? 'V': '.',
			s.AddrPC.Offset, s.AddrReturn.Offset,
			s.AddrFrame.Offset, s.AddrStack.Offset );

		if ( s.AddrPC.Offset == 0 )
		{
			m_pstaDump->Append( "(-nosymbols- PC == 0)\r\n" );
		}
		else
		{ // we seem to have a valid PC
			char undName[MAXNAMELEN]; // undecorated name
			//char undFullName[MAXNAMELEN]; // undecorated name with all shenanigans
			// show procedure info (SymGetSymFromAddr())
			if ( ! SymGetSymFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, pSym ) )
			{
				if ( gle != 487 )
					m_pstaDump->FormatAppend( "SymGetSymFromAddr(): gle = %u\r\n", gle );
			}
			else
			{
				UnDecorateSymbolName( pSym->Name, undName, MAXNAMELEN, UNDNAME_NAME_ONLY );
				//UnDecorateSymbolName( pSym->Name, undFullName, MAXNAMELEN, UNDNAME_COMPLETE );
				m_pstaDump->Append( undName );
				//if ( offsetFromSymbol != 0 )
				//	m_pstaDump->FormatAppend( " %+d bytes", offsetFromSymbol );
				//m_pstaDump->FormatAppend( "\r\n    Sig:  %s\r\n", pSym->Name );
				//m_pstaDump->FormatAppend( "\r\n    Decl: %s\r\n", undFullName );
			}

			// show line number info, NT5.0-method (SymGetLineFromAddr()). If we can't get this function,
			// or it doesn't work, leave out line number info.
			if (! g_pfnSymGetLineFromAddr)
			{
				StrApp staModName("IMAGEHLP.DLL");
				g_pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR) GetProcAddress(
					GetModuleHandle(staModName.Chars()), "SymGetLineFromAddr");
			}
			if (! g_pfnSymGetLineFromAddr ||
				! g_pfnSymGetLineFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, &Line ) )
			{
				if ( g_pfnSymGetLineFromAddr && gle != 487 ) // apparently a magic number indicating not in symbol file.
					m_pstaDump->FormatAppend( "SymGetLineFromAddr(): gle = %u\r\n", gle );
				else
					m_pstaDump->FormatAppend( "   (no line # avail)\r\n");

			}
			else
			{
				m_pstaDump->FormatAppend( "   %s(%u)\r\n",
					Line.FileName, Line.LineNumber );
			}

#ifdef JT_20010626_WantModuleInfo
			// If we want this info adapt the printf and _snprintf in the following.

			// show module info (SymGetModuleInfo())
			if ( ! SymGetModuleInfo( hProcess, s.AddrPC.Offset, &Module ) )
			{
				m_pstaDump->FormatAppend( "SymGetModuleInfo): gle = %u\r\n", gle );
			}
			else
			{ // got module info OK
				m_pstaDump->FormatAppend( "    Mod:  %s[%s], base: 0x%x\r\n    Sym:  type: ",
					Module.ModuleName, Module.ImageName, Module.BaseOfImage );
				switch ( Module.SymType )
					{
					case SymNone:
						m_pstaDump->FormatAppend( "-nosymbols-");
						break;
					case SymCoff:
						m_pstaDump->FormatAppend( "COFF");
						break;
					case SymCv:
						m_pstaDump->FormatAppend( "CV");
						break;
					case SymPdb:
						m_pstaDump->FormatAppend( "PDB");
						break;
					case SymExport:
						m_pstaDump->FormatAppend( "-exported-");
						break;
					case SymDeferred:
						m_pstaDump->FormatAppend( "-deferred-");
						break;
					case SymSym:
						m_pstaDump->FormatAppend( "SYM");
						break;
					default:
						m_pstaDump->FormatAppend( "symtype=%d", (long) Module.SymType);
						break;
					}
				m_pstaDump->FormatAppend( ", file: %s\r\n", Module.LoadedImageName);
			} // got module info OK
#endif // JT_20010626_WantModuleInfo

			// We don't want to return more than about 10K of info (enough for an email).
			// This also serves to make sure there's enough room in the buffer for more.
			// The idea is that we'd like to keep both the top and bottom of the stack.
			// So we delete frames from the middle until we have less than 10K.
			if (m_pstaDump->Length() > MAXDUMPLEN)
			{
				if (!ichEndLowHalf)
				{
					static char * pszGap =
						"\r\n\r\n\r\n******************Frames skipped here***************\r\n\r\n\r\n";
					int cchGap = strlen(pszGap);
					ichEndLowHalf = FindStartOfFrame(MAXDUMPLEN / 2);
					// Overwrite some of what's there with the gap marker. The incomplete
					// frame will be part of what gets deleted.
					m_pstaDump->Replace(ichEndLowHalf, ichEndLowHalf + cchGap, pszGap, cchGap);
					ichEndLowHalf += cchGap;
				}
				int cchLeave = m_pstaDump->Length();
				int ichKeep = ichEndLowHalf;
				while (cchLeave > MAXDUMPLEN)
				{
					int ichKeepT = FindStartOfFrame(ichKeep + 1);
					cchLeave -= ichKeepT - ichKeep;
					ichKeep = ichKeepT;
				}
				m_pstaDump->Replace(ichEndLowHalf, ichKeep, (char *)NULL, 0);
			}

		} // we seem to have a valid PC

		// no return address means no deeper stackframe
		if ( s.AddrReturn.Offset == 0 )
		{
			// avoid misunderstandings in the printf() following the loop
			SetLastError( 0 );
			break;
		}

	} // for ( frameNum )

	if ( gle != 0 )
		printf( "\r\nStackWalk(): gle = %u\r\n", gle );

LCleanup:
	ResumeThread( hThread );
	// de-init symbol handler etc.
	SymCleanup( hProcess );
	free( pSym );
	delete [] tt;

#ifdef DEBUG
	::OutputDebugStringA(m_pstaDump->Chars());
#endif

}
Esempio n. 22
0
int getDebugInfo(char* fname)
{
	HANDLE Self;
	DWORD moduleAddr;
	IMAGEHLP_MODULE moduleInfo;

	namesSize = 1;

	maxDebug = CodeSize + 10000;
	hasDebug = calloc(maxDebug, sizeof(int));
	names    = calloc(MAX_NAMES_SIZE,1);
	nonCode    = calloc(MAX_NONCODE_SIZE,sizeof(Sym));
	nonCodeCount = 0;

	Self = GetCurrentProcess();

	SymSetOptions(SYMOPT_LOAD_LINES);

	if(!SymInitialize(Self,NULL,FALSE)) {
		printf("Failed to initialize Sym \n");
		return -1;
	}

	printf("Trying to load with base = %08X\n",imageBase);
//	moduleAddr = SymLoadModule(Self,NULL,fname,NULL,imageBase+BASE_SHIFT,0);
	moduleAddr = SymLoadModule(Self,NULL,fname,NULL,0,0);

    if(!moduleAddr) {
		printf("Error: %n",GetLastError());
		return -1;
	}

	moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	if(SymGetModuleInfo(Self,moduleAddr,&moduleInfo)) {
		printf("ImageSize		: %d \n",moduleInfo.ImageSize);
		printf("NumSyms			: %d \n",moduleInfo.NumSyms);
		
		printf("SymType			: ");
		switch (moduleInfo.SymType) {
			case SymNone : printf("No symbols are loaded \n"); 
							break;
			case SymCoff : printf("COFF symbols \n"); 
							break;
			case SymCv	 : printf("CodeView symbols \n");
							break;
			case SymPdb  : printf("pdb file \n");
							break;
			case SymExport : printf("Symbols generated from a DLL's export table\n");
							break;
			case SymDeferred : printf("The library has not yet attempted to load symbols.\n"); 
							break;
			case SymSym : printf(".SYM file \n");
							break;
			default:  printf("Unknown value for SymType : %d\n",moduleInfo.SymType);
		}
		printf("ModuleName		: %s\n",moduleInfo.ModuleName);
		printf("ImageName		: %s\n",moduleInfo.ImageName);
		printf("LoadedImageName	: %s\n",moduleInfo.LoadedImageName); 
		printf("LoadedImageBase : %08X\n",moduleInfo.BaseOfImage);


	}

	SymEnumerateSymbols(Self,moduleAddr,SymbolEnumumeration,NULL);

	SymUnloadModule(Self,moduleAddr);
	SymCleanup(Self);

	return 0;
}
Esempio n. 23
0
BOOL
CmdBreakPoint(
    LPSTR             CmdBuf,
    HANDLE            hProcess,
    HANDLE            hThread,
    PEXCEPTION_RECORD ExceptionRecord
    )
{
    CHAR BpCmd = tolower(CmdBuf[1]);
    ULONG Address = 0;
    PBREAKPOINT_INFO bp;
    PPROCESS_INFO ThisProcess;
    ULONG Flags;
    LPSTR p;
    LPSTR SymName;
    ULONG i;
    IMAGEHLP_MODULE mi;


    ThisProcess = GetProcessInfo( hProcess );
    if (!ThisProcess) {
        printf( "could not get process information\n" );
        return FALSE;
    }

    PTHREAD_INFO ThisThread = GetThreadInfo( hProcess, hThread );
    if (!ThisThread) {
        printf( "could not get thread information\n" );
        return FALSE;
    }

    SKIP_NONWHITE( CmdBuf );
    SKIP_WHITE( CmdBuf );
    p = CmdBuf;

    switch ( BpCmd ) {
        case 'p':
            Flags = 0;
            CmdBuf = GetAddress( CmdBuf, &Address );
            SymName = (LPSTR) MemAlloc( CmdBuf - p + 16 );
            if (!SymName) {
                printf( "could not allocate memory for bp command\n" );
                break;
            }
            strncpy( SymName, p, CmdBuf - p );
            if (!Address) {
                Flags = BPF_UNINSTANCIATED;
                printf( "breakpoint not instanciated\n" );
            }
            bp = SetBreakpoint(
                ThisProcess,
                Address,
                Flags,
                SymName,
                UserBpHandler
                );
            MemFree( SymName );
            if (!bp) {
                printf( "could not set breakpoint\n" );
            }
            ThisProcess->UserBpCount += 1;
            bp->Number = ThisProcess->UserBpCount;
            SKIP_WHITE( CmdBuf );
            if (CmdBuf[0]) {
                if (CmdBuf[0] == '/') {
                    switch (tolower(CmdBuf[1])) {
                        case 'c':
                            CmdBuf += 3;
                            if (CmdBuf[0] != '\"') {
                                printf( "invalid syntax\n" );
                                return FALSE;
                            }
                            CmdBuf += 1;
                            p = strchr( CmdBuf, '\"' );
                            if (!p) {
                                printf( "invalid syntax\n" );
                                return FALSE;
                            }
                            p[0] = 0;
                            bp->Command = _strdup( CmdBuf );
                            break;

                        default:
                            break;
                    }
                }
            }
            break;

        case 'l':
            for (i=0; i<MAX_BREAKPOINTS; i++) {
                if (ThisProcess->Breakpoints[i].Number) {
                    ULONG disp = 0;
                    if (ThisProcess->Breakpoints[i].Flags & BPF_WATCH) {
                        printf( "#%d %c%c\t          \tWatch\n",
                            ThisProcess->Breakpoints[i].Number,
                            ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I',
                            ThisProcess->Breakpoints[i].Flags & BPF_DISABLED       ? 'D' : 'E'
                            );
                    } else if ((ThisProcess->Breakpoints[i].Address != 0) &&
                        (ThisProcess->Breakpoints[i].Address != 0xffffffff)) {
                        SymGetModuleInfo(
                            ThisProcess->hProcess,
                            ThisProcess->Breakpoints[i].Address,
                            &mi
                            );
                        if (SymGetSymFromAddr(
                            ThisProcess->hProcess,
                            ThisProcess->Breakpoints[i].Address,
                            &disp,
                            sym
                            )) {
                                printf( "#%d %c%c\t0x%08x\t%s!%s\n",
                                    ThisProcess->Breakpoints[i].Number,
                                    ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I',
                                    ThisProcess->Breakpoints[i].Flags & BPF_DISABLED       ? 'D' : 'E',
                                    ThisProcess->Breakpoints[i].Address,
                                    mi.ModuleName,
                                    sym ? sym->Name : ""
                                    );
                        }
                    } else {
                        printf( "#%d %c%c\t          \t%s\n",
                            ThisProcess->Breakpoints[i].Number,
                            ThisProcess->Breakpoints[i].Flags & BPF_UNINSTANCIATED ? 'U' : 'I',
                            ThisProcess->Breakpoints[i].Flags & BPF_DISABLED       ? 'D' : 'E',
                            ThisProcess->Breakpoints[i].SymName
                            );
                    }
                }
            }
            break;

        case 'c':
            if (!CmdBuf[0]) {
                printf( "missing breakpoint number\n" );
                return FALSE;
            }
            if (CmdBuf[0] == '*') {
                for (i=0; i<MAX_BREAKPOINTS; i++) {
                    if (ThisProcess->Breakpoints[i].Number) {
                        ClearBreakpoint( ThisProcess, &ThisProcess->Breakpoints[i] );
                    }
                }
                return TRUE;
            }
            if (isdigit(CmdBuf[0])) {
                ULONG BpNum = atoi( CmdBuf );
                for (i=0; i<MAX_BREAKPOINTS; i++) {
                    if (ThisProcess->Breakpoints[i].Number == BpNum) {
                        ClearBreakpoint( ThisProcess, &ThisProcess->Breakpoints[i] );
                        return TRUE;
                    }
                }
            }
            printf( "invalid breakpoint number\n" );
            return FALSE;

        case 'd':
            break;

        case 'e':
            break;

        case 'a':
#if defined(_M_IX86)
            CmdBuf = GetAddress( CmdBuf, &Address );

            bp = GetAvailBreakpoint( ThisProcess );
            if (!bp) {
                printf( "could not set breakpoint\n" );
                return FALSE;
            }

            bp->Address = Address;
            bp->Handler = UserBpHandler;
            bp->Flags   = BPF_WATCH;

            ThisProcess->UserBpCount += 1;
            bp->Number = ThisProcess->UserBpCount;

            CurrContext.Dr0 = Address;
            CurrContext.Dr6 = 0x000d0002;
            SetRegContext( ThisThread->hThread, &CurrContext );
#else
            printf( "only available on x86\n" );
#endif
            break;

        default:
            break;
    }

    return TRUE;
}
Esempio n. 24
0
    void
    backtrace() {
        static struct sym_t {
            HANDLE proc;
            sym_t() {
                proc = GetCurrentProcess();
                SymSetOptions(
                    SYMOPT_DEFERRED_LOADS | // シンボルを参照する必要があるときまで読み込まない
                    SYMOPT_LOAD_LINES |     // 行番号情報を読み込む
                    SYMOPT_UNDNAME          // すべてのシンボルを装飾されていない形式で表します
                    );
                if(!SymInitialize(proc, 0, true)){
                    throw exception("error : SymInitialize");
                }
                // cout << "<SymInitialize>" << endl;
            }
            ~sym_t() {
                SymCleanup(proc);
                // cout << "<SymCleanup>" << endl;
            }
        } s_sym;

        array<void*,8> addr;
        int count = RtlCaptureStackBackTrace(0, addr.size(), &addr[0], 0);
        cout << "---- BEGIN BACKTRACE ----" << endl;
        for(int Li = 1; Li < count; ++Li){
            auto p = reinterpret_cast<uintptr_t>(addr[Li]);

            IMAGEHLP_MODULE module;
            ::memset(&module, 0, sizeof(module));
            module.SizeOfStruct = sizeof(module);
            if(!SymGetModuleInfo(s_sym.proc, p, &module)){
                throw exception("error : SymGetModuleInfo");
            }

            char buffer[sizeof(IMAGEHLP_SYMBOL) + MAX_PATH];
            ::memset(buffer, 0, sizeof(buffer));
            auto symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(buffer);
            symbol->SizeOfStruct = sizeof(*symbol);
            symbol->MaxNameLength = MAX_PATH;

            DWORDx disp = 0;
            if(!SymGetSymFromAddr(s_sym.proc, p, &disp, symbol)){
                throw exception("error : SymGetSymFromAddr");
            }
            if(!strcmp(symbol->Name, "__tmainCRTStartup")){
                break;
            }

            string text = "?";
            IMAGEHLP_LINE line;
            ::memset(&line, 0, sizeof(line));
            line.SizeOfStruct = sizeof(line);
            DWORD disp2 = 0;
            if(!SymGetLineFromAddr(s_sym.proc, p, &disp2, &line)){
                line.FileName = "?";
                line.LineNumber = 0;
                text = "?";
            } else {
                text = getline(line.FileName, line.LineNumber);
            }

            cout << Li
                 << " : 0x" << hex << setw(sizeof(uintptr_t) * 2) << setfill('0') << p
                 << " : " << module.ModuleName
                 << " : " << symbol->Name
                 << " : " << line.FileName << "(" << dec << line.LineNumber << ")"
                 << " : " << text.c_str()
                 << endl;
        }
        cout << "---- END BACKTRACE ----" << endl << endl;
    }
Esempio n. 25
0
/* Runs a stack trace 
 * Parameters:
 *  e - The exception information
 * Returns:
 *  The stack trace with function and line number information
 */
__inline char *StackTrace(EXCEPTION_POINTERS *e) 
{
	static char buffer[5000];
	char curmodule[32];
	DWORD symOptions, dwDisp, frame;
	HANDLE hProcess = GetCurrentProcess();
	IMAGEHLP_SYMBOL *pSym = MyMallocEx(sizeof(IMAGEHLP_SYMBOL)+500);
	IMAGEHLP_LINE pLine;
	IMAGEHLP_MODULE pMod;
	STACKFRAME Stack;

	/* Load the stack information */
	memset(&Stack, 0, sizeof(Stack));
	Stack.AddrPC.Offset = e->ContextRecord->Eip;
	Stack.AddrPC.Mode = AddrModeFlat;
	Stack.AddrFrame.Offset = e->ContextRecord->Ebp;
	Stack.AddrFrame.Mode = AddrModeFlat;
	Stack.AddrStack.Offset = e->ContextRecord->Esp;
	Stack.AddrStack.Mode = AddrModeFlat;
	if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
		hProcess = (HANDLE)GetCurrentProcessId();
	else
		hProcess = GetCurrentProcess();	

	/* Initialize symbol retrieval system */
	SymInitialize(hProcess, NULL, TRUE);
	SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_UNDNAME);
	bzero(pSym, sizeof(IMAGEHLP_SYMBOL)+500);
	pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	pSym->MaxNameLength = 500;
	bzero(&pLine, sizeof(IMAGEHLP_LINE));
	pLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);
	bzero(&pMod, sizeof(IMAGEHLP_MODULE));
	pMod.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	/* Retrieve the first module name */
	SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
	strcpy(curmodule, pMod.ModuleName);
	sprintf(buffer, "\tModule: %s\n", pMod.ModuleName);

	/* Walk through the stack */
	for (frame = 0; ; frame++) 
	{
		char buf[500];
		if (!StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(),
			&Stack, NULL, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL))
			break;
		SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
		if (strcmp(curmodule, pMod.ModuleName)) 
		{
			strcpy(curmodule, pMod.ModuleName);
			sprintf(buf, "\tModule: %s\n", pMod.ModuleName);
			strcat(buffer, buf);
		}
		SymGetLineFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, &pLine);
		SymGetSymFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, pSym);
		sprintf(buf, "\t\t#%d %s:%d: %s\n", frame, pLine.FileName, pLine.LineNumber, 
		        pSym->Name);
		strcat(buffer, buf);
	}
	return buffer;

}
Esempio n. 26
0
PPROFBLK SetupProfiling(LPCTSTR ptchFileName)
{
		PVOID	ImageBase;
		PPROFBLK pProfBlk;
		PPROFBLK pPrevProfBlk;
		ULONG	 ulBlkOff;
		LPCSTR  ptchImageName;
	    TCHAR	atchImageName [256];
    	PIMAGE_NT_HEADERS  pImageNtHeader;
		IMAGEHLP_MODULE	 ModuleInfo;

	    // Skip directory name
	    if ( (ptchImageName = strrchr(ptchFileName, '\\')) )
	        ptchImageName++;
	    else
	        ptchImageName = (PTCHAR)ptchFileName;

		// Make uppercase copy
	    _strupr (strcpy (atchImageName, ptchImageName));

		// Don't profile CAP
	    if ( !strcmp (atchImageName, CAPDLL) )
	        return NULL;

		// Search prof blk list for matching image name
		pPrevProfBlk = NULL;
		ulBlkOff = ulLocProfBlkOff;

	    while (ulBlkOff != 0) 
	    {
    		pPrevProfBlk = MKPPROFBLK(ulBlkOff);

			// If found image, no need to set up new block
			if (!strcmp((PCHAR)pPrevProfBlk->atchImageName, atchImageName))
				return FALSE;

			ulBlkOff = pPrevProfBlk->ulNxtBlk;
		}

		try // Accessing new block can cause an access fault
			// which will extend the allocation 
		{
			// Place block at next available offset
			pProfBlk = MKPPROFBLK(*pulProfBlkBase);

			// Fill in initial values
			pProfBlk->ImageBase =0;
		    pProfBlk->CodeStart = 0;
		    pProfBlk->CodeLength = 0;
			pProfBlk->iSymCnt = 0;
			pProfBlk->State = BLKSTATE_ASSIGNED;
			pProfBlk->ulNxtBlk = 0;
		    strcpy ((TCHAR *) pProfBlk->atchImageName, atchImageName);

			// Link to previous block or initial block offset
			if (pPrevProfBlk)
				pPrevProfBlk->ulNxtBlk = *pulProfBlkBase;
			else
				ulLocProfBlkOff = *pulProfBlkBase;

			// Load module symbols
			ImageBase = GetModuleHandle(ptchImageName);
			SymLoadModule(hThisProcess, NULL, (LPSTR)ptchFileName,
												 (LPSTR)ptchImageName, (DWORD)ImageBase, 0);
			if (ImageBase != NULL)
			{
		 		pProfBlk->ImageBase = ImageBase;

				// Get code start address
				if ((pImageNtHeader = ImageNtHeader(ImageBase)) != NULL)
				{
					pProfBlk->CodeStart = (PULONG)((TCHAR *)ImageBase +
													 pImageNtHeader->OptionalHeader.BaseOfCode);
	  			}
				else
				{
					// If can't get code start, use imagebase as next best guess
					pProfBlk->CodeStart = ImageBase;
				}

	#if defined(MIPS) && !defined(MIPS_VC40_INTERFACE)

				// Enumerate symbols to find adress of _penter
		    	fPenterFound = FALSE;
				SymEnumerateSymbols(hThisProcess, (DWORD)ImageBase,
									 FindPenterCallback, (PVOID)pProfBlk);

	#endif // MIPS && !MIPS_VC40_INTERFACE

				// Get module info for symbols count
				SymGetModuleInfo(hThisProcess, (DWORD)ImageBase, &ModuleInfo);
				pProfBlk->iSymCnt = ModuleInfo.NumSyms;

				// Determine location for symbols and symbol names
				pProfSymb = (PSYMINFO)(&pProfBlk->atchImageName[strlen(atchImageName) + 1]);
				pProfBlk->ulSym = (PTCHAR)pProfSymb - (PTCHAR)pulProfBlkBase;
				pcProfSymbName = (PTCHAR)&pProfSymb[ModuleInfo.NumSyms];

				// Now enumerate symbols to build up symbol table
				ulMaxSymbAddr = (ULONG)pProfBlk->CodeStart;
				SymEnumerateSymbols(hThisProcess, (DWORD)ImageBase,
									 SymbolEnumCallback, (PVOID)pProfBlk);

				// Set symbol range based on max symbol address	encountered
				if (ulMaxSymbAddr > (ULONG)pProfBlk->CodeStart)
					pProfBlk->CodeLength = ulMaxSymbAddr - (ULONG)pProfBlk->CodeStart;

				// Update pointer to available space
				*pulProfBlkBase = (ULONG)(pcProfSymbName - (PTCHAR)pulProfBlkBase);

				// Unload the module
				SymUnloadModule(hThisProcess, (DWORD)ImageBase);

				// Do any requested import/export patching
	        	PatchDll (ptchPatchImports, ptchPatchCallers, bCallersToPatch,
	                       atchImageName, ImageBase);
			}
			else
			{	
				// No symbols - Update offset to next free space
				*pulProfBlkBase = (ULONG)&pProfBlk->atchImageName[strlen(atchImageName) + 1]
									-(ULONG)pulProfBlkBase;
			} // ImageBase != NULL

		}
		//
		// + : transfer control to the handler (EXCEPTION_EXECUTE_HANDLER)
		// 0 : continue search                 (EXCEPTION_CONTINUE_SEARCH)
		// - : dismiss exception & continue    (EXCEPTION_CONTINUE_EXECUTION)
		//
		except ( AccessXcptFilter (GetExceptionCode(), GetExceptionInformation(), COMMIT_SIZE))
		{
		    // Should never get here since filter never returns
		    // EXCEPTION_EXECUTE_HANDLER.
		    CapDbgPrint ("CAP:  DoDllInitializations() - *LOGIC ERROR* - "
		              "Inside the EXCEPT: (xcpt=0x%lx)\n", GetExceptionCode());
		} // end of TRY/EXCEPT

		return pProfBlk;
}
Esempio n. 27
0
void
AddImage(
    PSZ   pszName,
    PVOID BaseOfDll,
    ULONG SizeOfImage,
    ULONG CheckSum,
    ULONG ProcessId,
    PSZ   pszModuleName,
    BOOL  ForceSymbolLoad
    )
{
    PIMAGE_INFO         pImageNew;
    PIMAGE_INFO         *pp;
    UCHAR               index = 0;
    PSZ                 pszBaseName;
    PCHAR               KernelBaseFileName;
    HANDLE              KernelBaseFileHandle;
    DWORD               BytesWritten;
    IMAGEHLP_MODULE     mi;
    CHAR                buf[256];
    ULONG               LoadAddress;


    if (pszName == NULL) {
        return;
    }

    if ((_stricmp( pszName, KERNEL_IMAGE_NAME ) == 0) ||
        (_stricmp( pszName, KERNEL_IMAGE_NAME_MP ) == 0)) {
        //
        // rename the image if necessary
        //
        if (GetModnameFromImage( (ULONG)BaseOfDll, NULL, buf )) {
            strcpy( pszName, buf );
        }
        pszModuleName = "NT";
    }

    if (_stricmp( pszName, HAL_IMAGE_FILE_NAME ) == 0) {
        //
        // rename the image if necessary
        //
        if (GetModnameFromImage( (ULONG)BaseOfDll, NULL, buf )) {
            strcpy( pszName, buf );
        }
        pszModuleName = "HAL";
    }

    pszBaseName = strchr(pszName,'\0');
    while (pszBaseName > pszName) {
        if (pszBaseName[-1] == '\\' || pszBaseName[-1] == '/' || pszBaseName[-1] == ':') {
            pszName = pszBaseName;
            break;
        } else {
            pszBaseName -= 1;
        }
    }

    //
    //  search for existing image with same checksum at same base address
    //      if found, remove symbols, but leave image structure intact
    //

    pp = &pProcessCurrent->pImageHead;
    while (pImageNew = *pp) {
        if (pImageNew->lpBaseOfImage == BaseOfDll) {

            if (fVerboseOutput) {
                dprintf("%s: force unload of %s\n", DebuggerName, pImageNew->szImagePath);
            }
            SymUnloadModule( pProcessCurrent->hProcess, (ULONG)pImageNew->lpBaseOfImage );
            break;

        } else if (pImageNew->lpBaseOfImage > BaseOfDll) {

            pImageNew = NULL;
            break;

        }

        pp = &pImageNew->pImageNext;
    }

    //  if not found, allocate and fill new image structure

    if (!pImageNew) {
        for (index=0; index<pProcessCurrent->MaxIndex; index++) {
            if (pProcessCurrent->pImageByIndex[ index ] == NULL) {
                pImageNew = calloc(sizeof(IMAGE_INFO),1);
                break;
            }
        }

        if (!pImageNew) {
            DWORD NewMaxIndex;
            PIMAGE_INFO *NewImageByIndex;

            NewMaxIndex = pProcessCurrent->MaxIndex + 32;
            if (NewMaxIndex < 0x100) {
                NewImageByIndex = calloc( NewMaxIndex,  sizeof( *NewImageByIndex ) );
            } else {
                NewImageByIndex = NULL;
            }
            if (NewImageByIndex == NULL) {
                dprintf("%s: No room for %s image record.\n",
                        DebuggerName,
                        pszName );
                return;
            }

            if (pProcessCurrent->pImageByIndex) {
                memcpy( NewImageByIndex,
                        pProcessCurrent->pImageByIndex,
                        pProcessCurrent->MaxIndex * sizeof( *NewImageByIndex )
                      );
                free( pProcessCurrent->pImageByIndex );
            }

            pProcessCurrent->pImageByIndex = NewImageByIndex;
            index = (UCHAR) pProcessCurrent->MaxIndex;
            pProcessCurrent->MaxIndex = NewMaxIndex;
            pImageNew = calloc(sizeof(IMAGE_INFO),1);
            if (!pImageNew) {
                dprintf("%s: Unable to allocate memory for %s symbols.\n",
                        DebuggerName, pszName);
                return;
            }
        }

        pImageNew->pImageNext = *pp;
        *pp = pImageNew;

        pImageNew->index = index;
        pProcessCurrent->pImageByIndex[ index ] = pImageNew;
    }

    //
    //  pImageNew has either the unloaded structure or the newly created one
    //
    pImageNew->lpBaseOfImage = BaseOfDll;
    pImageNew->dwCheckSum = CheckSum;
    pImageNew->dwSizeOfImage = SizeOfImage;
    pImageNew->GoodCheckSum = TRUE;
    strcpy( pImageNew->szImagePath, pszName );

    LoadAddress = SymLoadModule(
        pProcessCurrent->hProcess,
        NULL,
        pImageNew->szImagePath,
        pszModuleName,
        (ULONG)pImageNew->lpBaseOfImage,
        pImageNew->dwSizeOfImage
        );

    if (!LoadAddress) {
        DelImage( pszName, 0, 0 );
        return;
    }

    if (!pImageNew->lpBaseOfImage) {
        pImageNew->lpBaseOfImage = (PVOID)LoadAddress;
    }

    if (ForceSymbolLoad) {
        SymLoadModule(
            pProcessCurrent->hProcess,
            NULL,
            NULL,
            NULL,
            (ULONG)pImageNew->lpBaseOfImage,
            0
            );
    }

    if (SymGetModuleInfo( pProcessCurrent->hProcess, (ULONG)pImageNew->lpBaseOfImage, &mi )) {
        pImageNew->dwSizeOfImage = mi.ImageSize;
        strcpy( pImageNew->szImagePath, mi.ImageName );
        strcpy( pImageNew->szDebugPath, mi.LoadedImageName );
    } else {
        DelImage( pszName, 0, 0 );
        return;
    }

    if (pszModuleName) {
        strcpy( pImageNew->szModuleName, pszModuleName );
    } else {
        CreateModuleNameFromPath( pImageNew->szImagePath, pImageNew->szModuleName );
    }

    if (fVerboseOutput) {
        dprintf( "%s ModLoad: %08lx %08lx   %-8s\n",
                 DebuggerName,
                 pImageNew->lpBaseOfImage,
                 (ULONG)(pImageNew->lpBaseOfImage) + pImageNew->dwSizeOfImage,
                 pImageNew->szImagePath
                 );
    }
}
Esempio n. 28
0
DWORD
ConsoleDebugger(
    HANDLE              hProcess,
    HANDLE              hThread,
    PEXCEPTION_RECORD   ExceptionRecord,
    BOOL                UnexpectedException,
    LPSTR               InitialCommand
    )
{
    PPROCESS_INFO ThisProcess;
    DWORD ContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
    static CHAR CmdBuf[512];

    Stepped = FALSE;

    if (!ConsoleCreated) {
        CmdBuf[0] = 0;
        if (!CreateDebuggerConsole()) {
            return ContinueStatus;
        }
    }

    ThisProcess = GetProcessInfo( hProcess );
    if (!ThisProcess) {
        printf( "could not get process information\n" );
    }

    if (UnexpectedException) {
        printf( "\n" );
        printf( "*---------------------------------------\n" );
        printf( "An unexpected error has occurred\n" );
        printf( "Address:     0x%08x\n", ExceptionRecord->ExceptionAddress );
        printf( "Error code:  0x%08x\n", ExceptionRecord->ExceptionCode );
        printf( "*---------------------------------------\n" );
        PrintRegisters();
        PrintOneInstruction( hProcess, (ULONG)ExceptionRecord->ExceptionAddress );
    }

    if (BreakInNow) {
        BreakInNow = FALSE;
        printf( "*** Initial breakpoint\n\n" );
    }

    //
    // check to see if any modules need symbols loading
    //
    for (ULONG i=0; i<MAX_DLLS; i++) {
        if (DllList[i].BaseAddress && !DllList[i].Unloaded) {
            IMAGEHLP_MODULE ModuleInfo;
            if (!SymGetModuleInfo( hProcess, DllList[i].BaseAddress, &ModuleInfo )) {
                if (ThisProcess) {
                    printf( "loading 0x%08x %s\n",
                        DllList[i].BaseAddress,
                        DllList[i].Name
                        );
                    LoadSymbols(
                        ThisProcess,
                        &DllList[i],
                        NULL
                        );
                }
            }
        }
    }

    CurrProcess = hProcess;
    if (InitialCommand) {
        strcpy( CmdBuf, InitialCommand );
    }
    while( TRUE ) {
        if (!InitialCommand) {
            printf( "ApiMon> " );
            scanf( "%[^\n]", CmdBuf );
            getchar();
        }

        LPSTR p = CmdBuf;
        while (p[0]) {

            LPSTR s = p;
            while (*s) {
                if (*s == '\"') {
                    s += 1;
                    while (*s && *s != '\"') {
                        s += 1;
                    }
                    if (*s == '\"') {
                        s += 1;
                    }
                }
                if (*s == ';') {
                    break;
                }
                s += 1;
            }
            if (*s == ';') {
                s[0] = 0;
            } else {
                s = NULL;
            }

            switch( tolower(p[0]) ) {
                case 'q':
                    ExitProcess( 0 );
                    break;

                case 'g':
                    ContinueStatus = DBG_CONTINUE;
                    goto exit;

                case 'k':
                    CmdStackTrace( p, hProcess, hThread, ExceptionRecord );
                    break;

                case 'd':
                    CmdDisplayMemory( p, hProcess, hThread, ExceptionRecord );
                    break;

                case 'r':
                    if (p[1] == 't') {
                        PrintRegistersFlag = !PrintRegistersFlag;
                    }
                    CmdDisplayRegisters( p, hProcess, hThread, ExceptionRecord );
                    break;

                case 'u':
                    CmdDisplayCode( p, hProcess, hThread, ExceptionRecord );
                    break;

                case 'b':
                    CmdBreakPoint( p, hProcess, hThread, ExceptionRecord );
                    break;

                case 'l':
                    if (tolower(p[1]) == 'm') {
                        CmdDisplayModules( p, hProcess, hThread, ExceptionRecord );
                    } else if (tolower(p[1]) == 'n') {
                        CmdListNear( p, hProcess, hThread, ExceptionRecord );
                    } else {
                        goto invalid_command;
                    }
                    break;

                case 't':
                    if (p[1] == 'r') {
                        PrintRegistersFlag = !PrintRegistersFlag;
                    }
                    if (CmdTrace( p, hProcess, hThread, ExceptionRecord )) {
                        ContinueStatus = DBG_CONTINUE;
                        Stepped = TRUE;
                        goto exit;
                    }
                    break;

                case 'p':
                    if (p[1] == 'r') {
                        PrintRegistersFlag = !PrintRegistersFlag;
                    }
                    if (CmdStep( p, hProcess, hThread, ExceptionRecord )) {
                        ContinueStatus = DBG_CONTINUE;
                        Stepped = TRUE;
                        goto exit;
                    }
                    break;

                case 'h':
                    if (tolower(p[1]) == 'e' && tolower(p[2]) == 'l' && tolower(p[3]) == 'p') {
                        CmdDisplayHelp( p, hProcess, hThread, ExceptionRecord );
                    }
                    break;

                case '?':
                    {
                        ULONG val = GetExpression( p+1 );
                        if (!ExprError) {
                            printf( "Evaluate expression: %d = 0x%08x\n", val, val );
                        }
                    }
                    break;

                default:
invalid_command:
                    printf( "****>>> invalid command\n" );
                    break;
            }
            if (s) {
                p = s + 1;
            } else {
                p += strlen(p);
            }
        }
    }

exit:

    return ContinueStatus;
}
Esempio n. 29
0
	//*************************************************************************
	// Method:		GetStackInfo
	// Description: Gets the call stack for the specified thread
	//
	// Parameters:
	//	hThread - the handle to the target thread
	//	threadContext - the context of the target thread
	//
	// Return Value: (FrameInfo *) An array containing stack trace data
	//*************************************************************************
	SiUtils::SiArray <FrameInfo *> StackWalker::GetStackInfo(HANDLE hThread, CONTEXT &threadContext)
	{
		//Clear the frame array of any previous data
		frameArray.Clear();

		DWORD imageType = IMAGE_FILE_MACHINE_I386;
		HANDLE hProcess = GetCurrentProcess();
		
		int frameNum;						// counts walked frames
		DWORD offsetFromSymbol;				// tells us how far from the symbol we were
		DWORD symOptions;					// symbol handler settings
		IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *) malloc( IMGSYMLEN + MAXNAMELEN );
		char undName[MAXNAMELEN];			// undecorated name
		char undFullName[MAXNAMELEN];		// undecorated name with all shenanigans
		IMAGEHLP_MODULE Module;
		IMAGEHLP_LINE Line;
		std::string symSearchPath;
		char *tt = 0, *p;

		STACKFRAME s;						// in/out stackframe
		memset( &s, '\0', sizeof s );

		tt = new char[TTBUFLEN];
		// build symbol search path from:
		symSearchPath = "";
		// current directory
		if (GetCurrentDirectory(TTBUFLEN, tt ))
			symSearchPath += tt + std::string( ";" );
		
		// dir with executable
		if (GetModuleFileName(0, tt, TTBUFLEN))
		{
			for ( p = tt + strlen( tt ) - 1; p >= tt; -- p )
			{
				// locate the rightmost path separator
				if ( *p == '\\' || *p == '/' || *p == ':' )
					break;
			}
			
			if ( p != tt )
			{
				if ( *p == ':' ) // we leave colons in place
					++ p;
				*p = '\0'; // eliminate the exe name and last path sep
				symSearchPath += tt + std::string( ";" );
			}
		}
		
		// environment variable _NT_SYMBOL_PATH
		if ( GetEnvironmentVariable( "_NT_SYMBOL_PATH", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );
		// environment variable _NT_ALTERNATE_SYMBOL_PATH
		if ( GetEnvironmentVariable( "_NT_ALTERNATE_SYMBOL_PATH", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );
		// environment variable SYSTEMROOT
		if ( GetEnvironmentVariable( "SYSTEMROOT", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );

		if ( symSearchPath.size() > 0 ) // if we added anything, we have a trailing semicolon
			symSearchPath = symSearchPath.substr( 0, symSearchPath.size() - 1 );

		strncpy( tt, symSearchPath.c_str(), TTBUFLEN );
		tt[TTBUFLEN - 1] = '\0'; // if strncpy() overruns, it doesn't add the null terminator

		// init symbol handler stuff (SymInitialize())
		if (!SymInitialize(hProcess, tt, false ))
			goto cleanup;

		// SymGetOptions()
		symOptions = SymGetOptions();
		symOptions |= SYMOPT_LOAD_LINES;
		symOptions &= ~SYMOPT_UNDNAME;
		SymSetOptions( symOptions );

		// Enumerate modules and tell imagehlp.dll about them.
		enumAndLoadModuleSymbols( hProcess, GetCurrentProcessId() );

		// init STACKFRAME for first call
		// Notes: AddrModeFlat is just an assumption. I hate VDM debugging.
		// Notes: will have to be #ifdef-ed for Alphas; MIPSes are dead anyway,
		// and good riddance.
		s.AddrPC.Offset = threadContext.Eip;
		s.AddrPC.Mode = AddrModeFlat;
		s.AddrFrame.Offset = threadContext.Ebp;
		s.AddrFrame.Mode = AddrModeFlat;

		memset( pSym, '\0', IMGSYMLEN + MAXNAMELEN );
		pSym->SizeOfStruct = IMGSYMLEN;
		pSym->MaxNameLength = MAXNAMELEN;

		memset( &Line, '\0', sizeof Line );
		Line.SizeOfStruct = sizeof Line;

		memset( &Module, '\0', sizeof Module );
		Module.SizeOfStruct = sizeof Module;

		offsetFromSymbol = 0;

		for ( frameNum = 0; ; ++ frameNum )
		{
			FrameInfo * frameInfo = new FrameInfo();

			if (!StackWalk( imageType, hProcess, hThread, &s, &threadContext, NULL,
				SymFunctionTableAccess, SymGetModuleBase, NULL ) )
				break;

			frameInfo->frameNumber = frameNum;
			frameInfo->IsWOWFarCall = s.Far;
			frameInfo->IsVirtualFrame = s.Virtual;
			frameInfo->Eip = s.AddrPC.Offset;				//if 0, the no symbols
			frameInfo->ReturnAddr = s.AddrReturn.Offset;
			frameInfo->FramePtr = s.AddrFrame.Offset;
			frameInfo->StackPtr = s.AddrStack.Offset;

			if (s.AddrPC.Offset == 0)
			{
				//printf( "(-nosymbols- PC == 0)\n" );
			}
			else
			{ // we seem to have a valid PC
				// show procedure info (SymGetSymFromAddr())
				if ( ! SymGetSymFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, pSym ) )
				{
					/*if ( GetLastError() != 487 )
						printf( "SymGetSymFromAddr(): GetLastError() = %lu\n", GetLastError() );*/
				}
				else
				{
					// UnDecorateSymbolName()
					UnDecorateSymbolName( pSym->Name, undName, MAXNAMELEN, UNDNAME_NAME_ONLY );
					UnDecorateSymbolName( pSym->Name, undFullName, MAXNAMELEN, UNDNAME_COMPLETE );

					strcpy (frameInfo->undecoratedName, undName);
					strcpy (frameInfo->undecoratedFullName, undFullName);
					strcpy (frameInfo->signature, pSym->Name );
					frameInfo->offsetFromSymbol = offsetFromSymbol;
				}

				// show module info (SymGetModuleInfo())
				if (SymGetModuleInfo( hProcess, s.AddrPC.Offset, &Module ) )
				{	
					strcpy (frameInfo->ModuleName, Module.ModuleName);
					strcpy (frameInfo->ImageName, Module.ImageName);
					frameInfo->BaseOfImage = Module.BaseOfImage;

				}

			} // we seem to have a valid PC

			// no return address means no deeper stackframe
			if ( s.AddrReturn.Offset == 0 )
			{
				// avoid misunderstandings in the printf() following the loop
				SetLastError( 0 );
				break;
			}
			
			this->frameArray.Add (frameInfo);

		} // for ( frameNum )

	cleanup:
		// de-init symbol handler etc. (SymCleanup())
		SymCleanup( hProcess );
		free( pSym );
		delete [] tt;
		return frameArray;
	}
Esempio n. 30
0
void write_stack_trace(PCONTEXT pContext, TextOutputStream& outputStream)
{
  HANDLE m_hProcess = GetCurrentProcess();
  DWORD dwMachineType = 0;

  CONTEXT context = *pContext;

  // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
  if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) )
  {
    return;
  }

  STACKFRAME sf;
  memset( &sf, 0, sizeof(sf) );

#ifdef _M_IX86
  // Initialize the STACKFRAME structure for the first call.  This is only
  // necessary for Intel CPUs, and isn't mentioned in the documentation.
  sf.AddrPC.Offset       = context.Eip;
  sf.AddrPC.Mode         = AddrModeFlat;
  sf.AddrStack.Offset    = context.Esp;
  sf.AddrStack.Mode      = AddrModeFlat;
  sf.AddrFrame.Offset    = context.Ebp;
  sf.AddrFrame.Mode      = AddrModeFlat;

  dwMachineType = IMAGE_FILE_MACHINE_I386;
#endif

  while ( 1 )
  {
    // Get the next stack frame
    if ( ! StackWalk(  dwMachineType,
                        m_hProcess,
                        GetCurrentThread(),
                        &sf,
                        &context,
                        0,
                        SymFunctionTableAccess,
                        SymGetModuleBase,
                        0 ) )
        break;

    if ( 0 == sf.AddrFrame.Offset ) // Basic sanity check to make sure
      break;                      // the frame is OK.  Bail if not.

    // Get the name of the function for this stack frame entry
    BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + MAX_SYM_NAME ];
    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_SYM_NAME;
                    
    DWORD64 symDisplacement = 0;    // Displacement of the input address,
                                    // relative to the start of the symbol

    IMAGEHLP_MODULE module = { sizeof(IMAGEHLP_MODULE) };
    if(SymGetModuleInfo(m_hProcess, sf.AddrPC.Offset, &module))
    {
      outputStream << module.ModuleName << "!";

      if ( SymFromAddr(m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
      {
        char undecoratedName[MAX_SYM_NAME];
        UnDecorateSymbolName(pSymbol->Name, undecoratedName, MAX_SYM_NAME, UNDNAME_COMPLETE);

        outputStream << undecoratedName;

        outputStream << "(";
        // Use SymSetContext to get just the locals/params for this frame
        IMAGEHLP_STACK_FRAME imagehlpStackFrame;
        imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
        SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );

        // Enumerate the locals/parameters
        EnumerateSymbolsContext context(sf, outputStream);
        SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context );
        outputStream << ")";

        outputStream << " + " << Offset(reinterpret_cast<void*>(symDisplacement));

        // Get the source line for this stack frame entry
        IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
        DWORD dwLineDisplacement;
        if ( SymGetLineFromAddr( m_hProcess, sf.AddrPC.Offset,
                                &dwLineDisplacement, &lineInfo ) )
        {
          outputStream << " " << lineInfo.FileName << " line " << Unsigned(lineInfo.LineNumber); 
        }
      }
      else
      {
        outputStream << Address(reinterpret_cast<void*>(sf.AddrPC.Offset));
      }
    }

    outputStream << "\n";
  }

  SymCleanup(m_hProcess);

  return;
}