D3D9 Hook problem [solved]

Posts 1–13 of 13 · Page 1 of 1
D3D9 Hook problem [solved]
I think it's hooking something because when I launch CA it just freezes. nothing comes up. It's like my .dll is stopping Combat Arms from launching. I would like to know if anyone might know what the problem might be. FYI: Im using Detours 2.1
Code:
include <d3d9.h>
#include <d3dx9.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "detours.h"
HMODULE D3D9Handle = NULL;
DWORD** VtablePtr = NULL;
DWORD* VTable = NULL;
ID3DXFont* pfont = NULL;

typedef HRESULT (*oPresent) (LPDIRECT3DDEVICE9, CONST RECT* ,CONST RECT* , HWND, CONST RGNDATA* );
typedef HRESULT (*oReset)(LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*);
oPresent pPresent = NULL;
oReset pReset = NULL;

HRESULT myPresent(LPDIRECT3DDEVICE9 pDevice, CONST RECT* pSourceRect,CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion)
{
	RECT font_rect;
		SetRect(&font_rect,20,50,500,50+23);
		pfont->DrawTextA(NULL,				//pSprite
                        "THATS THE WAY IT IS!",				//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 myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pParam)
{
	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(VOID)
{          
    D3D9Handle = GetModuleHandleA("d3d9.dll");
	VtablePtr = FindDevice((DWORD)D3D9Handle,0x128000);
    VTable = *VtablePtr;	
	pPresent = (oPresent)DetourAttach( &(PVOID&)VTable[17], myPresent);
	pReset   = (oReset)DetourAttach(&(PVOID&)VTable[16],myReset);

	D3DXCreateFontA((LPDIRECT3DDEVICE9)VtablePtr,     //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
}

void UnHook()
{
	DetourDetach(&(PVOID&)VTable[17], &(PVOID&)myPresent);
	DetourDetach(&(PVOID&)VTable[16], &(PVOID&)myReset);
	return;
}


void mainthread()
{
	while(1)
	{
		Sleep(200);
	}
}
		

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved)
{
	switch(dwReason)
	{
		case DLL_PROCESS_ATTACH:
			DisableThreadLibraryCalls( hModule );
			while((!GetModuleHandleA("d3d9.dll") || !GetModuleHandleA("ClientFX.fxd")|| !GetModuleHandleA("CShell.dll")))
			{Sleep(200);}//waiting for modules to load
			DetourTransactionBegin();
			DetourUpdateThread( GetCurrentThread() );
			Hook();
			DetourTransactionCommit();
			//CreateThread( 0, 0, ( LPTHREAD_START_ROUTINE )Hook, 0, 0, 0 );
			CreateThread( 0, 0, ( LPTHREAD_START_ROUTINE )mainthread, 0, 0, 0 );
			

		case DLL_PROCESS_DETACH:
			DetourTransactionBegin();
			UnHook();
			DetourTransactionCommit();

	}
}
The FindDevice() method is Croner's. Also thanks to Longevity for showing me. Please help, I think Im getting close, but I can't move on with my menu until I'm able to find a working hook to render text. Any advice is appreciated.

Also: If anyone has a spare D3D9 test environment laying around I could really use one. Since Im not sure what I did with mine... =/

Thanks.
Hmm, I'm not too sure. I have a question though, when declaring functions, is it automatically using the standard calling convention? If it isn't, you have to declare your type definitions __stdcall* oPresent etc.. Same for your function it's detouring to. HRESULT __stdcall Hook_Present.

Other than that, I don't see what the problem could be. Although, I've never used detours 2.1 before.

Edit: Oh, I may have found something, you create a detour on Present then you create the font. So, you're already trying to draw text while you haven't even created the font. You may want to fix that up.
Quote Originally Posted by Void View Post
Hmm, I'm not too sure. I have a question though, when declaring functions, is it automatically using the standard calling convention? If it isn't, you have to declare your type definitions __stdcall* oPresent etc.. Same for your function it's detouring to. HRESULT __stdcall Hook_Present.

Other than that, I don't see what the problem could be. Although, I've never used detours 2.1 before.

Edit: Oh, I may have found something, you create a detour on Present then you create the font. So, you're already trying to draw text while you haven't even created the font. You may want to fix that up.
Hmmm... good catch. I'll make sure it doesn't print anything till after all my detours are initialized.

And yes they're stdcall by default.
Umm, the way I made sure the font was created before starting to draw some text was something like:

[php]
HRESULT HookPresent(Params)
{
static bool font = true;
if(font)
{
CreateFontHere;
font = false;
}

DrawTextHere;
}
[/php]

Yeah, that's probably not the best way to do it. But, meh..
Okay I edited it and narrowed it down to this part:
Code:
 
void Hook()
{   
	while(!init)Sleep(300);
    D3D9Handle = GetModuleHandleA("d3d9.dll");
	VtablePtr = FindDevice((DWORD)D3D9Handle,0x128000);
    VTable = *VtablePtr;
	DetourTransactionBegin();
	DetourUpdateThread( GetCurrentThread() );
	pPresent = (oPresent)DetourAttach( &(PVOID&)VTable[17], myPresent);
	pReset   = (oReset)DetourAttach(&(PVOID&)VTable[16],myReset);
	DetourTransactionCommit();

	MessageBoxA(NULL,"Hook here", "Report:", MB_OK);// Makes it here

	D3DXCreateFontA((LPDIRECT3DDEVICE9)VtablePtr,     //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
	return;
}
I've been staring at code for hours now. Practically all day and I can't figure this damned thing out.

It fails when I get to createfont and I know it has something to do with VtablePtr.
Maybe you should try hooking the functions and leaving it to do nothing, just to see if it's the hook that's the problem.

Like:
[php]
HRESULT HookPresent(Params)
{
return pPresent(Params);
}
[/php]
Nope it's not the hooks. It's my detours... might be because Im using detours 2.1 I'll look into it more later. I've had enough debugging for one day... well fk its night now, but whatever...
Here's a test environment if you still need it.
test9.rarattachment deleted · 64 downloads before removal
The problem has been solved. Big thanks to learn_more, David, and even Volt for the D3D9 (debugging would have taken twice as long without it).
Did you edit the original code with the new solved one? If not, I'd like to know what the problem was. Not sure about anyone else. =\
Here's the fully working code. No errors as of yet.
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.
I TOLD YOU YOU HAD TO DECLARE THEM USING THE STANDARD CALLING CONVENTION AHHH

RAGEQUIT!
Quote Originally Posted by Void View Post
I TOLD YOU YOU HAD TO DECLARE THEM USING THE STANDARD CALLING CONVENTION AHHH

RAGEQUIT!
Hmmmm... seems you did :l, but I had tons of other problems at that time too, so I completely forgot what you said.
Posts 1–13 of 13 · Page 1 of 1
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?