0

所以最近我想使用 DirectX 向示例窗口添加一个 imgui 界面,所以我观看了一个视频,我必须使用 DirectX9sdk 挂钩 EndScene 功能才能添加我的自定义 imgui 界面。

但是我有一些问题:

  1. 我在哪里可以找到 DirectX9 函数和类型的任何文档(如果有的话,因为我不明白为什么我们特别要挂钩 EndScene 函数)或者我在哪里可以找到任何文章更深入地解释 DirectX 的工作原理?
  2. 到目前为止,我已经看到了 EndScene 挂钩的两个版本,一个带有 patternScanning 函数,它扫描 shaderapi dll 中的签名,另一个创建 DirectXDevice,然后从那里访问 vtable;网上有没有资源,还是我们必须自己做的事情?这是我的版本:
while (!DirectXDevice) // loops until it finds the device
        DirectXDevice = **(DWORD**)(FindPattern("shaderapidx9.dll", "A1 ?? ?? ?? ?? 50 8B 08 FF 51 0C") + 0x1);

    void** pVTable = *reinterpret_cast<void***>(DirectXDevice); // getting the vtable array
    oEndScene = (f_EndScene)DetourFunction((PBYTE)pVTable[42], (PBYTE)Hooked_EndScene)//getting the 42th virtual function and detouring it to our own
  1. 我真的不明白 __stdcall 在这里做什么,我知道它是用来调用 WINAPI 函数的,但这里有什么用呢?
HRESULT __stdcall Hooked_EndScene(IDirect3DDevice9* pDevice){//some code}

注意:这就是我挂钩到原始端场景的功能。

非常感谢,如果有很多问题,我很抱歉,但我真的无法解决这个问题。

4

1 回答 1

1

你怎么知道你需要挂钩哪些函数?

说白了,你必须是一位经验丰富的 DirectX 图形程序员才能发现这一点。不要期望能够连接到您不了解的框架中。碰巧EndScene总是在渲染目标上的所有其他绘制调用之后调用它。

有大量可用的 D3D9 编程资源,在线和纸质形式。他们中的大多数不是免费的。恐怕这不是您希望的答案。

图案扫描或创建临时 D3D9 设备有什么用?

微软没有做出任何明确的努力来制作可EndScene挂钩的。它恰好是可挂钩的,因为每个正常功能都是可挂钩的。您需要一种在内存中查找函数的方法,因为函数不会总是在同一个地址。

一种方法是扫描函数内部出现的已知指令。需要有人成为第一个找出您可以扫描的模式的人。你远不是第一个钩子的人EndScene,很多人之前都对这个功能进行了逆向工程,并分享了可搜索的模式。

注意:模式不一定需要直接在目标函数内部。在您的情况下,它也可能首先引导您找到其他东西,即ID3D9Device实例。重要的是,您可以以EndScene某种方式找到实现该功能的方法。

另一种方法是获取指向函数的指针。如果它是一个常规的 C 函数,那就很容易了。这很困难,因为 OOP 往往会使这些事情变得困难——你必须通过各种接口来争取正确的 vtable。

这两种方法都有优点和缺点——创建 D3D9 设备更安全,但也更具侵入性,因为目标进程可能不会期望某人只是随机创建新设备。

为什么需要钩子函数__stdcall

由于您将原始函数替换为挂钩版本,因此挂钩函数的调用约定必须与原始函数的调用约定相同。调用者EndScene期望(并且被编译)__stdcall约定,因此新函数也必须以相同的方式运行,否则堆栈将被破坏。您替换函数的行为不会改变调用者调用它的方式。

于 2020-04-19T15:24:31.450 回答