extern "C" FARPROC __stdcall dllGetProcAddress(HMODULE hModule, LPCSTR function) { uintptr_t loc = (uintptr_t)_ReturnAddress(); void* address = NULL; LibraryLoader* dll = DllLoaderContainer::GetModule(hModule); if( !dll ) { CLog::Log(LOGERROR, "%s - Invalid hModule specified",__FUNCTION__); return NULL; } /* how can somebody get the stupid idea to create such a stupid function */ /* where you never know if the given pointer is a pointer or a value */ if( HIGH_WORD(function) == 0 && LOW_WORD(function) < 1000) { if( dll->ResolveOrdinal(LOW_WORD(function), &address) ) { CLog::Log(LOGDEBUG, "%s(%p(%s), %d) => %p", __FUNCTION__, hModule, dll->GetName(), LOW_WORD(function), address); } else if( dll->IsSystemDll() ) { char ordinal[5]; sprintf(ordinal, "%d", LOW_WORD(function)); address = (void*)create_dummy_function(dll->GetName(), ordinal); /* add to tracklist if we are tracking this source dll */ DllTrackInfo* track = tracker_get_dlltrackinfo(loc); if( track ) tracker_dll_data_track(track->pDll, (uintptr_t)address); CLog::Log(LOGDEBUG, "%s - created dummy function %s!%s",__FUNCTION__, dll->GetName(), ordinal); } else { address = NULL; CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p",__FUNCTION__ , hModule, dll->GetName(), function, address); } } else { if( dll->ResolveExport(function, &address) ) { CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p",__FUNCTION__ , hModule, dll->GetName(), function, address); } else { DllTrackInfo* track = tracker_get_dlltrackinfo(loc); /* some dll's require us to always return a function or it will fail, other's */ /* decide functionallity depending on if the functions exist and may fail */ if( dll->IsSystemDll() && track && stricmp(track->pDll->GetName(), "CoreAVCDecoder.ax") == 0 ) { address = (void*)create_dummy_function(dll->GetName(), function); tracker_dll_data_track(track->pDll, (uintptr_t)address); CLog::Log(LOGDEBUG, "%s - created dummy function %s!%s", __FUNCTION__, dll->GetName(), function); } else { address = NULL; CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p", __FUNCTION__, hModule, dll->GetName(), function, address); } } } return (FARPROC)address; }
int DllLoader::ResolveImports(void) { int bResult = 1; if ( NumOfDirectories >= 2 && Directory[IMPORT_TABLE].Size > 0 ) { ImportDirTable = (ImportDirTable_t*)RVA2Data(Directory[IMPORT_TABLE].RVA); #ifdef DUMPING_DATA PrintImportTable(ImportDirTable); #endif ImportDirTable_t *Imp = ImportDirTable; while ( Imp->ImportLookupTable_RVA != 0 || Imp->TimeStamp != 0 || Imp->ForwarderChain != 0 || Imp->Name_RVA != 0 || Imp->ImportAddressTable_RVA != 0) { const char *Name = (const char*)RVA2Data(Imp->Name_RVA); const char* FileName=ResolveReferencedDll(Name); // If possible use the dll name WITH path to resolve exports. We could have loaded // a dll with the same name as another dll but from a different directory if (FileName) Name=FileName; unsigned long *Table = (unsigned long*)RVA2Data(Imp->ImportLookupTable_RVA); unsigned long *Addr = (unsigned long*)RVA2Data(Imp->ImportAddressTable_RVA); while (*Table) { if (*Table & 0x80000000) { void *Fixup; if ( !ResolveOrdinal(Name, *Table&0x7ffffff, &Fixup) ) { bResult = 0; char szBuf[128]; CLog::Log(LOGDEBUG,"Unable to resolve ordinal %s %lu\n", Name, *Table&0x7ffffff); sprintf(szBuf, "%lu", *Table&0x7ffffff); *Addr = create_dummy_function(Name, szBuf); tracker_dll_data_track(this, *Addr); } else { *Addr = (unsigned long)Fixup; //woohoo!! } } else { // We don't handle Hint/Name tables yet!!! char *ImpName = (char*)RVA2Data(*Table + 2); void *Fixup; if ( !ResolveName(Name, ImpName, &Fixup) ) { *Addr=get_win_function_address(Name, ImpName); if(!*Addr) { CLog::Log(LOGDEBUG,"Unable to resolve %s %s\n", Name, ImpName); *Addr = create_dummy_function(Name, ImpName); tracker_dll_data_track(this, *Addr); bResult = 0; } } else { *Addr = (unsigned long)Fixup; } } Table++; Addr++; } Imp++; } } return bResult; }