Detours 因 wglMakeCurrent 而崩溃

Posted

技术标签:

【中文标题】Detours 因 wglMakeCurrent 而崩溃【英文标题】:Detours crashes with wglMakeCurrent 【发布时间】:2016-05-10 18:23:32 【问题描述】:

我在我的项目中使用 Detours 来保存窗口的 GL 上下文。

所以我按照Detours 3.0 Express Edition附带的代码示例:

static BOOL (WINAPI * trueWglMakeCurrent)(HDC, HGLRC) = wglMakeCurrent;
BOOL WINAPI hookedWglMakeCurrent(HDC hdc, HGLRC hglrc);

BOOL WINAPI hookedWglMakeCurrent(HDC hdc, HGLRC hglrc)

    wContext = hglrc;
    wDC = hdc;

    return trueWglMakeCurrent(hdc, hglrc);  //CRASH HERE
    //return TRUE;

但是在调用原始 WGL 方法时它会崩溃。如果我将返回更改为return TRUE,它不会崩溃。但它显然也不会渲染任何东西。

hdchglrc 具有有效地址,它们可能对应于我需要的 GL 上下文,因为这是在创建所需的窗口之后立即调用的。

编辑

将相同的方法应用于其他 OpenGL 函数时不会崩溃,例如SwapBuffers、glFinish 等

在我只是加载我的 DLL 并执行 wglMakeCurrent 的隔离测试的情况下,它可以工作。

如果将我的 DLL 注入应用程序,然后在此应用程序上使用 wglMakeCurrent,Detours 会导致 trueWglMakeCurrent 调用的无限递归。

【问题讨论】:

尝试在调试器下运行它并在崩溃时获取调用堆栈。然后在这里发布调用堆栈。 @MarcSherman 我测试了更多,发现确实是无限递归导致软件崩溃。看看我的新编辑 我的猜测是你的钩子通过调用 trueWglMakeCurrent 导致了无限递归。反汇编 trueWglMakeCurrent(例如在 windbg uf trueWglMakeCurrent 中)应该将 JMP 显示为 hookedWglMakeCurrent 作为第一条指令。我相信安装钩子的 Detours API 也会返回一个函数指针,当你的钩子想要调用真正的实现时应该调用它。 trueWglMakeCurrent 应该是这个函数指针。我通过将这些定义放在与我的 DLLMain 相同的文件中来解决它。不知道为什么。 【参考方案1】:

问题是由于未正确链接函数而导致的无限递归。

Detours 创建一个指向原始wglMakeCurrent 的函数指针,在我的例子中,我存储在trueWglMakeCurrent 中。但是,只有当我声明它并在具有 DLLMain 和 DetourAPI 用法的同一文件上使用它时它才有效。和例子一模一样:

static BOOL (WINAPI * trueWglMakeCurrent)(HDC,HGLRC) = wglMakeCurrent;

GTNSPECTRA_C_EXPORT BOOL WINAPI hookedWglMakeCurrent(HDC hDC, HGLRC hRC)

    ...
    return trueWglMakeCurrent(hDC, hRC);


BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  reason,
                   LPVOID lpReserved)

    ...
    DetourRestoreAfterWith();

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)trueWglMakeCurrent, hookedWglMakeCurrent);
    DetourTransactionCommit();

    ...
    return TRUE;
 

【讨论】:

以上是关于Detours 因 wglMakeCurrent 而崩溃的主要内容,如果未能解决你的问题,请参考以下文章

“QGLContext::makeCurrent() : wglMakeCurrent failed: The operation completed successfully” 是啥意思?

Detours 3.0 钩子 GetProcAddresss()

构建 32 位 Detours 库

25.Detours劫持技术

Dev-C++ 和 Detours 编译错误

C++——Detours(Win32 API劫持)——劫持类方法