BOOL InitDbgHelp( VOID) { static const char *pszMsSymbolServer = "srv**symbols*http://msdl.microsoft.com/download/symbols"; DWORD Options; /* Save current process ;-) */ ghProcess = GetCurrentProcess(); /* Initialize dbghelp */ if (!SymInitialize(ghProcess, 0, FALSE)) { error("SymInitialize() failed."); return FALSE; } /* Set options */ Options = SymGetOptions(); Options |= SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_DEBUG;// | SYMOPT_NO_PROMPTS; Options &= ~SYMOPT_DEFERRED_LOADS; SymSetOptions(Options); /* Test if we can reach the MS symbol server */ if (!SymSrvIsStore(ghProcess, pszMsSymbolServer)) { error("Failed to connect to symbol server."); return FALSE; } /* Set MS symbol server as symbol search path */ SymSetSearchPath(ghProcess, pszMsSymbolServer); return TRUE; }
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; }
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); } } }
void SymEngine::Close() { if (isInitialized) { SymCleanup(hProcess); isInitialized = false; } if (needRestorePreviousSettings) { HANDLE currentProcess = GetCurrentProcess(); SymSetOptions(previousOptions); SymSetSearchPath(currentProcess, previousSearchPath); SymInitialize(currentProcess, NULL, TRUE); needRestorePreviousSettings = false; } }
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; }
int main(int argc, char *argv[]) { DWORD error; HANDLE process; ULONG64 module_base; int i; char* search; char buf[256]; /* Enough to hold one hex address, I trust! */ int rv = 0; /* We may add SYMOPT_UNDNAME if --demangle is specified: */ DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES; char* filename = "a.out"; /* The default if -e isn't specified */ int print_function_name = 0; /* Set to 1 if -f is specified */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--functions") == 0 || strcmp(argv[i], "-f") == 0) { print_function_name = 1; } else if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) { symopts |= SYMOPT_UNDNAME; } else if (strcmp(argv[i], "-e") == 0) { if (i + 1 >= argc) { fprintf(stderr, "FATAL ERROR: -e must be followed by a filename\n"); return 1; } filename = argv[i+1]; i++; /* to skip over filename too */ } else if (strcmp(argv[i], "--help") == 0) { usage(); exit(0); } else { usage(); exit(1); } } process = GetCurrentProcess(); if (!SymInitialize(process, NULL, FALSE)) { error = GetLastError(); fprintf(stderr, "SymInitialize returned error : %d\n", error); return 1; } search = malloc(SEARCH_CAP); if (SymGetSearchPath(process, search, SEARCH_CAP)) { if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) { fprintf(stderr, "Search path too long\n"); SymCleanup(process); return 1; } strcat(search, ";" WEBSYM); } else { error = GetLastError(); fprintf(stderr, "SymGetSearchPath returned error : %d\n", error); rv = 1; /* An error, but not a fatal one */ strcpy(search, WEBSYM); /* Use a default value */ } if (!SymSetSearchPath(process, search)) { error = GetLastError(); fprintf(stderr, "SymSetSearchPath returned error : %d\n", error); rv = 1; /* An error, but not a fatal one */ } SymSetOptions(symopts); module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0); if (!module_base) { /* SymLoadModuleEx failed */ error = GetLastError(); fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n", error, filename); SymCleanup(process); return 1; } buf[sizeof(buf)-1] = '\0'; /* Just to be safe */ while (fgets(buf, sizeof(buf)-1, stdin)) { /* GNU addr2line seems to just do a strtol and ignore any * weird characters it gets, so we will too. */ unsigned __int64 addr = _strtoui64(buf, NULL, 16); ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; IMAGEHLP_LINE64 line; DWORD dummy; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; if (print_function_name) { if (SymFromAddr(process, (DWORD64)addr, NULL, pSymbol)) { printf("%s\n", pSymbol->Name); } else { printf("??\n"); } } line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); if (SymGetLineFromAddr64(process, (DWORD64)addr, &dummy, &line)) { printf("%s:%d\n", line.FileName, (int)line.LineNumber); } else { printf("??:0\n"); } } SymUnloadModule64(process, module_base); SymCleanup(process); return rv; }
/** * Loads modules for current process. */ static void LoadProcessModules(const FString &RemoteStorage) { int32 ErrorCode = 0; HANDLE ProcessHandle = GetCurrentProcess(); // Enumerate process modules. HMODULE* ModuleHandlePointer = GetProcessModules(ProcessHandle); if (!ModuleHandlePointer) { ErrorCode = GetLastError(); return; } // Load the modules. for( int32 ModuleIndex = 0; ModuleHandlePointer[ModuleIndex]; ModuleIndex++ ) { MODULEINFO ModuleInfo = {0}; #if WINVER > 0x502 WCHAR ModuleName[FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = {0}; WCHAR ImageName[FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = {0}; #else ANSICHAR ModuleName[FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = { 0 }; ANSICHAR ImageName[FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = { 0 }; #endif #if PLATFORM_64BITS static_assert(sizeof( MODULEINFO ) == 24, "Broken alignment for 64bit Windows include."); #else static_assert(sizeof( MODULEINFO ) == 12, "Broken alignment for 32bit Windows include."); #endif FGetModuleInformation( ProcessHandle, ModuleHandlePointer[ModuleIndex], &ModuleInfo, sizeof( ModuleInfo ) ); FGetModuleFileNameEx( ProcessHandle, ModuleHandlePointer[ModuleIndex], ImageName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); FGetModuleBaseName( ProcessHandle, ModuleHandlePointer[ModuleIndex], ModuleName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); // Set the search path to find PDBs in the same folder as the DLL. #if WINVER > 0x502 WCHAR SearchPath[MAX_PATH] = {0}; WCHAR* FileName = NULL; const auto Result = GetFullPathNameW( ImageName, MAX_PATH, SearchPath, &FileName ); #else ANSICHAR SearchPath[MAX_PATH] = { 0 }; ANSICHAR* FileName = NULL; const auto Result = GetFullPathNameA( ImageName, MAX_PATH, SearchPath, &FileName ); #endif FString SearchPathList; if (Result != 0 && Result < MAX_PATH) { *FileName = 0; #if WINVER > 0x502 SearchPathList = SearchPath; #else SearchPathList = ANSI_TO_TCHAR(SearchPath); #endif } if (!RemoteStorage.IsEmpty()) { if (!SearchPathList.IsEmpty()) { SearchPathList.AppendChar(';'); } SearchPathList.Append(RemoteStorage); } #if WINVER > 0x502 SymSetSearchPathW(ProcessHandle, *SearchPathList); // Load module. const DWORD64 BaseAddress = SymLoadModuleExW( ProcessHandle, ModuleHandlePointer[ModuleIndex], ImageName, ModuleName, (DWORD64) ModuleInfo.lpBaseOfDll, (uint32) ModuleInfo.SizeOfImage, NULL, 0 ); if( !BaseAddress ) { ErrorCode = GetLastError(); UE_LOG(LogWindows, Warning, TEXT("SymLoadModuleExW. Error: %d"), GetLastError()); } #else SymSetSearchPath(ProcessHandle, TCHAR_TO_ANSI(*SearchPathList)); // Load module. const DWORD64 BaseAddress = SymLoadModuleEx( ProcessHandle, ModuleHandlePointer[ModuleIndex], ImageName, ModuleName, (DWORD64)ModuleInfo.lpBaseOfDll, (uint32)ModuleInfo.SizeOfImage, NULL, 0 ); if (!BaseAddress) { ErrorCode = GetLastError(); UE_LOG(LogWindows, Warning, TEXT("SymLoadModuleEx. Error: %d"), GetLastError()); } #endif } // Free the module handle pointer allocated in case the static array was insufficient. FMemory::Free(ModuleHandlePointer); }
int main(int argc, char *argv[]) { DWORD error; HANDLE process; ULONG64 module_base; SYM_CONTEXT ctx; int i; char* search; char* filename = NULL; int rv = 0; /* We may add SYMOPT_UNDNAME if --demangle is specified: */ DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) { symopts |= SYMOPT_UNDNAME; } else if (strcmp(argv[i], "--help") == 0) { usage(); exit(0); } else { break; } } if (i != argc - 1) { usage(); exit(1); } filename = argv[i]; process = GetCurrentProcess(); if (!SymInitialize(process, NULL, FALSE)) { error = GetLastError(); fprintf(stderr, "SymInitialize returned error : %d\n", error); return 1; } search = malloc(SEARCH_CAP); if (SymGetSearchPath(process, search, SEARCH_CAP)) { if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) { fprintf(stderr, "Search path too long\n"); SymCleanup(process); return 1; } strcat(search, ";" WEBSYM); } else { error = GetLastError(); fprintf(stderr, "SymGetSearchPath returned error : %d\n", error); rv = 1; /* An error, but not a fatal one */ strcpy(search, WEBSYM); /* Use a default value */ } if (!SymSetSearchPath(process, search)) { error = GetLastError(); fprintf(stderr, "SymSetSearchPath returned error : %d\n", error); rv = 1; /* An error, but not a fatal one */ } SymSetOptions(symopts); module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0); if (!module_base) { /* SymLoadModuleEx failed */ error = GetLastError(); fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n", error, filename); SymCleanup(process); return 1; } ShowSymbolInfo(process, module_base); memset(&ctx, 0, sizeof(ctx)); ctx.module_base = module_base; if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) { error = GetLastError(); fprintf(stderr, "SymEnumSymbols returned error: %d\n", error); rv = 1; } else { DWORD j; qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp); for (j = 0; j < ctx.syms_len; j++) { printf("%016I64x X %s\n", ctx.syms[j].addr, ctx.syms[j].name); } /* In a perfect world, maybe we'd clean up ctx's memory? */ } SymUnloadModule64(process, module_base); SymCleanup(process); return rv; }
int main(int argc, char* argv[]) { // Tell dbghelp to print diagnostics to the debugger output. SymSetOptions(SYMOPT_DEBUG); // Initialize dbghelp const HANDLE fakeProcess = (HANDLE)1; BOOL result = SymInitialize(fakeProcess, NULL, FALSE); #ifdef TESTING // Set a search path and cache directory. If this isn't set // then _NT_SYMBOL_PATH will be used instead. // Force setting it here to make sure that the test succeeds. SymSetSearchPath(fakeProcess, "SRV*c:\\symbolstest*http://msdl.microsoft.com/download/symbols"); // Valid PDB data to test the code. std::string gTextArg = "072FF0EB54D24DFAAE9D13885486EE09"; const char* ageText = "2"; const char* fileName = "kernel32.pdb"; // Valid PE data to test the code fileName = "crypt32.dll"; const char* dateStampText = "4802A0D7"; const char* sizeText = "95000"; //fileName = "chrome_child.dll"; //const char* dateStampText = "5420D824"; //const char* sizeText = "20a6000"; #else if (argc < 4) { printf("Error: insufficient arguments.\n"); printf("Usage: %s guid age pdbname\n", argv[0]); printf("Usage: %s dateStamp size pename\n", argv[0]); printf("Example: %s 6720c31f4ac24f3ab0243e0641a4412f 1 " "chrome_child.dll.pdb\n", argv[0]); printf("Example: %s 4802A0D7 95000 crypt32.dll\n", argv[0]); return 0; } std::string gTextArg = argv[1]; const char* dateStampText = argv[1]; const char* ageText = argv[2]; const char* sizeText = argv[2]; const char* fileName = argv[3]; #endif // Parse the GUID and age from the text GUID g = {}; DWORD age = 0; DWORD dateStamp = 0; DWORD size = 0; // Settings for SymFindFileInPath void* id = nullptr; DWORD flags = 0; DWORD two = 0; const char* ext = strrchr(fileName, '.'); if (!ext) { printf("No extension found on %s. Fatal error.\n", fileName); return 0; } if (_stricmp(ext, ".pdb") == 0) { std::string gText; // Scan the GUID argument and remove all non-hex characters. This allows // passing GUIDs with '-', '{', and '}' characters. for (auto c : gTextArg) { if (isxdigit(c)) { gText.push_back(c); } } printf("Parsing symbol data for a PDB file.\n"); if (gText.size() != 32) { printf("Error: GUIDs must be exactly 32 characters" " (%s was stripped to %s).\n", gTextArg.c_str(), gText.c_str()); return 10; } int count = sscanf_s(gText.substr(0, 8).c_str(), "%x", &g.Data1); DWORD temp; count += sscanf_s(gText.substr(8, 4).c_str(), "%x", &temp); g.Data2 = (unsigned short)temp; count += sscanf_s(gText.substr(12, 4).c_str(), "%x", &temp); g.Data3 = (unsigned short)temp; for (auto i = 0; i < ARRAYSIZE(g.Data4); ++i) { count += sscanf_s(gText.substr(16 + i * 2, 2).c_str(), "%x", &temp); g.Data4[i] = (unsigned char)temp; } count += sscanf_s(ageText, "%x", &age); if (count != 12) { printf("Error: couldn't parse the GUID/age string. Sorry.\n"); return 10; } flags = SSRVOPT_GUIDPTR; id = &g; two = age; printf("Looking for %s %s %s.\n", gText.c_str(), ageText, fileName); } else { printf("Parsing symbol data for a PE (.dll or .exe) file.\n"); if (strlen(dateStampText) != 8) printf("Warning!!! The datestamp (%s) is not eight characters long. " "This is usually wrong.\n", dateStampText); int count = sscanf_s(dateStampText, "%x", &dateStamp); count += sscanf_s(sizeText, "%x", &size); flags = SSRVOPT_DWORDPTR; id = &dateStamp; two = size; printf("Looking for %s %x %x.\n", fileName, dateStamp, two); } char filePath[MAX_PATH] = {}; DWORD three = 0; if (SymFindFileInPath(fakeProcess, NULL, fileName, id, two, three, flags, filePath, NULL, NULL)) { printf("Found symbol file - placed it in %s.\n", filePath); } else { printf("Error: symbols not found - error %u. Are dbghelp.dll and " "symsrv.dll in the same directory as this executable?\n", GetLastError()); printf("Note that symbol server lookups sometimes fail randomly. " "Try again?\n"); } SymCleanup(fakeProcess); return 0; }
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; }