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

标签 c++ linux opengl reverse-engineering

我安静地思考了一个项目,该项目需要从 OpenGL 应用程序(特别是游戏)中提取颜色和深度缓冲区。就操纵游戏本身而言,它与模组完全无关,或者旨在用于“作弊”目的,但更多的是用于数据收集。

所以现在我正在尝试找出可能的方法来实现它。当然,能够在 Windows 下使用 Direct3D 来实现这一点甚至会带来更多可用的应用程序,但由于我非常熟悉 Linux 下的 OpenGL,所以我会以这种方式开始。

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

现在的问题是,实现这一目标的最佳方法是什么?直接读取 GPU 内存很可能不起作用 according to this thread因为 OpenGL 中的内存映射完全依赖于供应商的实现,并且没有简单的方法来获取相应数据的 VRAM 地址。

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

  • 额外:从进程中提取 OpenGL 上下文,并从第三个应用程序访问缓冲区、着色器等,而无需真正直接操作目标应用程序二进制文件。
  • 静脉注入(inject):操纵目标应用程序二进制文件/代码,将相应的缓冲区/数据写入内存中的特定位置或直接保存它在某个地方。

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

更新:

经过一些研究,我发现我正在寻找的内容非常常见,通常称为“Hooking”或“拦截”。

对于 OpenGL 和 Direct3D,有许多不同的库和程序可以执行此操作:

还有很多其他的。

最佳答案

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

然而,任何此类方法的主要问题是,这正是许多作弊的原理。因此,许多视频游戏都会配备内置保护,以防止此类东西发挥作用。对于许多在线游戏,您甚至可能会因为尝试做这样的事情而冒着因涉嫌作弊而被暂停帐户的风险。但这只是需要注意的事情。根据我的经验,它仍然适用于许多游戏,特别是单人游戏。

“从另一个进程中提取 OpenGL 上下文”将不起作用,至少在任何正确的操作系统上都不起作用。首先进行流程抽象的全部目的是将应用程序彼此隔离......

由于我没有足够的声誉来在评论中提出这个问题,所以让我在这里问你你的目标到底是什么。您想要获取单个帧的此信息一次还是想要在一段时间内记录多个帧的此信息?您是否需要定制应用程序形式的自动化解决方案?如果这两者都没有,您也许可以使用图形调试工具,例如 Nsight Graphics捕获并导出您想要的帧...

关于c++ - 从 OpenGL 应用程序中提取颜色/深度缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51347989/

相关文章:

c# - 在 emgucv 中应用 sobel 滤波器进行边缘检测

C++ OpenCV 做人脸识别,直到相机被移除

c++ - 为什么 GCC 只是通过将其置于循环中而被欺骗以允许未定义的行为?

Linux 运行级别 1 : start programm

linux - Nasm Linux x64-86 |在文件末尾添加位以进行正确的 base 64 编码

c - 你将如何解决这个 opengl 必要性(在 c 中),涉及知道用户点击了棋盘游戏中的哪个方 block ?

c++ - 获取标题栏文字大小 WINAPI

linux - 将 tmpfs 视为 grep 的设备

c++ - 如何用OpenGl绘制动函数图?

c++ - 同时将单个缓冲区绑定(bind)到 SSBO 的多个索引目标