OpenGL/DirectX Hook - 类似于FRAPS

14

是否有可能像FRAPS一样检测正在使用OpenGL或DirectX的应用程序?(可能使用某种形式的钩子)?我可能不需要实际绘制到窗口,我只需要知道哪些进程正在进行某种形式的3D渲染。

(编辑:) 如果您不熟悉它,FRAPS是一个可以在3D应用程序上绘制“每秒帧数”计数器的程序。 FRAPS会自己找到所有正在运行的3D应用程序,而无需您指定进程名称。

“每秒帧数”计数器在外部游戏上的示例: enter image description here


我猜想你正在寻找的函数可能隐藏在微软的Windows APIs中。建议你在那里寻找解决方案。 - Oskar
您可以看一下http://taksi.sourceforge.net/。它是FRAPS的开源替代品。最大的优点是您可以查看源代码,找到您需要的内容。 - JohnGray
2
请注意,并非所有使用DirectX/Direct3D的应用程序都进行3D渲染。我们使用D3D来渲染H.264视频。 - Deanna
1
我认为这对于dx可能会有所帮助... 从注入的DLL挂钩DirectX EndScene - Zilog
@Deanna +1 谢谢你的警告,这是需要关注的另一件事情。 - David
3个回答

9
可能最简单的方法是检查OpenGL和DirectX核心库是否存在,可能还应该添加驱动程序OGL dll(如nvogl),可以通过使用p/invoke的EnumProcessesEnumProcessModulesEx来完成,这将至少给你一个可能使用OGL或DX的进程集合作为起点。
当然,有些应用程序加载两个API并仅使用其中一个,或者只有在特殊工具等情况下才会有条件地使用其中一个GFX API。对于这种情况,我认为最好的方法是执行某种形式的注入或像调试器一样附加到进程,然后钩住DX的Present或OGL的wglSwapBuffers
您可能可以通过枚举GDI句柄并查找DXGI或OGL渲染上下文来避免使用钩子,但我不知道这是否可行。

来自MSDN: "如果从在WOW64上运行的32位应用程序中调用此函数,则只能枚举32位进程的模块。如果进程是64位进程,则此函数将失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)。” 这不是问题的一部分,但我需要适用于32/64位的解决方案。如果进程是64位的呢?这是否意味着如果我将应用程序编译为64位,它应该可以与32/64位一起工作?还是只有当您是32位时,才无法枚举64位应用程序? - David
@David:有32位和64位的变体可用(EnumProcessModulesEx),但您需要一个64位应用程序才能获取32位和64位进程(请参见备注),并且您仍然需要32位构建以适用于32位操作系统。 - Necrolis

8
据我所了解,FRAPS采用相对粗暴的方法来确定放置商店的位置。该过程始于SetWindowsHookEx,请求操作系统将FRAPS hook DLL加载到它可以[和未来进程]运行的每个进程中。 DLL中的魔法归结为使用GetModuleHandleA运行一组过程性测试,以观察它所附加到的进程是否已加载任何OpenGL / DirectX模块。如果所有调用都返回NULL,则hook尝试从进程中删除自身。
另一方面,如果进程已加载它们,则仅通过删除保护并注入JMP hook来挂接该库的适当渲染函数。在OpenGL中,wglSwapBuffers通常是唯一相关的。当进程调用此函数时,它最终会调用FRAPS模块,然后FRAPS会将背景缓冲区捕获到其队列中以进行编码到AVI并呈现其小指示。然后它处理wglSwapBuffers的原始请求,并将执行返回给程序。
至于在C#中查询...请查看EasyHook(http://easyhook.codeplex.com/),看看它是否适合您。我个人没有使用过此API。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接