예제 #1
0
파일: createspec.c 프로젝트: nsxz/reactos
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;
}
예제 #2
0
파일: module.c 프로젝트: mingpen/OpenNT
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;
}
예제 #3
0
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;
	}
}
예제 #5
0
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;
}
예제 #6
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);
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
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;
}