bool Win32DllLoader::Load() { if (m_dllHandle != NULL) return true; CStdString strFileName = GetFileName(); CStdStringW strDllW; g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(strFileName), strDllW); m_dllHandle = LoadLibraryExW(strDllW.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (!m_dllHandle) { LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, 0, (LPTSTR) &lpMsgBuf, 0, NULL ); CLog::Log(LOGERROR, "%s: Failed to load %s with error %d:%s", __FUNCTION__, CSpecialProtocol::TranslatePath(strFileName).c_str(), dw, lpMsgBuf); LocalFree(lpMsgBuf); return false; } // handle functions that the dll imports if (NeedsHooking(strFileName.c_str())) OverrideImports(strFileName); else bIsSystemDll = true; return true; }
bool Win32DllLoader::Load() { if (m_dllHandle != NULL) return true; CStdString strFileName = GetFileName(); CLog::Log(LOGDEBUG, "%s(%s)\n", __FUNCTION__, strFileName.c_str()); CStdStringW strDllW; g_charsetConverter.utf8ToW(_P(strFileName), strDllW); m_dllHandle = LoadLibraryExW(strDllW.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (!m_dllHandle) { CLog::Log(LOGERROR, "%s: Unable to load %s (%d)", __FUNCTION__, strFileName.c_str(), GetLastError()); return false; } // handle functions that the dll imports if (NeedsHooking(strFileName.c_str())) OverrideImports(strFileName); else bIsSystemDll = true; return true; }
bool Win32DllLoader::Load() { if (m_dllHandle != NULL) return true; std::string strFileName = GetFileName(); std::wstring strDllW; g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(strFileName), strDllW, false, false, false); m_dllHandle = LoadLibraryExW(strDllW.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (!m_dllHandle) { DWORD dw = GetLastError(); wchar_t* lpMsgBuf = NULL; DWORD strLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPWSTR)&lpMsgBuf, 0, NULL); if (strLen == 0) strLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPWSTR)&lpMsgBuf, 0, NULL); if (strLen != 0) { std::string strMessage; g_charsetConverter.wToUTF8(std::wstring(lpMsgBuf, strLen), strMessage); CLog::Log(LOGERROR, "%s: Failed to load \"%s\" with error %lu: \"%s\"", __FUNCTION__, CSpecialProtocol::TranslatePath(strFileName).c_str(), dw, strMessage.c_str()); } else CLog::Log(LOGERROR, "%s: Failed to load \"%s\" with error %lu", __FUNCTION__, CSpecialProtocol::TranslatePath(strFileName).c_str(), dw); LocalFree(lpMsgBuf); return false; } // handle functions that the dll imports if (NeedsHooking(strFileName.c_str())) OverrideImports(strFileName); else bIsSystemDll = true; return true; }
void Win32DllLoader::OverrideImports(const std::string &dll) { std::wstring strdllW; g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(dll), strdllW, false); BYTE* image_base = (BYTE*)GetModuleHandleW(strdllW.c_str()); if (!image_base) { CLog::Log(LOGERROR, "%s - unable to GetModuleHandle for dll %s", __FUNCTION__, dll.c_str()); return; } PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)image_base; PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(image_base + dos_header->e_lfanew); // e_lfanew = value at 0x3c PIMAGE_IMPORT_DESCRIPTOR imp_desc = (PIMAGE_IMPORT_DESCRIPTOR)( image_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); if (!imp_desc) { CLog::Log(LOGERROR, "%s - unable to get import directory for dll %s", __FUNCTION__, dll.c_str()); return; } // loop over all imported dlls for (int i = 0; imp_desc[i].Characteristics != 0; i++) { char *dllName = (char*)(image_base + imp_desc[i].Name); // check whether this is one of our dll's. if (NeedsHooking(dllName)) { // this will do a loadlibrary on it, which should effectively make sure that it's hooked // Note that the library has obviously already been loaded by the OS (as it's implicitly linked) // so all this will do is insert our hook and make sure our DllLoaderContainer knows about it HMODULE hModule = dllLoadLibraryA(dllName); if (hModule) m_referencedDlls.push_back(hModule); } PIMAGE_THUNK_DATA orig_first_thunk = (PIMAGE_THUNK_DATA)(image_base + imp_desc[i].OriginalFirstThunk); PIMAGE_THUNK_DATA first_thunk = (PIMAGE_THUNK_DATA)(image_base + imp_desc[i].FirstThunk); // and then loop over all imported functions for (int j = 0; orig_first_thunk[j].u1.Function != 0; j++) { void *fixup = NULL; if (orig_first_thunk[j].u1.Function & 0x80000000) ResolveOrdinal(dllName, (orig_first_thunk[j].u1.Ordinal & 0x7fffffff), &fixup); else { // resolve by name PIMAGE_IMPORT_BY_NAME orig_imports_by_name = (PIMAGE_IMPORT_BY_NAME)( image_base + orig_first_thunk[j].u1.AddressOfData); ResolveImport(dllName, (char*)orig_imports_by_name->Name, &fixup); }/* if (!fixup) { // create a dummy function for tracking purposes PIMAGE_IMPORT_BY_NAME orig_imports_by_name = (PIMAGE_IMPORT_BY_NAME)( image_base + orig_first_thunk[j].u1.AddressOfData); fixup = CreateDummyFunction(dllName, (char*)orig_imports_by_name->Name); }*/ if (fixup) { // save the old function Import import; import.table = &first_thunk[j].u1.Function; import.function = first_thunk[j].u1.Function; m_overriddenImports.push_back(import); DWORD old_prot = 0; // change to protection settings so we can write to memory area VirtualProtect((PVOID)&first_thunk[j].u1.Function, 4, PAGE_EXECUTE_READWRITE, &old_prot); // patch the address of function to point to our overridden version first_thunk[j].u1.Function = (DWORD)fixup; // reset to old settings VirtualProtect((PVOID)&first_thunk[j].u1.Function, 4, old_prot, &old_prot); } } } }