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
,它不会崩溃。但它显然也不会渲染任何东西。
hdc
和 hglrc
具有有效地址,它们可能对应于我需要的 GL 上下文,因为这是在创建所需的窗口之后立即调用的。
编辑
将相同的方法应用于其他 OpenGL 函数时不会崩溃,例如SwapBuffers、glFinish 等
在我只是加载我的 DLL 并执行 wglMakeCurrent
的隔离测试的情况下,它可以工作。
如果将我的 DLL 注入应用程序,然后在此应用程序上使用 wglMakeCurrent
,Detours 会导致 trueWglMakeCurrent
调用的无限递归。
【问题讨论】:
尝试在调试器下运行它并在崩溃时获取调用堆栈。然后在这里发布调用堆栈。 @MarcSherman 我测试了更多,发现确实是无限递归导致软件崩溃。看看我的新编辑 我的猜测是你的钩子通过调用 trueWglMakeCurrent 导致了无限递归。反汇编 trueWglMakeCurrent(例如在 windbguf 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” 是啥意思?