Example #1
0
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;
}
Example #2
0
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;
        }
    }
}
Example #3
0
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;
        }
    }
}