c++ - 为什么 DirectX Device Present Hook 无法绕道工作?

标签 c++ windows x86 directx-9 detours

我正在创建一个 Hook ,该 Hook 将允许从 Direct X 9 设备 Hook Present 方法,

我这样做:

#include <windows.h>
#include <detours.h>
#include <iostream>
#include <d3d9.h>

#pragma comment( lib, "d3d9.lib"   )


typedef HRESULT(PresentDef)(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion);
PresentDef* Real_Present;
PresentDef Mine_Present;

HRESULT Mine_Present(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion)
{
    return Real_Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

BOOL WINAPI DetoursInit(HINSTANCE, DWORD dwReason, LPVOID) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:

        LoadLibrary("d3d9.dll");

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        Real_Present = (PresentDef*)DetourFindFunction("d3d9.dll", "IDirect3DDevice9::Present");
        DetourAttach(&(PVOID &)Real_Present, Mine_Present);

        if (ERROR_SUCCESS != DetourTransactionCommit())
        {
            MessageBoxA(NULL, "Failed to Detour", "ERROR", 0);
            break;
        }
        break;

    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID &)Real_Present, Mine_Present);
        DetourTransactionCommit();
        break;
    }

    return TRUE;
}

但每次执行此操作时,我都会收到无法绕道消息。

有什么办法可以绕开微软的弯道纯虚拟成员(member)吗?

最佳答案

我不会提供任何代码示例。这是一个高级主题,您应该自己进行研究。 您可以下载《黑暗之魂》的 DSFix 源代码并查看。这将为您提供一个良好的起点。链接:http://blog.metaclassofnil.com/?tag=dsfix

基本思想是,您正在绕过“COM 对象”而不是“纯函数”。考虑“d3d9::IDirect3DDevice9::Present”与“d3d9::Present”。

在后一种情况下,使用您的方法绕道不会有任何问题。 Detours 知道 d3d9.dll 的入口点/地址,即“d3d9”,以及入口点/地址和函数 Present(),即“d3d9::Present”。

但是,由于 Direct3D 使用“COM 模型”,因此需要某种方式来引用“COM 对象”,在本例中为“IDirect3DDevice9”(Direct3D 设备的接口(interface))。为此,您可以通过函数 Direct3DCreate9 创建您自己的绕道 Direct3DDevice9 对象,该对象不是“COM 对象”,而是创建您需要引用 Present() 函数的“COM 对象”。因此,您应该绕道“d3d9::Direct3DCreate9”,这将创建一个设备对象(我们称之为 device9),您可以将其存储在代码中。然后您可以绕过 device9->Present 函数。

希望这是有道理的。 Detours 3 还提供了一些绕过 COM 的其他方法的示例。安装 detours 后,它们位于“Samples”文件夹中。还有类似的教程:http://forum.cheatengine.org/viewtopic.php?t=161045这使用旧版本的 detours 1.5。但总体方法是相同的。

关于c++ - 为什么 DirectX Device Present Hook 无法绕道工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22432546/

相关文章:

C++ 'vector' 未在此范围内声明

c++ - 您可以在 c 或 c++ 中分配一个非常大的单个内存块(> 4GB)吗?

c++ - 为什么在重定向 stdout 和 stdin 时 Python 的行为不符合预期?

c - 在 C 中截断文件

c - 简单 C Bootstrap /内核的问题

c++ - 使用临时初始化多个成员

c++ - GSL统计,什么是stride?

c - 用于套接字 SSL 的 Windows API

c - Linux asm ("int $0x0") 与除以零

gcc - ASM : too many memory references for `mov'