bool CallStack::loadAllModules() { #ifdef WIN32 DWORD dwNeeded = 0; if (!EnumProcessModules(hProcess, hModule, sizeof(hModule), &dwNeeded)) return false; const int iCount = dwNeeded / sizeof(HMODULE); for (int i = 0; i < iCount; ++i) { MODULEINFO info; GetModuleInformation(hProcess, hModule[i], &info, sizeof(info)); GetModuleFileNameEx(hProcess, hModule[i], szImageName, iMax); GetModuleBaseName(hProcess, hModule[i], szModuleName, iMax); #ifdef X64 SymLoadModule64(hProcess, hModule[i], szImageName, szModuleName, (DWORD64)info.lpBaseOfDll, info.SizeOfImage); #else SymLoadModule(hProcess, hModule[i], szImageName, szModuleName, (DWORD)info.lpBaseOfDll, info.SizeOfImage); #endif } #endif return true; }
void LoadModules() { const int MAX_MOD_HANDLES = 1024; HMODULE StaticModuleHandleArray[MAX_MOD_HANDLES]; HMODULE* ModuleHandleArray; DWORD Needed; HANDLE hProcess = GetCurrentProcess(); ModuleHandleArray = &StaticModuleHandleArray[0]; BOOL result = EnumProcessModules(hProcess, ModuleHandleArray, sizeof(ModuleHandleArray), &Needed); if( !result ) { DWORD error = GetLastError(); DebugLog("EnumProcessModule failed: error = %d", error); return; } if( Needed > sizeof(ModuleHandleArray) ) // was our static array not big enough? { ModuleHandleArray = (HMODULE*)DialogAllocator.AllocateBytes(Needed, sizeof(void*)); BOOL result = EnumProcessModules(hProcess, ModuleHandleArray, Needed, &Needed); if( !result ) { DWORD error = GetLastError(); DebugLog("EnumProcessModule(2) failed: error = %d", error); return; } } int NumModules = Needed / sizeof(HMODULE); MODULEINFO ModuleInfo; char ModuleFilePath[MAX_PATH]; char ModuleName[256]; char SearchFilePath[MAX_PATH]; for( int i = 0; i < NumModules; i++ ) { GetModuleInformation(hProcess, ModuleHandleArray[i], &ModuleInfo, sizeof(MODULEINFO)); GetModuleFileNameExA(hProcess, ModuleHandleArray[i], ModuleFilePath, MAX_PATH); GetModuleBaseNameA(hProcess, ModuleHandleArray[i], ModuleName, 256); char* FileName = nullptr; GetFullPathNameA(ModuleFilePath, MAX_PATH, SearchFilePath, &FileName); *FileName = 0; SymSetSearchPath(hApplicationProcess, SearchFilePath); DWORD64 BaseAddress = SymLoadModule64(hApplicationProcess, ModuleHandleArray[i], ModuleFilePath, ModuleName, (DWORD64)ModuleInfo.lpBaseOfDll, (DWORD) ModuleInfo.SizeOfImage); if( !BaseAddress ) { DWORD error = GetLastError(); DebugLog("SymLoadModule64 failed: error = %d", error); } } }
bool CSymbolEngine::LoadModuleSymbols( HANDLE hFile, const TString& ImageName, DWORD64 ModBase, DWORD ModSize ) { // Check preconditions if( m_hProcess == NULL ) { _ASSERTE( !_T("Symbol engine is not yet initialized.") ); m_LastError = ERROR_INVALID_FUNCTION; return false; } // In Unicode build, ImageName parameter should be translated to ANSI #ifdef _UNICODE char* pImageName = 0; if( !ImageName.empty() ) { size_t BufSize = 2 * ImageName.length(); pImageName = (char*)_alloca( BufSize + 2 ); size_t res = wcstombs( pImageName, ImageName.c_str(), BufSize ); pImageName[BufSize] = 0; if( res == -1 ) { _ASSERTE( !_T("Module name has bad format.") ); m_LastError = ERROR_INVALID_PARAMETER; return false; } } #else const char* pImageName = ImageName.empty() ? 0 : ImageName.c_str(); #endif //_UNICODE // Load symbols for the module #pragma TODO("replace SymLoadModule64 with SymLoadModuleEx ") DWORD64 rv = SymLoadModule64( m_hProcess, hFile, pImageName, NULL, ModBase, ModSize ); if( rv == 0 ) { m_LastError = GetLastError(); _ASSERTE( !_T("SymLoadModule64() failed.") ); return false; } // Complete return true; }
void Pdb::LoadModuleInfo() { fninfo_cache.Clear(); ModuleInfo f; dword cb = 1; HMODULE h; if(!EnumProcessModules(hProcess, &h, sizeof(HMODULE), &cb)) { Error(); return; } int n = cb / sizeof(HMODULE); Buffer<HMODULE> m(n); if(!EnumProcessModules(hProcess, m, cb, &cb)) { Error(); return; } Vector<ModuleInfo> nm; for (int i = 0; i < n; i++) { MODULEINFO mi; if(GetModuleInformation(hProcess, m[i], &mi, sizeof(mi))) { ModuleInfo& f = nm.Add(); f.base = (adr_t)mi.lpBaseOfDll; f.size = mi.SizeOfImage; int q = FindModuleIndex(f.base); if(q >= 0) { ModuleInfo& of = module[q]; f.path = of.path; f.symbols = of.symbols; of.symbols = false; LLOG("Stable " << Hex(f.base) << " (" << Hex(f.size) << "): " << f.path); } else { char name[MAX_PATH]; if(GetModuleFileNameEx(hProcess, m[i], name, MAX_PATH)) { f.path = name; if(FileExists(ForceExt(f.path, ".pdb"))) { adr_t w = (adr_t)SymLoadModule64(hProcess, NULL, name, 0, f.base, f.size); if(w) { LLOG("Loading symbols " << Hex(f.base) << '/' << hProcess << " returned base " << Hex(w)); f.symbols = true; LoadGlobals(w); } } } LLOG(Hex(f.base) << " (" << Hex(f.size) << "): " << f.path); } } } UnloadModuleSymbols(); module = pick(nm); refreshmodules = false; }
/** * Module enumeration callback function. * * @returns VBox status. * Failure will stop the search and return the return code. * Warnings will be ignored and not returned. * @param pVM VM Handle. * @param pszFilename Module filename. * @param pszName Module name. (short and unique) * @param ImageBase Address where to executable image is loaded. * @param cbImage Size of the executable image. * @param fRC Set if guest context, clear if host context. * @param pvArg User argument. */ static DECLCALLBACK(int) dbgfR3EnumModules(PVM pVM, const char *pszFilename, const char *pszName, RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg) { DWORD64 LoadedImageBase = SymLoadModule64(pVM, NULL, (char *)(void *)pszFilename, (char *)(void *)pszName, ImageBase, (DWORD)cbImage); if (!LoadedImageBase) Log(("SymLoadModule64(,,%s,,) -> lasterr=%d\n", pszFilename, GetLastError())); else Log(("Loaded debuginfo for %s - %s %llx\n", pszName, pszFilename, LoadedImageBase)); return VINF_SUCCESS; }
/** * Interface used by PDMR3LdrRelocate for telling us that a GC module has been relocated. * * @param pVM The VM handle. * @param OldImageBase The old image base. * @param NewImageBase The new image base. * @param cbImage The image size. * @param pszFilename The image filename. * @param pszName The module name. */ VMMR3DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage, const char *pszFilename, const char *pszName) { #ifdef HAVE_DBGHELP if (pVM->dbgf.s.fSymInited) { if (!SymUnloadModule64(pVM, OldImageBase)) Log(("SymUnloadModule64(,%RGv) failed, lasterr=%d\n", OldImageBase, GetLastError())); DWORD ImageSize = (DWORD)cbImage; Assert(ImageSize == cbImage); DWORD64 LoadedImageBase = SymLoadModule64(pVM, NULL, (char *)(void *)pszFilename, (char *)(void *)pszName, NewImageBase, ImageSize); if (!LoadedImageBase) Log(("SymLoadModule64(,,%s,,) -> lasterr=%d (relocate)\n", pszFilename, GetLastError())); else Log(("Reloaded debuginfo for %s - %s %llx\n", pszName, pszFilename, LoadedImageBase)); } #else #endif }
HMODULE LoadModuleWithSymbolsFullPath( _In_ PSTR pszFullModuleFileName) { HMODULE hmod; DWORD64 dwModuleBase; /* Load the DLL */ hmod = LoadLibraryExA(pszFullModuleFileName, NULL, LOAD_IGNORE_CODE_AUTHZ_LEVEL | DONT_RESOLVE_DLL_REFERENCES | LOAD_WITH_ALTERED_SEARCH_PATH); if (hmod == NULL) { return NULL; } /* Load symbols for this module */ dwModuleBase = SymLoadModule64(ghProcess, NULL, pszFullModuleFileName, NULL, (DWORD_PTR)hmod, 0); if (dwModuleBase == 0) { /* ERROR_SUCCESS means, we have symbols already */ if (GetLastError() != ERROR_SUCCESS) { return NULL; } } else { printf("Successfully loaded symbols for '%s'\n", pszFullModuleFileName); } return hmod; }
void enumAndLoadModuleSymbols( HANDLE hProcess, DWORD pid ) { ModuleList modules; ModuleListIter it; char *img, *mod; // fill in module list fillModuleList( modules, pid, hProcess ); for ( it = modules.begin(); it != modules.end(); ++ it ) { // unfortunately, SymLoadModule() wants writeable strings img = new char[(*it).imageName.size() + 1]; strcpy( img, (*it).imageName.c_str() ); mod = new char[(*it).moduleName.size() + 1]; strcpy( mod, (*it).moduleName.c_str() ); SymLoadModule64( hProcess, 0, img, mod, (*it).baseAddress, (*it).size ); delete [] img; delete [] mod; } }
SEA_EXPORT const char* resolve_pointer(const char* szModulePath, uint64_t addr) { static std::string res; res.clear(); static HANDLE hCurProc = GetCurrentProcess(); DWORD dwOptions = SymSetOptions((SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS) & ~SYMOPT_DEFERRED_LOADS); static BOOL bInitialize = SymInitialize(hCurProc, NULL, TRUE); if (!bInitialize) return nullptr; static std::map<std::string, uint64_t> modules; uint64_t module = 0; if (modules.count(szModulePath)) { module = modules[szModulePath]; } else { module = SymLoadModule64(hCurProc, NULL, szModulePath, NULL, 0x800000, 0); modules[szModulePath] = module; } if (!module) return nullptr; IMAGEHLP_LINE64 line = { sizeof(IMAGEHLP_LINE64) }; DWORD dwDisplacement = 0; SymGetLineFromAddr64(hCurProc, module + addr, &dwDisplacement, &line); if (line.FileName) { res += std::string(line.FileName) + "(" + std::to_string(line.LineNumber) + ")\n"; } char buff[sizeof(SYMBOL_INFO) + 1024] = {}; SYMBOL_INFO * symbol = (SYMBOL_INFO*)buff; symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); SymFromAddr(hCurProc, module + addr, nullptr, symbol); res += symbol->Name; return res.c_str(); }
int main(int argc, char* argv[]) { if (argc != 2) { printf("\n *** OffsetToSource by Sasha Goldshtein (blog.sashag.net), (C) 2013 ***\n\n"); printf(" Usage: OffsetToSource module[.exe|.dll][!function]+0x<offset>\n\n"); printf(" Example: OffsetToSource myapp!main+0xd0\n"); printf(" Example: OffsetToSource myapp+0x441d0\n"); return 2; } const HANDLE hProcess = GetCurrentProcess(); SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES); if (FALSE == SymInitialize(hProcess, NULL, FALSE)) { printf("*** Error initializing symbol engine: 0x%x\n", GetLastError()); return 1; } CHAR symbolPath[2048], path[2048]; GetEnvironmentVariableA("PATH", path, ARRAYSIZE(symbolPath)); GetEnvironmentVariableA("_NT_SYMBOL_PATH", symbolPath, ARRAYSIZE(symbolPath)); strcat_s(path, ";.;"); strcat_s(path, symbolPath); SymSetSearchPath(hProcess, path); //Parse argv[1] to obtain the module name, symbol name, and offset // Example format: module!Class::Method+0x40 // Another option: module+0x1000 BOOL symbolNameSpecified; CHAR moduleName[200], symName[200]; DWORD offset = 0; CHAR* bang = strchr(argv[1], '!'); if (bang != NULL) { strncpy_s(moduleName, argv[1], bang - argv[1]); CHAR* plus = strchr(bang, '+'); if (plus != NULL) { strncpy_s(symName, bang + 1, plus - bang - 1); sscanf_s(plus + 1, "0x%x", &offset); } else { strcpy_s(symName, bang + 1); } symbolNameSpecified = TRUE; } else { CHAR* plus = strchr(argv[1], '+'); if (plus == NULL) { printf("*** Invalid input: %s\n", argv[1]); return 1; } strncpy_s(moduleName, argv[1], plus - argv[1]); sscanf_s(plus + 1, "0x%x", &offset); symbolNameSpecified = FALSE; } BOOL nakedName = strstr(moduleName, ".dll") == NULL && strstr(moduleName, ".exe") == NULL; if (nakedName) { strcat_s(moduleName, ".dll"); } DWORD64 moduleBase; while (0 == (moduleBase = SymLoadModule64(hProcess, NULL, moduleName, NULL, 0, 0))) { if (nakedName) { strcpy(strstr(moduleName, ".dll"), ".exe"); nakedName = FALSE; continue; } printf("*** Error loading symbols: 0x%x\n", GetLastError()); return 1; } DWORD64 symbolAddress; if (symbolNameSpecified) { ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; if (FALSE == SymFromName(hProcess, symName, pSymbol)) { printf("*** Error retrieving symbol information for symbol %s: 0x%x\n", argv[1], GetLastError()); return 1; } symbolAddress = pSymbol->Address + offset; } else { symbolAddress = moduleBase + offset; } DWORD displacement; IMAGEHLP_LINE64 line; RtlZeroMemory(&line, sizeof(line)); line.SizeOfStruct = sizeof(line); if (FALSE == SymGetLineFromAddr64(hProcess, symbolAddress, &displacement, &line)) { printf("*** Error retrieving source line for %s: 0x%x\n", argv[1], GetLastError()); return 1; } printf("%s [0x%I64x] = %s line %d (+0x%x)\n", argv[1], symbolAddress, line.FileName, line.LineNumber, displacement); SymCleanup(hProcess); return 0; }
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* ptrs) { EXCEPTION_RECORD* rec = ptrs->ExceptionRecord; CONTEXT* ctx = ptrs->ContextRecord; DWORD base = Vars.pModule ? Vars.pModule->dwBaseAddress : (DWORD)Vars.hModule; char path[MAX_PATH+_MAX_FNAME] = ""; sprintf_s(path, sizeof(path), "%s\\D2BS.bin", Vars.szPath); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId()); HANDLE hThread = GetCurrentThread(); CONTEXT context = *ctx; SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_FAIL_CRITICAL_ERRORS|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS); SymInitialize(hProcess, Vars.szPath, TRUE); SymLoadModule64(hProcess, NULL, path, NULL, base, 0); STACKFRAME64 stack; stack.AddrPC.Offset = context.Eip; stack.AddrPC.Mode = AddrModeFlat; stack.AddrStack.Offset = context.Esp; stack.AddrStack.Mode = AddrModeFlat; stack.AddrFrame.Offset = context.Ebp; stack.AddrFrame.Mode = AddrModeFlat; std::string trace; for(int i = 0; i < 64; i++) { if(!StackWalk64(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &stack, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; // infinite loop if(stack.AddrReturn.Offset == stack.AddrPC.Offset) break; // jump to 0 if(stack.AddrPC.Offset == 0) break; SYMBOL_INFO* sym = GetSymFromAddr(hProcess, stack.AddrPC.Offset); if(sym) { char msg[1024]; ULONG64 base = (sym->Address - sym->ModBase); IMAGEHLP_LINE64* line = GetLineFromAddr(hProcess, stack.AddrPC.Offset); if(line) sprintf_s(msg, 1024, "\t%s+0x%08x, File: %s line %d\n", sym->Name, base, strrchr(line->FileName, '\\')+1, line->LineNumber); else sprintf_s(msg, 1024, "\t%s+0x%08x\n", sym->Name, base); trace.append(msg); delete line; } else { char addr[100]; sprintf_s(addr, sizeof(addr), "\t0x%08x\n", stack.AddrFrame.Offset); trace.append(addr); } delete[] (char*)sym; } SYMBOL_INFO* sym = GetSymFromAddr(hProcess, (DWORD64)rec->ExceptionAddress); IMAGEHLP_LINE64* line = GetLineFromAddr(hProcess, (DWORD64)rec->ExceptionAddress); Log("EXCEPTION!\n*** 0x%08x at 0x%08x (%s in %s line %d)\n" "D2BS loaded at: 0x%08x\n" "Registers:\n" "\tEIP: 0x%08x, ESP: 0x%08x\n" "\tCS: 0x%04x, DS: 0x%04x, ES: 0x%04x, SS: 0x%04x, FS: 0x%04x, GS: 0x%04x\n" "\tEAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x, ESI: 0x%08x, EDI: 0x%08x, EBP: 0x%08x, FLG: 0x%08x\n" "Stack Trace:\n%s\nEnd of stack trace.", rec->ExceptionCode, rec->ExceptionAddress, sym != NULL ? sym->Name : "Unknown", line != NULL ? strrchr(line->FileName, '\\')+1 : "Unknown", line != NULL ? line->LineNumber : 0, base, ctx->Eip, ctx->Esp, ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegSs, ctx->SegFs, ctx->SegGs, ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi, ctx->Ebp, ctx->EFlags, trace.c_str()); delete[] (char*)sym; delete line; SymCleanup(hProcess); return EXCEPTION_EXECUTE_HANDLER; }
bool CATDbgHelper::Open( const string& sParameter, const unsigned long iLong ) { LOG_FUNC_ENTRY("CATDbgHelper::Open"); // Verify that file exits. Version 5.1.2600.5512 of dbghelp.dll does not correctly // return error code if missing image file. This can lead upto applicaton crash. if ( ! CATBase::FileExists( sParameter.c_str() ) ) { LOG_STRING( "Missing image file: " << sParameter ); return false; } // Is it urel try read map? if ( sParameter.find( "\\urel\\" ) != string::npos ) { string sMapFile = sParameter; sMapFile.append( ".map" ); ReadMapFile( sMapFile ); } // Set base address used m_BaseAddress = iLong + AT_VIRTUAL_OFFSET_DBGHELPER; // Binary file (also referred as symbol). size_t length = sParameter.length(); if ( length == 0 ) { LOG_STRING("DbgHelp:Invalid binary parameter."); return false; } char* pChar = new char[ sParameter.length()+1 ]; strcpy( pChar, sParameter.c_str() ); // Have to be casted to PSTR before using dbg api. Even tho its typedef same. // This will avoid access violations bug. // Note pChar is not deleted because its the member pointer just casted its // memory allocation freed in destructor. if ( m_pBinaryFile ) delete[] m_pBinaryFile; m_pBinaryFile = (PSTR) pChar; // Initialize dbghelper if not done only once. if ( ! CDBGHELPER_OPEN ) { // Set symbol options SymSetOptions( SYMOPT_LOAD_LINES | SYMOPT_DEBUG | SYMOPT_UNDNAME | SYMOPT_LOAD_ANYTHING ); if ( !SymInitialize( GetCurrentProcess(), NULL, TRUE ) ) { LOG_STRING("DbgHelp:Error initializing dbghelper " << (int) GetLastError()); return false; } LOG_STRING("DbgHelp:dbghelper opened."); CDBGHELPER_OPEN = true; } // Set symbol search path. if ( !SymSetSearchPath( GetCurrentProcess(), NULL ) ) { LOG_STRING("DbgHelp:Error setting symbol search path " << (int) GetLastError()); return false; } // Load module. DWORD64 ret; ret = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); // 5.1 api version. if ( ret != m_BaseAddress && ret != 0) { LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError()); return false; } CDBGHELPER_CLIENTS++; return true; }
bool CATDbgHelper::AddressToLine( CATMemoryAddress* result ) { LOG_FUNC_ENTRY("CATDbgHelper::AddressToLine"); // Set state out of range result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE ); // check that dbghelper has been initialized successfully. if ( ! CDBGHELPER_OPEN ) return false; // Check has binary been moved, if so unload and load to new base address. if ( result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER != m_BaseAddress ) { // Unload. if ( SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) ) { // Set new base address. m_BaseAddress = result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER; // (Re)load. DWORD64 loading = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); if ( loading != m_BaseAddress && loading != 0) { LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError()); return false; } } else LOG_STRING("Dbghelp:Module unload failed " << (int) GetLastError() ); } // Address to find (offset+given address). unsigned long iAddressToFind = result->GetAddress() + AT_VIRTUAL_OFFSET_DBGHELPER; // Displacements of line/symbol information. DWORD64 displacementSymbol; DWORD displacementLine; // Structure to get symbol information. CSymbolInfo symbol; // Structure to get line information. CLineInfo line; // Find Symbol for given address if( ! SymFromAddr( GetCurrentProcess(), iAddressToFind , &displacementSymbol, &symbol.si ) ) { LOG_STRING("Failed to find symbol information for given line."); return AddressToFunction( result ); } // Find line information if( ! SymGetLineFromAddr64( GetCurrentProcess(), iAddressToFind, &displacementLine, &line ) ) { // If it fails get symbol line information LOG_STRING("Dbghelp:Failed to find line information for address, trying for symbol of address."); if( ! SymGetLineFromAddr64( GetCurrentProcess(), symbol.si.Address, &displacementLine, &line ) ) { LOG_STRING("Dbghelp:Failed to find line information for symbol address."); return AddressToFunction( result ); } } // Set the results. result->SetFileName( string( line.FileName ) ); result->SetFunctionName( string( symbol.si.Name ) ); result->SetExactLineNumber( (int) line.LineNumber ); result->SetAddressToLineState( CATMemoryAddress::EXACT ); // Return. return true; }
ULONG getSymbols() { CString FilePathName; PCSTR path; DWORD error; DWORD64 dw64Base; DWORD dwFileSize; g_CountOfFunFound = 0; dw64Base = getNtBase(); if (dw64Base==0) { ::MessageBox(NULL,"Get base 0",NULL,NULL); return 0 ; } char szSystemDir[1024]={0}; GetSystemDirectory(szSystemDir, sizeof(szSystemDir)); FilePathName = szSystemDir; FilePathName = FilePathName+"\\"+PathFindFileName(osname); path=FilePathName; //记得要带上symsrv.dll和dbghelp.dll char *pSymPath = "srv*C:\\winddk\\symbolsl*http://msdl.microsoft.com/download/symbols"; myprint("retriving symbols for %s,symbols store in %s\r\n",path, pSymPath); SymCleanup(GetCurrentProcess()); if (SymInitialize(GetCurrentProcess(), pSymPath, TRUE)) { // SymInitialize returned success } else { // SymInitialize failed error = GetLastError(); myprint("SymInitialize returned error : %d\n", error); return 0; } DWORD err=0; // get the file size HANDLE hFile = CreateFile( FilePathName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if( INVALID_HANDLE_VALUE == hFile ) { err = GetLastError(); ::MessageBox(NULL,"out",NULL,NULL); return false; } if( INVALID_FILE_SIZE == ( dwFileSize = GetFileSize(hFile, NULL)) ) { } CloseHandle(hFile); DWORD64 dw64ModAddress=SymLoadModule64( GetCurrentProcess(),NULL, (char*)path,NULL,dw64Base,dwFileSize); if(dw64ModAddress==0) { error = GetLastError(); myprint("SymLoadModule64 returned error : %d\n", error); return 0; } if(!SymEnumSymbols( GetCurrentProcess(), dw64ModAddress, NULL, // Null point out that list all symbols SymEnumSymbolsProc, NULL)) { //_tprintf( _T("Failed when SymEnumSymbols(): %d \n"), GetLastError() ); return 0; } myprint("g_CountOfFunFound %d\r\n", g_CountOfFunFound); bool bRetSym = (g_CountOfFunFound>sizeof(dync_funs)/sizeof(dync_funs[0])); return bRetSym?dw64Base:0; }
/** * Load debug info, optionally related to a specific module. * * @returns VBox status. * @param pVM VM Handle. * @param pszFilename Path to the file containing the symbol information. * This can be the executable image, a flat symbol file of some kind or stripped debug info. * @param AddressDelta The value to add to the loaded symbols. * @param pszName Short hand name for the module. If not related to a module specify NULL. * @param ModuleAddress Address which the image is loaded at. This will be used to reference the module other places in the api. * Ignored when pszName is NULL. * @param cbImage Size of the image. * Ignored when pszName is NULL. */ VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage) { /* * Lazy init. */ if (!pVM->dbgf.s.fSymInited) { int rc = dbgfR3SymLazyInit(pVM); if (RT_FAILURE(rc)) return rc; } /* * Open the load file. */ FILE *pFile = NULL; char szFoundFile[RTPATH_MAX]; int rc = dbgfR3ModuleLocateAndOpen(pVM, pszFilename, szFoundFile, sizeof(szFoundFile), &pFile); if (pFile) { /* * Probe the file type. */ SYMFILETYPE enmType = dbgfR3ModuleProbe(pFile); if (enmType != SYMFILETYPE_UNKNOWN) { /* * Add the module. */ if (pszName) { #ifdef HAVE_DBGHELP /** @todo arg! checkout the inserting of modules and then loading them again.... Or just the module representation.... */ DWORD64 ImageBase = SymLoadModule64(pVM, NULL, (char *)(void *)szFoundFile, (char *)(void *)pszName, ModuleAddress, cbImage); if (!ImageBase) ImageBase = SymLoadModule64(pVM, NULL, (char *)(void *)pszName, (char *)(void *)pszName, ModuleAddress, cbImage); if (ImageBase) { AssertMsg(ModuleAddress == 0 || ModuleAddress == ImageBase, ("ModuleAddres=%RGv ImageBase=%llx\n", ModuleAddress, ImageBase)); ModuleAddress = ImageBase; } else rc = win32Error(pVM); #else rc = VERR_NOT_IMPLEMENTED; #endif } if (RT_SUCCESS(rc)) { /* * Seek to the start of the file. */ rc = fseek(pFile, 0, SEEK_SET); Assert(!rc); /* * Process the specific. */ switch (enmType) { case SYMFILETYPE_LINUX_SYSTEM_MAP: rc = dbgfR3LoadLinuxSystemMap(pVM, pFile, ModuleAddress, AddressDelta); break; case SYMFILETYPE_PDB: case SYMFILETYPE_DBG: case SYMFILETYPE_MZ: #ifdef HAVE_DBGHELP /* done it all above! */ break; #endif case SYMFILETYPE_LD_MAP: case SYMFILETYPE_MS_MAP: case SYMFILETYPE_OBJDUMP: case SYMFILETYPE_ELF: rc = VERR_NOT_SUPPORTED; break; default: AssertFailed(); rc = VERR_INTERNAL_ERROR; break; } /* file switch. */ } /* module added successfully. */ } /* format identified */ else rc = VERR_NOT_SUPPORTED; /** @todo check for read errors */ fclose(pFile); } return rc; }