我正在创建一个钩子,它允许从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
消息。
有没有办法绕过微软走弯路的纯虚拟会员?
答案 0 :(得分:3)
我不打算提供任何代码示例。这是一个高级主题,您应该自己做研究。 您可以下载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-&gt; Present功能。
希望这是有道理的。 Detours 3也有一些其他方法来绕行COM。安装绕道后,它们位于“Samples”文件夹中。还有一些教程如:http://forum.cheatengine.org/viewtopic.php?t=161045这使用旧版本的detours 1.5。但总的方法是一样的。