为啥 DirectX Device Present 钩子在弯路中不起作用?

Posted

技术标签:

【中文标题】为啥 DirectX Device Present 钩子在弯路中不起作用?【英文标题】:Why does the DirectX Device Present hook not work in detours?为什么 DirectX Device Present 钩子在弯路中不起作用? 【发布时间】:2014-03-16 03:18:23 【问题描述】:

我正在创建一个挂钩,它允许从 Direct X 9 设备挂钩 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;

但每次我这样做时,我都会收到Failed to detour 消息。

有没有办法让纯虚拟会员绕道微软的弯路?

【问题讨论】:

【参考方案1】:

我不会给出任何代码示例。这是一个高级主题,您应该自己进行研究。 您可以下载 DSFix for Dark Souls 的源代码并查看它。这会给你一个很好的起点。链接:http://blog.metaclassofnil.com/?tag=dsfix

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

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

但是,由于 Direct3D 使用“COM 模型”,因此需要某种方式来引用“COM 对象”,在本例中为“IDirect3DDevice9”(Direct3D 设备的接口)。为此,您可以通过函数 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。但是总体方法是相同的。

【讨论】:

以上是关于为啥 DirectX Device Present 钩子在弯路中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

“Device eth0 does not seem to be present”解决办法

device eth0 does not seem to be present, delaying initialization

Linux解决Device eth0 does not seem to be present

Centos 配置eth0 提示Device does not seem to be present

Centos 配置eth0 提示Device does not seem to be present

5.Linux解决Device eth0 does not seem to be present