2010-03-01 4 views
3

Fraps 형식 프로그램을 만들려고합니다. 실패한 부분에 대한 설명을 참조하십시오.C++ d3d 후킹 - 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; 
} 

답변

5

IDirect3D9::CreateDevice의 C 인터페이스에 대한 서명은 다음과 같습니다

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

로 확장 어떤 : 다른 말로하면

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

, 당신은 잘못 CreateDevice의 썽크를 선언했다.

또한, 대신 직접 IDirect3D9 VTABLE로 색인, 당신은 단지 #define CINTERFACE하려는 당신이 d3d->lpVtbl->CreateDevice을 무시하려는 기능에 액세스 할 수 있습니다.

+0

굉장! 그것은 작동합니다! 고맙습니다. – Mango

+0

@Mango, 항상 답을 받아 들일 수도 있습니다 :) – MSN

+0

죄송합니다. 요즘 등록이 저를 위해 작동하지 않았습니다. 등록하고 답변을 수락했습니다. 다시 한번 감사드립니다. – Mango