I got some more spare time to play with HadesMem and I threw this EndScene hook together. You need to inject this DLL at process creation for this hook to work since it hooks Direct3DCreate9 to get the IDirect3DDevice9 pointer.
Code:
// Windows API
#include <Windows.h>
#include <D3D9.h>
// C++ Standard Library
#include <cstdio>
#include <vector>
#include <string>
// Boost
#pragma warning(push, 1)
#include <boost/thread.hpp>
#pragma warning(pop)
// Hades
#include "HadesMem/Patcher.h"
std::shared_ptr<Hades::Memory::MemoryMgr> MyMemory;
std::shared_ptr<Hades::Memory::PatchDetour> MyPatch;
HRESULT EndScene_Hook(IDirect3DDevice9 *thisPtr)
{
typedef HRESULT (WINAPI *tEndScene)(IDirect3DDevice9 *);
static int frames=1;
if( ++frames == 100 )
{
OutputDebugString( L"HackDll: EndScene_Hook called 100 times.\n" );
frames = 1;
}
HRESULT hr = reinterpret_cast<tEndScene>(MyPatch->GetTrampoline())(thisPtr);
return hr;
}
HRESULT CreateDevice_Hook(IDirect3D9 *thisPtr,UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,
DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface)
{
typedef HRESULT (WINAPI *tCreateDevice)(IDirect3D9 *,UINT,D3DDEVTYPE,HWND,
DWORD, D3DPRESENT_PARAMETERS*, IDirect3DDevice9** );
OutputDebugString( L"HackDll: CreateDevice_Hook called." );
HRESULT hr = reinterpret_cast<tCreateDevice>(MyPatch->GetTrampoline())(thisPtr,
Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,
ppReturnedDeviceInterface);
if( SUCCEEDED(hr) )
{
MyPatch->Remove();
DWORD *pVMT = (DWORD *)(*(DWORD *)*ppReturnedDeviceInterface); // Get the vtable pointer
void *pEndScene = (void *)pVMT[42]; // Get pointer to EndScene
MyPatch.reset(new Hades::Memory::PatchDetour(*MyMemory, pEndScene, &EndScene_Hook));
MyPatch->Apply();
}
return hr;
}
IDirect3D9* WINAPI Direct3DCreate9_Hook(UINT SDKVersion)
{
typedef IDirect3D9* (WINAPI *tDirect3DCreate9)(UINT);
OutputDebugString( L"HackDll: Direct3DCreate9_Hook called." );
IDirect3D9* pD3D = reinterpret_cast<tDirect3DCreate9>(MyPatch->GetTrampoline())(SDKVersion);
if( NULL != pD3D )
{
MyPatch->Remove();
DWORD *pVMT = (DWORD *)(*(DWORD *)pD3D); // Get the vtable pointer
void *pCreateDevice = (void *)pVMT[16]; // Get pointer to CreateDevice
MyPatch.reset(new Hades::Memory::PatchDetour(*MyMemory, pCreateDevice, &CreateDevice_Hook));
MyPatch->Apply();
}
return pD3D;
}
extern "C" __declspec(dllexport) DWORD __stdcall Initialize(HMODULE Module)
{
try
{
// Break to debugger if present
if (IsDebuggerPresent())
{
DebugBreak();
}
OutputDebugString( L"HackDll: Initialize called." );
MyMemory.reset(new Hades::Memory::MemoryMgr(GetCurrentProcessId()));
HMODULE HookMod = GetModuleHandle(L"d3d9.dll");
MyPatch.reset(new Hades::Memory::PatchDetour(*MyMemory, GetProcAddress(
HookMod, "Direct3DCreate9"), &Direct3DCreate9_Hook));
MyPatch->Apply();
}
catch (boost::exception const& e)
{
// Dump error information
std::string str = "HackDll: ";
str += boost::diagnostic_information(e);
OutputDebugStringA(str.c_str());
}
catch (std::exception const& e)
{
// Dump error information
std::string str = "HackDll: ";
str += e.what();
OutputDebugStringA(str.c_str());
}
// Test return values
return 1337;
}
BOOL WINAPI DllMain(HINSTANCE /*hinstDLL*/, DWORD /*fdwReason*/,
LPVOID /*lpvReserved*/)
{
return TRUE;
}