2010-03-01 41 views
3

Essayer de créer un programme de type Fraps. Voir le commentaire pour où il échoue.C++ d3d hooking - COM vtable

#include "precompiled.h" 

typedef IDirect3D9* (STDMETHODCALLTYPE* Direct3DCreate9_t)(UINT SDKVersion); 
Direct3DCreate9_t RealDirect3DCreate9 = NULL; 

typedef HRESULT (STDMETHODCALLTYPE* CreateDevice_t)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface); 
CreateDevice_t RealD3D9CreateDevice = NULL; 

HRESULT STDMETHODCALLTYPE HookedD3D9CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface) 
{ 
    // this call makes it jump to HookedDirect3DCreate9 and crashes. i'm doing something wrong 
    HRESULT ret = RealD3D9CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, 
     pPresentationParameters, ppReturnedDeviceInterface); 

    return ret; 
} 

IDirect3D9* STDMETHODCALLTYPE HookedDirect3DCreate9(UINT SDKVersion) 
{ 
    MessageBox(0, L"Creating d3d", L"", 0); 

    IDirect3D9* d3d = RealDirect3DCreate9(SDKVersion); 

    UINT_PTR* pVTable = (UINT_PTR*)(*((UINT_PTR*)d3d)); 
    RealD3D9CreateDevice = (CreateDevice_t)pVTable[16]; 

    DetourTransactionBegin(); 
    DetourUpdateThread(GetCurrentThread()); 
    DetourAttach(&(PVOID&)RealD3D9CreateDevice, HookedD3D9CreateDevice); 
    if (DetourTransactionCommit() != ERROR_SUCCESS) 
    { 
     MessageBox(0, L"failed to create createdev hook", L"", 0); 
    } 

    return d3d; 
} 

bool APIENTRY DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved) 
{ 
    if (fdwReason == DLL_PROCESS_ATTACH) 
    { 
     MessageBox(0, L"", L"", 0); 

     RealDirect3DCreate9 = (Direct3DCreate9_t)GetProcAddress(GetModuleHandle(L"d3d9.dll"), "Direct3DCreate9"); 

     DetourTransactionBegin(); 
     DetourUpdateThread(GetCurrentThread()); 
     DetourAttach(&(PVOID&)RealDirect3DCreate9, HookedDirect3DCreate9); 
     DetourTransactionCommit(); 
    } 

    // TODO detach hooks 

    return true; 
} 

Répondre

5

La signature de l'interface C de IDirect3D9::CreateDevice est:

STDMETHOD(CreateDevice)(
    THIS_ 
    UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow, 
    DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface) PURE; 

qui se développe pour:

typedef HRESULT (STDMETHODCALLTYPE* CreateDevice_t)(
    IDirect3D9 FAR *This, // you forgot this. 
    UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, 
    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, 
    IDirect3DDevice9** ppReturnedDeviceInterface); 

En d'autres termes, vous avez déclaré le thunk pour CreateDevice de manière incorrecte. En outre, au lieu d'indexer directement dans le vtable IDirect3D9, vous pouvez simplement vouloir #define CINTERFACE et accéder à la fonction que vous souhaitez remplacer par d3d->lpVtbl->CreateDevice.

+0

Génial! Ça marche! Je vous remercie. – Mango

+0

@Mango, vous pouvez toujours accepter la réponse aussi :) – MSN

+0

Désolé, l'enregistrement ne fonctionnait pas pour moi l'autre jour. Enregistré et accepté la réponse. Merci encore. – Mango