Code:
#include <d3d9.h>
#include <d3dx9.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "detours.h"
bool init = false;//hook ready?
HMODULE D3D9Handle = NULL;
DWORD** VtablePtr = NULL;
DWORD** VTable = NULL;
ID3DXFont* pfont = NULL;
LPDIRECT3DDEVICE9 Device = NULL;
int globali = 0;
extern "C" typedef HRESULT (WINAPI* oPresent) (LPDIRECT3DDEVICE9, CONST RECT* ,CONST RECT* , HWND, CONST RGNDATA* );
extern "C" typedef HRESULT (WINAPI* oReset)(LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*);
oPresent pPresent = NULL;
oReset pReset = NULL;
HRESULT WINAPI myPresent(LPDIRECT3DDEVICE9 pDevice, CONST RECT* pSourceRect,CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion)
{
globali++;
char buf[20] = "\0";
if(!pfont)
{
D3DXCreateFontA(pDevice, //D3D Device
22, //Font height
0, //Font width
FW_NORMAL, //Font Weight
1, //MipLevels
false, //Italic
DEFAULT_CHARSET, //CharSet
OUT_DEFAULT_PRECIS, //OutputPrecision
ANTIALIASED_QUALITY, //Quality
DEFAULT_PITCH|FF_DONTCARE,//PitchAndFamily
"Arial", //pFacename,
&pfont); //ppFont
}
RECT font_rect;
SetRect(&font_rect,20,50,500,50+23);
pfont->DrawTextA(NULL, //pSprite
itoa(globali,buf,10), //your text
-1, //Count(-1 to disregard)
&font_rect, //pRect(controls positioning)
DT_LEFT|DT_NOCLIP, //Format (DT_WORDBREAK for wrapping)
0xFFFFFFFF); //Color (ARGB)
return pPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}
HRESULT WINAPI myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pParam)
{
//MessageBoxA(NULL,"In Reset","Report:", MB_OK);
HRESULT hr = NULL;
pfont->OnLostDevice();
hr = pReset(pDevice, pParam);
pfont->OnResetDevice();
return hr;
}
DWORD** FindDevice(DWORD Base,DWORD Len)
{
unsigned long i = 0, n = 0;
for( i = 0; i < Len; i++ )
{
if(*(BYTE *)(Base+i+0x00)==0xC7)n++;
if(*(BYTE *)(Base+i+0x01)==0x06)n++;
if(*(BYTE *)(Base+i+0x06)==0x89)n++;
if(*(BYTE *)(Base+i+0x07)==0x86)n++;
if(*(BYTE *)(Base+i+0x0C)==0x89)n++;
if(*(BYTE *)(Base+i+0x0D)==0x86)n++;
if(n == 6) return (DWORD**)
(Base + i + 2);n = 0;
}
return(0);
}
void Hook()
{ char buf[16] = "\0";
while(!init)Sleep(300);
D3D9Handle = GetModuleHandleA("d3d9.dll");
VtablePtr = FindDevice((DWORD)D3D9Handle,0x128000);
//MessageBoxA(NULL, itoa((int)VtablePtr, buf, 16), "Report:", MB_OK);
*(DWORD_PTR *)&VTable = *(DWORD_PTR *)VtablePtr;
//VTable = VtablePtr;
pPresent =(oPresent) VTable[17];
pReset = (oReset) VTable[16];
//MessageBoxA(NULL, itoa((int)pPresent, buf, 16), "Report: pPresent", MB_OK);//valid address!
//MessageBoxA(NULL, itoa((int)pReset, buf, 16), "Report: pReset", MB_OK);// 'ditto'
//DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//MessageBoxA(NULL, itoa((int)pPresent, buf, 16), "Report: pPresent", MB_OK);
DetourAttach(&(PVOID&)pPresent, myPresent);
DetourAttach(&(PVOID&)pReset, myReset);
DetourTransactionCommit();
//MessageBoxA(NULL,"I DID IT!", "Report:", MB_OK);
return;
}
void UnHook()
{
DetourDetach(&(PVOID&)VTable[17], &(PVOID&)myPresent);
DetourDetach(&(PVOID&)VTable[16], &(PVOID&)myReset);
return;
}
HINSTANCE lGetModuleHandle(CHAR *szModule)
{
HINSTANCE hModule = NULL;
if(!(hModule = GetModuleHandleA(szModule)) )
{
hModule = LoadLibraryA(szModule);
}return hModule;
}
void mainthread()
{
while(1)
{
Sleep(200);
}
}
void IsHookReady()
{
while((!GetModuleHandleA("d3d9.dll")))// || !GetModuleHandleA("ClientFX.fxd")|| !GetModuleHandleA("CShell.dll")))
{Sleep(200);}
init = true;
//MessageBoxA(NULL, "Modules loaded! Hooking...", "Report:", MB_OK);
return;
}
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
//DisableThreadLibraryCalls( hModule );
CreateThread(0,0,(LPTHREAD_START_ROUTINE)IsHookReady,0,0,0);
CreateThread( 0, 0, ( LPTHREAD_START_ROUTINE )Hook, 0, 0, 0 );
//MessageBoxA(NULL,"made it here","Debug",MB_OK);
//CreateThread( 0, 0, ( LPTHREAD_START_ROUTINE )mainthread, 0, 0, 0 );
break;
case DLL_PROCESS_DETACH:
MessageBoxA(NULL,"Breaks here.", "Report:", MB_OK);
DetourTransactionBegin();
UnHook();
DetourTransactionCommit();
break;
}
return TRUE;
}
I'll go into more details later, but for now I'll just say the problem was I did not declare oPresent and myPresent functions with the right calling convention. As you know I've been working on this since Friday so excuse, Im gonna go take a much needed break.