void patchDescriptor(HMODULE hModule, const char *szModule, T pImportDescriptor) { const char* szDescriptorName = getDescriptorName(hModule, pImportDescriptor); ModulesMap::const_iterator modIt = modulesMap.find(szDescriptorName); if (modIt != modulesMap.end()) { const char *szMatchModule = modIt->first; // same as szDescriptorName const Module & module = modIt->second; const FunctionMap & functionMap = module.functionMap; FunctionMap::const_iterator fnIt; for (fnIt = functionMap.begin(); fnIt != functionMap.end(); ++fnIt) { const char *szFunctionName = fnIt->first; LPVOID lpNewAddress = fnIt->second; BOOL bHooked; bHooked = patchFunction(hModule, szModule, szMatchModule, pImportDescriptor, szFunctionName, lpNewAddress); if (bHooked && !module.bInternal && pSharedMem) { pSharedMem->bReplaced = TRUE; } } } }
static FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName) { if (VERBOSITY >= 3) { /* XXX this can cause segmentation faults */ logGetProcAddress(hModule, lpProcName); } if (!NOOP) { char szModule[MAX_PATH]; DWORD dwRet = GetModuleFileNameA(hModule, szModule, sizeof szModule); assert(dwRet); const char *szBaseName = getBaseName(szModule); ModulesMap::const_iterator modIt; modIt = modulesMap.find(szBaseName); if (modIt != modulesMap.end()) { if (VERBOSITY > 1 && VERBOSITY < 3) { logGetProcAddress(hModule, lpProcName); } if (HIWORD(lpProcName) == 0) { debugPrintf("inject: ignoring %s!@%u\n", szBaseName, LOWORD(lpProcName)); return GetProcAddress(hModule, lpProcName); } const Module & module = modIt->second; const FunctionMap & functionMap = module.functionMap; FunctionMap::const_iterator fnIt; fnIt = functionMap.find(lpProcName); if (fnIt != functionMap.end()) { LPVOID pProcAddress = fnIt->second; if (VERBOSITY > 0) { debugPrintf("inject: replacing %s!%s\n", szBaseName, lpProcName); } if (!module.bInternal && pSharedMem) { pSharedMem->bReplaced = TRUE; } return (FARPROC)pProcAddress; } else { if (VERBOSITY > 0 && !module.bInternal) { debugPrintf("inject: ignoring %s!%s\n", szBaseName, lpProcName); } } } } return GetProcAddress(hModule, lpProcName); }
void patchDescriptor(HMODULE hModule, const char *szModule, T pImportDescriptor, Action action) { const char* szDescriptorName = getDescriptorName(hModule, pImportDescriptor); ModulesMap::const_iterator modIt = modulesMap.find(szDescriptorName); if (modIt != modulesMap.end()) { const char *szMatchModule = modIt->first; // same as szDescriptorName const Module & module = modIt->second; const FunctionMap & functionMap = module.functionMap; FunctionMap::const_iterator fnIt; for (fnIt = functionMap.begin(); fnIt != functionMap.end(); ++fnIt) { const char *szFunctionName = fnIt->first; LPVOID lpHookAddress = fnIt->second; // Knowning the real address is useful when patching imports by ordinal LPVOID lpRealAddress = NULL; HMODULE hRealModule = GetModuleHandleA(szDescriptorName); if (hRealModule) { // FIXME: this assertion can fail when the wrapper name is the same as the original DLL //assert(hRealModule != g_hHookModule); if (hRealModule != g_hHookModule) { lpRealAddress = (LPVOID)GetProcAddress(hRealModule, szFunctionName); } } LPVOID lpOldAddress = lpRealAddress; LPVOID lpNewAddress = lpHookAddress; if (action == ACTION_UNHOOK) { std::swap(lpOldAddress, lpNewAddress); } BOOL bPatched; bPatched = patchFunction(hModule, szModule, szMatchModule, pImportDescriptor, szFunctionName, lpOldAddress, lpNewAddress); if (action == ACTION_HOOK && bPatched && !module.bInternal && pSharedMem) { pSharedMem->bReplaced = TRUE; } } } }
static void dumpRegisteredHooks(void) { if (VERBOSITY > 1) { ModulesMap::const_iterator modIt; for (modIt = modulesMap.begin(); modIt != modulesMap.end(); ++modIt) { const char *szMatchModule = modIt->first; const Module & module = modIt->second; const FunctionMap & functionMap = module.functionMap; FunctionMap::const_iterator fnIt; for (fnIt = functionMap.begin(); fnIt != functionMap.end(); ++fnIt) { const char *szFunctionName = fnIt->first; debugPrintf("inject: registered hook for %s!%s%s\n", szMatchModule, szFunctionName, module.bInternal ? " (internal)" : ""); } } } }
void ModuleRegistry::unloadModules() { _uninitialisedModules.clear(); // greebo: It's entirely possible that the clear() method will clear the // last shared_ptr of a module. Module might still call this class' moduleExists() // method which in turn refers to a semi-destructed ModulesMap instance. // So, copy the contents to a temporary map before clearing it out. ModulesMap tempMap; tempMap.swap(_initialisedModules); tempMap.clear(); // We need to delete all pending objects before unloading modules // wxWidgets needs a chance to delete them before memory access is denied if (wxTheApp != NULL) { wxTheApp->ProcessIdle(); } _loader.unloadModules(); }
static inline bool isMatchModuleName(const char *szModuleName) { ModulesMap::const_iterator modIt = modulesMap.find(szModuleName); return modIt != modulesMap.end(); }
/** * Determine all loaded modules as well as the process module itself for the given process id. */ NaviError LinuxSystem::fillModules(pid_t pid, ModulesMap& modules) { std::string filename = "/proc/" + zylib::zycon::toString(pid) + "/maps"; msglog->log(LOG_ALL, "Trying to read the modules map from file %s", filename.c_str()); std::ifstream file(filename.c_str()); if (!file) { msglog->log(LOG_ALWAYS, "Error: Couldn't read modules map file"); return NaviErrors::COULDNT_READ_MEMORY; } std::vector < std::string > lines; std::string line; while (std::getline(file, line)) { msglog->log(LOG_ALL, "Successfully read line %s from modules map file", line.c_str()); lines.push_back(line); } // 08048000-08053000 r-xp 00000000 08:01 282412 /usr/bin/kdeinit // 08053000-08054000 r--p 0000a000 08:01 282412 /usr/bin/kdeinit // 08054000-08055000 rw-p 0000b000 08:01 282412 /usr/bin/kdeinit // 09f73000-0a016000 rw-p 09f73000 00:00 0 [heap] // b6638000-b6672000 rw-p b6672000 00:00 0 // b66bb000-b66d9000 r-xp 00000000 08:01 352021 /usr/lib/kde3/plugins/styles/plastik.so // b66d9000-b66da000 r--p 0001d000 08:01 352021 /usr/lib/kde3/plugins/styles/plastik.so // b66da000-b66db000 rw-p 0001e000 08:01 352021 /usr/lib/kde3/plugins/styles/plastik.so // b66db000-b66e1000 r--s 00000000 08:01 396230 /var/cache/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-x86.cache-2 // b66e1000-b66e4000 r--s 00000000 08:01 396239 /var/cache/fontconfig/e383d7ea5fbe662a33d9b44caf393297-x86.cache-2 // b66e4000-b66e5000 r--s 00000000 08:01 396225 /var/cache/fontconfig/4c73fe0c47614734b17d736dbde7580a-x86.cache-2 // b66e5000-b66e8000 r--s 00000000 08:01 396231 /var/cache/fontconfig/a755afe4a08bf5b97852ceb7400b47bc-x86.cache-2 // b66e8000-b66ef000 r--s 00000000 08:01 396608 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-x86.cache-2 // b66ef000-b66f7000 r--s 00000000 08:01 396240 /var/cache/fontconfig/e3de0de479f42330eadf588a55fb5bf4-x86.cache-2 // b66f7000-b6702000 r--s 00000000 08:01 396220 /var/cache/fontconfig/0f34bcd4b6ee430af32735b75db7f02b-x86.cache-2 // b6702000-b6709000 r--s 00000000 08:01 396234 /var/cache/fontconfig/d52a8644073d54c13679302ca1180695-x86.cache-2 std::string lastName = ""; CPUADDRESS start = 0; CPUADDRESS end = 0; for (std::vector<std::string>::iterator Iter = lines.begin(); Iter != lines.end(); ++Iter) { std::string line = *Iter; size_t position = line.find("/"); if (position != std::string::npos) { // OK, we found a line with a name; now we gotta figure out if we found a new module // or just with a new section in the same module. std::string name = line.substr(position); // TODO: Only works in 32bit platforms std::string startString = Iter->substr(0, 8); std::string endString = Iter->substr(9, 8); if (name != lastName) { // We found a new module, so we can take the information from the previous // module and add the previous module to the list of modules. if (lastName != "") { Module newModule(getModuleName(lastName), lastName, start, end - start); modules.insert(std::make_pair(lastName, newModule)); } lastName = name; start = zylib::zycon::parseHexString < CPUADDRESS > (startString); end = zylib::zycon::parseHexString < CPUADDRESS > (endString); } else { // The module in the current line is the same module we already processed // in the previous line. Only the end information has to be updated in this // case. end = zylib::zycon::parseHexString < CPUADDRESS > (endString); } } else if (lastName != "") { // We found a line without a name and the previous module has // a valid name => Add the previous module to the list of modules. Module newModule(getModuleName(lastName), lastName, start, end - start); modules.insert(std::make_pair(lastName, newModule)); lastName = ""; } } if (lastName != "") { // Add the last module in the list. Module newModule(getModuleName(lastName), lastName, start, end - start); modules.insert(std::make_pair(lastName, newModule)); } return NaviErrors::SUCCESS; }