static HMODULE WINAPI MyLoadLibraryA(LPCSTR lpLibFileName) { HMODULE hModule = LoadLibraryA(lpLibFileName); DWORD dwLastError = GetLastError(); if (VERBOSITY >= 2) { debugPrintf("inject: intercepting %s(\"%s\") = 0x%p\n", __FUNCTION__ + 2, lpLibFileName, hModule); } if (VERBOSITY > 0) { const char *szBaseName = getBaseName(lpLibFileName); if (isMatchModuleName(szBaseName)) { if (VERBOSITY < 2) { debugPrintf("inject: intercepting %s(\"%s\")\n", __FUNCTION__, lpLibFileName); } #ifdef __GNUC__ void *caller = __builtin_return_address (0); HMODULE hModule = 0; BOOL bRet = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)caller, &hModule); assert(bRet); char szCaller[MAX_PATH]; DWORD dwRet = GetModuleFileNameA(hModule, szCaller, sizeof szCaller); assert(dwRet); debugPrintf("inject: called from %s\n", szCaller); #endif } } // Hook all new modules (and not just this one, to pick up any dependencies) patchAllModules(ACTION_HOOK); SetLastError(dwLastError); return hModule; }
static void patchModule(HMODULE hModule, const char *szModule, Action action) { /* Never patch this module */ if (hModule == g_hThisModule) { return; } /* Never patch our hook module */ if (hModule == g_hHookModule) { return; } /* Hook modules only once */ if (action == ACTION_HOOK) { std::pair< std::set<HMODULE>::iterator, bool > ret; EnterCriticalSection(&Mutex); ret = g_hHookedModules.insert(hModule); LeaveCriticalSection(&Mutex); if (!ret.second) { return; } } const char *szBaseName = getBaseName(szModule); /* Don't hook our replacement modules to avoid tracing internal APIs */ /* XXX: is this really a good idea? */ if (isMatchModuleName(szBaseName)) { return; } /* Leave these modules alone */ if (stricmp(szBaseName, "kernel32.dll") == 0 || stricmp(szBaseName, "ConEmuHk.dll") == 0) { return; } if (VERBOSITY > 0) { debugPrintf("inject: found module %s\n", szModule); } PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = getFirstImportDescriptor(hModule, szModule); if (pImportDescriptor) { while (pImportDescriptor->FirstThunk) { patchDescriptor(hModule, szModule, pImportDescriptor, action); ++pImportDescriptor; } } PImgDelayDescr pDelayDescriptor = getDelayImportDescriptor(hModule, szModule); if (pDelayDescriptor) { while (pDelayDescriptor->rvaDLLName) { if (VERBOSITY > 1) { const char* szName = getDescriptorName(hModule, pDelayDescriptor); debugPrintf("inject: found %sdelay-load import entry for module %s\n", pDelayDescriptor->grAttrs & dlattrRva ? "" : "old-style ", szName); } patchDescriptor(hModule, szModule, pDelayDescriptor, action); ++pDelayDescriptor; } } }
static void patchModule(HMODULE hModule, const char *szModule, Action action) { /* Never patch this module */ if (hModule == g_hThisModule) { return; } /* Never patch our hook module */ if (hModule == g_hHookModule) { return; } /* Hook modules only once */ if (action == ACTION_HOOK) { std::pair< std::set<HMODULE>::iterator, bool > ret; EnterCriticalSection(&g_Mutex); ret = g_hHookedModules.insert(hModule); LeaveCriticalSection(&g_Mutex); if (!ret.second) { return; } } const char *szBaseName = getBaseName(szModule); /* Don't hook our replacement modules to avoid tracing internal APIs */ /* XXX: is this really a good idea? */ if (isMatchModuleName(szBaseName)) { return; } /* Leave these modules alone. * * Hooking other injection DLLs easily leads to infinite recursion (and * stack overflow), especially when those libraries use techniques like * modifying the hooked functions prolog (instead of patching IAT like we * do). * * See also: * - http://www.nynaeve.net/?p=62 */ if (stricmp(szBaseName, "kernel32.dll") == 0 || stricmp(szBaseName, "AcLayers.dll") == 0 || stricmp(szBaseName, "ConEmuHk.dll") == 0 || stricmp(szBaseName, "gameoverlayrenderer.dll") == 0 || stricmp(szBaseName, "gameoverlayrenderer64.dll") == 0) { return; } if (VERBOSITY > 0) { debugPrintf("inject: found module %s\n", szModule); } PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = getFirstImportDescriptor(hModule, szModule); if (pImportDescriptor) { while (pImportDescriptor->FirstThunk) { patchDescriptor(hModule, szModule, pImportDescriptor, action); ++pImportDescriptor; } } PImgDelayDescr pDelayDescriptor = getDelayImportDescriptor(hModule, szModule); if (pDelayDescriptor) { while (pDelayDescriptor->rvaDLLName) { if (VERBOSITY > 1) { const char* szName = getDescriptorName(hModule, pDelayDescriptor); debugPrintf("inject: found %sdelay-load import entry for module %s\n", pDelayDescriptor->grAttrs & dlattrRva ? "" : "old-style ", szName); } patchDescriptor(hModule, szModule, pDelayDescriptor, action); ++pDelayDescriptor; } } }