EndScene挂钩问题



所以最近我想用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}

注意:这是我挂接到原始结束场景的函数。

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

如何知道需要挂接哪些函数

坦率地说,你必须是一个经验丰富的DirectX图形程序员才能发现这一点。不要期望能够连接到一个你不理解的框架中。恰好EndScene总是在渲染目标上的所有其他绘制调用之后被调用。

D3D9有大量的在线和纸质编程资源,其中大部分都不是免费的。恐怕这不是你所希望的答案。

图案扫描或创建临时D3D9设备是怎么回事

微软并没有做出任何明确的努力使EndScene可以挂起。它只是恰好是可挂起的,因为每个正常函数都是可挂接的。您需要一种在内存中查找函数的方法,因为函数并不总是在同一地址。

一种方法是扫描出现在函数内部的已知指令。需要有人成为第一个发现你可以扫描的模式的人。您远不是第一个挂接EndScene的人,因此许多人之前已经对该功能进行了逆向工程,并共享了可搜索的模式。

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

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

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

为什么钩子函数需要__stdcall

由于您用钩住的版本替换了原始函数,因此钩住的函数的调用约定必须与原始函数的调用惯例相同。EndScene的调用方需要(并且使用(__stdcall约定进行编译,因此新函数的行为也必须相同,否则堆栈将损坏。你替换函数的行为不会改变调用者调用它的方式。

相关内容

  • 没有找到相关文章

最新更新