Beispiel #1
0
int KFuncTable::InterceptWin32(const char        *Caller,
                               const char        *Callee,
                               PIMAGE_THUNK_DATA  pName,
                               PIMAGE_THUNK_DATA  pThunk,
                               const char        *baseAddress)
{
    int no = 0;
    
    // if module not added to module table, quit
    if (LookupModule(Caller, Callee) == -1)
        return 0;

    
    while ( pThunk->u1.Function )
    {
        int id;

        PBYTE   pFunctionName        = (PBYTE) ( baseAddress + (unsigned) pName->u1.ForwarderString + 2);
        FARPROC pInterceptedFunction = LookupInterceptedAPI((FARPROC) pThunk->u1.Function, id);

        if ( pInterceptedFunction )
			if ( HackCopy(& pThunk->u1.Function, & pInterceptedFunction, sizeof(FARPROC)) )
			{
				m_func[id].f_hooked = TRUE;
				no ++;
			}	
            
        pName ++;
        pThunk++;
    }

    return no;
}
// Adds a modules to the MODULE_FILE_INFO list.  If the module imports other
// modules, this routine recurses to add them, and check their imports.
errModuleDependencyList
MODULE_DEPENDENCY_LIST::AddModule( PSTR pszFileName )
{
    PE_EXE peFile( pszFileName );       // Get easy access to the executable
    
    if ( FALSE == peFile.IsValid() )    // A valid PE file???
        return (errModuleDependencyList)peFile.GetErrorType();

    PMODULE_FILE_INFO pNew = new MODULE_FILE_INFO( pszFileName );
    if ( !pNew )
        return errMDL_GENERAL_FAILURE;

    pNew->m_pNext = m_pList;
    m_pList = pNew;

    m_cModules++;
    
    //
    // Now see if this module imports any other modules.  If so, we need
    // to recurse and add them as well.
    //
    if (0 == peFile.GetDataDirectoryEntrySize( IMAGE_DIRECTORY_ENTRY_IMPORT ))
        return errMDL_NO_ERROR;

    // Make a pointer to the imports table
    PIMAGE_IMPORT_DESCRIPTOR pImportDir;
    pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)
        peFile.GetDataDirectoryEntryPointer(IMAGE_DIRECTORY_ENTRY_IMPORT);
    if ( !pImportDir )
        return errMDL_NO_ERROR;

    // While there are still non-null IMAGE_IMPORT_DESCRIPTORs...
    while ( pImportDir->Name )
    {
        // Get a pointer to the imported module's base name
        PSTR pszBaseName;
        pszBaseName = (PSTR)peFile.GetReadablePointerFromRVA(pImportDir->Name);
        if ( !pszBaseName )
            break;

        // Check to see if it's already in our list.  Don't add again if so.
        if ( 0 == LookupModule( pszBaseName, FALSE ) )
        {
            // Search path supposedly has the same searching algorithm as
            // the the Win32 loader...
            char szPath[MAX_PATH];
            PSTR pszDontCare;
            if ( SearchPath(0, pszBaseName, 0, MAX_PATH, szPath, &pszDontCare))
                AddModule( szPath );
            else
                pNew->AddNotFoundModule( pszBaseName );
        }
        
        pImportDir++;   // Advance to next imported module
    }

    return errMDL_NO_ERROR;
}
Beispiel #3
0
bool Yap_getUnknown(Term mod) {
  ModEntry *m = LookupModule(mod);
  return Yap_getUnknownModule(m);
}
Beispiel #4
0
Win32CallstackResolver::Win32CallstackResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal)
{
	wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini"));
	{
		FILE *f = NULL;
		_wfopen_s(&f, configPath.c_str(), L"a");
		if(f) fclose(f);
	}

	wchar_t inputBuf[2048];
	GetPrivateProfileStringW(L"renderdoc", L"ignores", NULL, &inputBuf[0], 2048, configPath.c_str());
	wstring ignores = inputBuf;
	split(ignores, pdbIgnores, L';');

	wstring widepdbsearch = StringFormat::UTF82Wide(pdbSearchPaths);

	split(widepdbsearch, pdbRememberedPaths, L';');

	pdblocateProcess = NULL;
	pdblocatePipe = NULL;

	OpenPdblocateHandle();
	
	if(memcmp(moduleDB, "WN32CALL", 8))
	{
		RDCWARN("Can't load callstack resolve for this log. Possibly from another platform?");
		return;
	}

	char *chunks = moduleDB + 8;
	char *end = chunks + DBSize - 8;
	
	EnumModChunk *chunk = (EnumModChunk *)(chunks);
	WCHAR *modName = (WCHAR *)(chunks+sizeof(EnumModChunk));

	if(pdblocatePipe == NULL)
		return;

	// loop over all our modules
	for(; chunks < end; chunks += sizeof(EnumModChunk)+(chunk->imageNameLen)*sizeof(WCHAR) )
	{
		chunk = (EnumModChunk *)chunks;
		modName = (WCHAR *)(chunks+sizeof(EnumModChunk));

		if(killSignal && *killSignal)
			break;
		
		Module m;

		m.name = modName;
		m.base = chunk->base;
		m.size = chunk->size;
		m.moduleId = 0;

		if(find(pdbIgnores.begin(), pdbIgnores.end(), m.name) != pdbIgnores.end())
		{
			RDCWARN("Not attempting to get symbols for %ls", m.name.c_str());

			modules.push_back(m);
			continue;
		}

		// get default pdb (this also looks up symbol server etc)
		// relies on pdblocate. Always done in unicode
		std::wstring defaultPdb = LookupModule(modName, chunk->guid, chunk->age);

		// strip newline
		if(defaultPdb != L"" && defaultPdb[defaultPdb.length()-1] == '\n')
			defaultPdb.pop_back();

		// if we didn't even get a default pdb we'll have to prompt first time through
		bool failed = false;

		if(defaultPdb == L"")
		{
			defaultPdb = strlower(basename(m.name));

			size_t it = defaultPdb.find(L".dll");
			if(it != wstring::npos)
			{
				defaultPdb[it+1] = L'p';
				defaultPdb[it+2] = L'd';
				defaultPdb[it+3] = L'b';
			}

			it = defaultPdb.find(L".exe");
			if(it != wstring::npos)
			{
				defaultPdb[it+1] = L'p';
				defaultPdb[it+2] = L'd';
				defaultPdb[it+3] = L'b';
			}
			failed = true;
		}

		std::wstring pdbName = defaultPdb;

		int fallbackIdx = -1;

		while(m.moduleId == 0)
		{
			if(failed)
			{
				fallbackIdx++;
				// try one of the folders we've been given, just in case the symbols
				// are there
				if(fallbackIdx < (int)pdbRememberedPaths.size())
				{
					pdbName = pdbRememberedPaths[fallbackIdx] + L"\\" + basename(pdbName);
				}
				else
				{
					pdbName = dirname(defaultPdb) + L"\\" + basename(defaultPdb);

					// prompt for new pdbName, unless it's renderdoc or dbghelp
					if(pdbName.find(L"renderdoc.") != wstring::npos ||
						pdbName.find(L"dbghelp.") != wstring::npos)
						pdbName = L"";
					else
						pdbName = pdbBrowse(pdbName);

					// user cancelled, just don't load this pdb
					if(pdbName == L"")
						break;
				}

				failed = false;
			}

			m.moduleId = GetModuleID(pdbName, chunk->guid, chunk->age);

			if(m.moduleId == 0)
			{
				failed = true;
			}
			else
			{
				if(fallbackIdx >= (int)pdbRememberedPaths.size())
				{
					wstring dir = dirname(pdbName);
					if(find(pdbRememberedPaths.begin(), pdbRememberedPaths.end(), dir) == pdbRememberedPaths.end())
					{
						pdbRememberedPaths.push_back(dir);
					}
				}
			}
		}

		// didn't load the pdb? go to the next module.
		if (m.moduleId == 0)
		{
			modules.push_back(m); // still add the module, with 0 module id
			
			RDCWARN("Couldn't get symbols for %ls", m.name.c_str());

			// silently ignore renderdoc.dll and dbghelp.dll without asking to permanently ignore
			if(m.name.find(L"renderdoc") != wstring::npos ||
				m.name.find(L"dbghelp") != wstring::npos)
				continue;

			wchar_t text[1024];
			wsprintf(text, L"Do you want to permanently ignore this file?\nPath: %ls", m.name.c_str());

			int ret = MessageBoxW(NULL, text, L"Ignore this pdb?", MB_YESNO);

			if(ret == IDYES)
				pdbIgnores.push_back(m.name);

			continue;
		}

		SetModuleBaseAddress(m.moduleId, chunk->base);
		
		RDCLOG("Loaded Symbols for %ls", m.name.c_str());

		modules.push_back(m); 
	}

	sort( pdbIgnores.begin(), pdbIgnores.end() );
	pdbIgnores.erase( unique( pdbIgnores.begin(), pdbIgnores.end() ), pdbIgnores.end() );
	merge(pdbIgnores, ignores, L';');
	WritePrivateProfileStringW(L"renderdoc", L"ignores", ignores.c_str(), configPath.c_str());
}