从OpenGL应用程序中提取颜色/深度缓冲区

Extract color/depth buffer from OpenGL applications

本文关键字:深度 缓冲区 颜色 提取 OpenGL 应用程序      更新时间:2023-10-16

我曾考虑过一个安静的项目,该项目需要从OpenGL应用程序(尤其是游戏(中提取颜色和深度缓冲区。从操纵游戏本身的角度来看,它绝对与修改无关,也不是为了"作弊",而只是为了收集数据。

因此,现在我正试图找出可能的方法来实现它。当然,在Windows下使用Direct3D甚至会产生更多可用的应用程序,但由于我非常熟悉Linux下的OpenGL,我会从这种方式开始。

由于有许多修改/作弊应用程序可以实际操作不同类型的视频游戏的颜色/深度缓冲区(例如,自我射击游戏中的wallhacks(,因此这似乎肯定是可能的。

现在的问题是,实现这一目标的最佳方式是什么?根据这个线程,直接读取GPU内存很可能不起作用,因为OpenGL中的内存映射完全取决于供应商的实现,并且没有简单的方法可以获得相应数据的VRAM地址。

我能想到的替代方法现在可能被归类为静脉外或静脉内:

  • Extravenive:从进程提取OpenGL上下文,并从第三个应用程序访问缓冲区、着色器等,而无需真正直接操纵目标应用程序二进制文件
  • 静脉内以这样一种方式操作目标应用程序二进制/代码,即将相应的缓冲区/数据写入内存中的特定位置或直接保存到某个位置

后期方法肯定会起作用,但可能需要付出更大的努力,并且需要针对每个应用程序进行。因此,首先肯定是首选,但所描述的方式是否适用?当您拥有另一个进程的OpenGL上下文值时,是否可以从不同进程访问OpenGL资源?有人有这方面的经验吗?

更新:

经过一些研究,我发现我想要的东西很常见,通常被称为"挂钩"或"拦截"。

对于OpenGL和Direct3D,有许多不同的库和程序可以做到这一点:

  • flattercept:OpenGL@Windows
  • Indicium Supra:DDirectX
  • apitrace:OpenGL+Direct3D@Windows、macOS、Linux
  • D3D9拦截器:Direct3D
  • Nvidia Nsight:Direct3D+OpenGL+Vulkan@Windows,Linux

和许多其他。

实现这一点的实际标准方法是将自己挂钩到流程中,并将应用程序(游戏(调用的API图形重定向到自己的代码中。然后,钩子可以记录它需要的任何数据,并在将调用传递给实际的API实现之前执行它想要的任何操作。有很多方法可以做到这一点,各有利弊,从用相同的界面构建一个假库,诱骗游戏加载该库而不是实际的图形库(DLL注入(,到修改加载的进程映像中的机器代码,使函数调用跳转到代码中。哪些方法适用并且最适合您的情况将在很大程度上取决于许多因素,如目标平台、目标应用程序、您想要连接的API等等

然而,任何这种方法的主要问题是,这正是作弊的数量。因此,许多电子游戏都会内置保护功能,以防止这种东西正常工作。在许多网络游戏中,你甚至可能会因为涉嫌作弊而冒着账户被暂停的风险。但这只是需要注意的一点。根据我的经验,它仍然适用于许多游戏,尤其是单人游戏。

"从另一个进程提取OpenGL上下文"将不起作用,至少在任何适当的操作系统上都不起作用。将流程抽象放在首位的全部目的是将应用程序彼此隔离…

由于我没有足够的声誉在评论中问这个问题,让我在这里问你你的目标是什么。你想在一帧内获得一次这些信息,还是想在一段时间内记录多帧?您是否需要一个自定义应用程序形式的自动化解决方案?如果两者都没有,您可能只需要使用像Nsight graphics这样的图形调试工具来捕获和导出您想要的帧…