Solved My EndScene Hook Isn't Being Called :\

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
So this has been my first delve into hooking of any kind and I decided to start with the good ol' VMT EndScene hook on the d3d9 module. Now, in memory I can look at the VTable and see that the pointer has in fact been swapped and is pointing to my module, yet it's not being called ( I debugged and placed BPs to verify ).

C++:
typedef HRESULT ( WINAPI* EndScene_t ) ( LPDIRECT3DDEVICE9 pDevice );
EndScene_t OriginalEndscene;

LPD3DXFONT pFont;

HRESULT WINAPI hkEndScene ( LPDIRECT3DDEVICE9 device ) {

	if ( !fontCreated ) {
		D3DXCreateFont ( device , 16 , 0 , FW_BOLD , 0 , 0 , 1 , 0 , 0 , 0 | FF_DONTCARE , "Arial" , &pFont );
		fontCreated = true;
	}

	RECT rFont{ 10, 10, 150, 150 };
	pFont->DrawTextA ( NULL , "Test" , -1 , &rFont , DT_LEFT , D3DCOLOR_RGBA ( 255 , 0 , 0 , 255 ) );

	return OriginalEndscene ( device );
}

DWORD WINAPI MainThread ( LPVOID lpParam ) {

	AllocConsole ();
	freopen ( "CONOUT$" , "w" , stdout );

	MODULEINFO d3d9Mod = GetModuleInfo ( "d3d9.dll" );
	DWORD* vTable = *( DWORD** ) ( FindPattern ( ( PBYTE ) d3d9Mod.lpBaseOfDll , d3d9Mod.SizeOfImage , "C7 06 ? ? ? ? 89 86 ? ? ? ? 89 86 ? ? ? ? 89 86 ? ? ? ? 89 86 ? ? ? ? 89 86 ? ? ? ?" ) + 2 );

	std::cout << "vTable: " << std::hex << vTable << std::endl;
	std::cout << "EndScene: " << std::hex << vTable [ 42 ] << std::endl;

	VMTHook hook ( vTable , 42 );
	OriginalEndscene = ( EndScene_t ) hook.ToggleHook ( 42 , ( DWORD ) hkEndScene );

	for ( ;; ) {
		if ( GetAsyncKeyState ( VK_DELETE ) )
			break;
		Sleep ( 150 );
	}

	std::cout << "Bye!" << std::endl;

	hook.~VMTHook ();
	FreeConsole ();
	FreeLibraryAndExitThread ( ( HMODULE ) lpParam , EXIT_SUCCESS );
	return 0;
}
I'm using the VMT class that Solaire posted to do the actual hooking, but like I said the pointer gets swapped just fine.
Any idea what my problem is?
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,295
37,938
269
If the pointer's swapped and nothings called then you most likely have a game that doesn't use it.

For example rainbow 6 siege loads d3d9 but it only uses d3d11, and wont allow the game to run if your hardware cant support d3d11 but can support d3d9
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
That would make sense if I was using a D3D11 game to test it, but I'm actually hooking a D3D9 Test Environment, so I'd assume that isn't the issue :\
 

till0sch

Respected Hacker
Dank Tier VIP
Dank Tier Donator
Oct 14, 2012
1,104
12,593
51
well we know nothing about that class you use
why not just use detours directly?
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
well we know nothing about that class you use
why not just use detours directly?
The class was linked in the original post, it's just takes a pointer to a vTable and swaps the pointer at the specified index. I've actually changed my implementation to do it manually but I have also figured out the problem. Despite me swapping the pointer, the original EndScene function is still being called, according to what I've read this is because I'm not hooking early enough... So now I have to figure how to either hook as early as possible OR figure out a way to force the module to scan the vTable again. I've tried to have my injector suspend all of the program's threads on launch, inject, and resume the threads but still to no avail :(

My new hook code btw:
C++:
void HookEndScene () {

	MODULEINFO d3d9Mod = GetModuleInfo ( "d3d9.dll" );
	DWORD* oTablePtr = ( DWORD* ) ( FindPattern ( ( PBYTE ) d3d9Mod.lpBaseOfDll , d3d9Mod.SizeOfImage , "C7 06 ? ? ? ? 89 86 ? ? ? ? 89 86" ) + 2 );
	DWORD* myTable = ( DWORD* ) malloc ( 0x1D8 );
	DWORD ogPointer = *( DWORD* ) ( *oTablePtr + 0xA8 ); // Original EndScene function pointer

        // Copy the original VMT to my own memory space
	memcpy ( myTable , *( void** ) oTablePtr , 0x1D8 );

        // Make the VMT pointer point to my VMT instead of the original
	DWORD prot = 0;
	VirtualProtect ( oTablePtr , 4 , PAGE_EXECUTE_READWRITE , &prot );
	*oTablePtr = ( DWORD ) myTable;
	VirtualProtect ( oTable , 4 , prot , &prot );
        
        // Change my VMT's EndScene pointer to my hook
	myTable [ 42 ] = ( DWORD ) hkEndScene;
}
This actually copies the original VMT to my own VMT and swaps the pointer to the original VMT to mine, and then I simply change my VMT's EndScene pointer to my hook; from what I've read this is supposed to be more VAC-safe and VAC is also the reason I'm not using Detours.
 
Last edited:

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,295
37,938
269
"*oTablePtr = ( DWORD ) myTable;"

if oTablePtr is the vtable ptr, then derefing it is the first function.

You'd want oTablePtr = ( Dword ) myTable
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
I appreciate the tip, but I can promise you that's not the problem. ( See below image ) Like I said in my other post, I'm like 90% sure my problem is with the timing of the hook; suspending threads via my own injector and injecting didn't seem to work either though so I'm not sure what to do.

 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,295
37,938
269
I'm 99% sure that is your problem mate.

Unless whatever game you're using does it better than 90% of all games and stores the end scene pointer it's simply that you aren't hooking the right thing, showing me that in reclass doesn't help without showing me the full vtable up until index 42/43.

Also before i forget, vmt hooking isn't more vac safe, you could just as easily byte patch it if you wanted to
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
I'm not modifying the original VTable fam... I'm making a copy of it in my own module and redirecting the pointer to point to my VTable instead of the original; I then changed the 42nd pointer in my copied VTable to point to my hook.
For added kicks, I modified the original VTable too and xxxx still doesn't draw...
 
Last edited:

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
I'm not modifying the original VTable fam... I'm making a copy of it in my own module and redirecting the pointer to point to my VTable instead of the original; I then changed the 42nd pointer in my copied VTable to point to my hook.
For added kicks, I modified the original VTable too and xxxx still doesn't draw...
If you are using d3dx9 features, you will find that things do not draw (I had this issue previously). Make sure that the test environment even uses them if you're trying to draw with them.
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
If you are using d3dx9 features, you will find that things do not draw (I had this issue previously). Make sure that the test environment even uses them if you're trying to draw with them.
Thanks for the info, but my hook isn't even being called :\ I tossed a cout in there and nothing is thrown into the console unless I manually call the function.
 

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
dude, i assume that you need to enter the function list first :p
->
C++:
vTable = (DWORD*)vTable[0];



anyways its much easier to create a childwindow, extract the device from it [ means to put a pointer on it ] and destroy the child-window instead of this pattern stuff for hooking dx9 o_O
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
dude, i assume that you need to enter the function list first :p
->
C++:
vTable = (DWORD*)vTable[0];



anyways its much easier to create a childwindow, extract the device from it [ means to put a pointer on it ] and destroy the child-window instead of this pattern stuff for hooking dx9 o_O
Thanks for the reply, if you looked at the pics in my last post I've accessed the VMT just fine; so the actual pointer swapping isn't the issue.

I've not seen the method you mentioned. Assuming I get the device pointer though, isn't it imperative that drawing be done somewhere between Present and EndScene? So how would I go about drawing with just a device pointer?
 

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
Thanks for the reply, if you looked at the pics in my last post I've accessed the VMT just fine; so the actual pointer swapping isn't the issue.

I've not seen the method you mentioned. Assuming I get the device pointer though, isn't it imperative that drawing be done somewhere between Present and EndScene? So how would I go about drawing with just a device pointer?
over the child window as i said :3

C++:
DWORD GetDx9VtableFunction(int index)
{
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "DX", NULL };   // create window class
	RegisterClassEx(&wc); //register it
	HWND hWnd = CreateWindow("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL); // create child window 
	LPDIRECT3D9 pD3D = Direct3DCreate9(D3D_SDK_VERSION); //create d3d object
	D3DPRESENT_PARAMETERS d3dpp; // self-explaining ..
	ZeroMemory(&d3dpp, sizeof(d3dpp));//..
	d3dpp.Windowed = TRUE;//..
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//..
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;//..  
	LPDIRECT3DDEVICE9 pd3dDevice; //create the device as i said
	pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice);// fill it with info
	DWORD* pVTable = (DWORD*)pd3dDevice; //set a pointer on it , as i said
	pVTable = (DWORD*)pVTable[0]; // baaam here is the entry for function list
	DWORD Foo = pVTable[index];  // sir index tells us which function we want
	DestroyWindow(hWnd); // we dont need the child anymore, lets kill it ];D

	return Foo; // return the function mr pointerino
}



edit: 80% of that is the normal way to setup a d3d9 window for normal painting and 20% is kinda hook the vtable lelele
 
Last edited:

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
over the child window as i said :3

C++:
DWORD GetDx9VtableFunction(int index)
{
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "DX", NULL };   // create window class
	RegisterClassEx(&wc); //register it
	HWND hWnd = CreateWindow("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL); // create child window 
	LPDIRECT3D9 pD3D = Direct3DCreate9(D3D_SDK_VERSION); //create d3d object
	D3DPRESENT_PARAMETERS d3dpp; // self-explaining ..
	ZeroMemory(&d3dpp, sizeof(d3dpp));//..
	d3dpp.Windowed = TRUE;//..
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//..
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;//..  
	LPDIRECT3DDEVICE9 pd3dDevice; //create the device as i said
	pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice);// fill it with info
	DWORD* pVTable = (DWORD*)pd3dDevice; //set a pointer on it , as i said
	pVTable = (DWORD*)pVTable[0]; // baaam here is the entry for function list
	DWORD Foo = pVTable[index];  // sir index tells us which function we want
	DestroyWindow(hWnd); // we dont need the child anymore, lets kill it ];D

	return Foo; // return the function mr pointerino
}



edit: 80% of that is the normal way to setup a d3d9 window for normal painting and 20% is kinda hook the vtable lelele
Isn't this just returning the address of the function at pointed to by a specified VTable index? My implementation with pattern scanning gave me the same address and it's less ass-pain. Perhaps I'm misunderstanding what to use this code for?
 

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
Isn't this just returning the address of the function at pointed to by a specified VTable index? My implementation with pattern scanning gave me the same address and it's less ass-pain. Perhaps I'm misunderstanding what to use this code for?
yes, it returns its adress, then you can just use detour as common and in my opinion is this better than making a pattern etc

C++:
oEndScene = (tEndScene)DetourFunction((PBYTE)GetDx9VtableFunction(42), (PBYTE)hkEnd);
because in that snippet you just need to change the value and you can do it with all functions which are listed, some ppl just overdo it with hooking classes
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
yes, it returns its adress, then you can just use detour as common and in my opinion is this better than making a pattern etc

C++:
oEndScene = (tEndScene)DetourFunction((PBYTE)GetDx9VtableFunction(42), (PBYTE)hkEnd);
because in that snippet you just need to change the value and you can do it with all functions which are listed, some ppl just overdo it with hooking classes
Cool, cool. Honestly though, for D3D9 you can condense all of that into four lines of code with sig scanning.
Your method seems a bit overkill to me, but hey, it works so I won't knock it :)

C++:
DWORD GetD3DFunc ( int index ) {
	return ( *( DWORD** ) ( FindPattern ( ( PBYTE ) GetModuleHandle ( "d3d9.dll" ) , 0xFFFFF , "C7 06 ? ? ? ? 89 86 ? ? ? ? 89 86" ) + 2 ) ) [ index ];
}
Edit: Also forgot to mention, I'd rather not use Detours since I'm dealing with VAC and from what I've read on UC that xxxx is detected. I'm not sure if the method itself is detected or just MS Detours. If it's the latter I'll look into just writing my own Detour function.
 
Last edited:

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
Cool, cool. Honestly though, for D3D9 you can condense all of that into four lines of code with sig scanning.
Your method seems a bit overkill to me, but hey, it works so I won't knock it :)

C++:
DWORD GetD3DFunc ( int index ) {
	DWORD* vTable = *( DWORD** ) ( FindPattern ( ( PBYTE ) GetModuleHandle ( "d3d9.dll" ) , 0xFFFFF , "C7 06 ? ? ? ? 89 86 ? ? ? ? 89 86" ) + 2 );
	return vTable [ index ];
}
Edit: Also forgot to mention, I'd rather not use Detours since I'm dealing with VAC and from what I've read on UC that xxxx is detected. I'm not sure if the method itself is detected or just MS Detours. If it's the latter I'll look into just writing my own Detour function.
well, the dx9 file might not change that fast, but i already saw ppl updating their patterns, this way removes that :)
and in case of detour, you can just replace the line where its used with your own func and it would still work hewhew :p

I never had problems with detours tbh, maybe because i never set my hacks public as long i use them privately xD
 

TheHylianTimelord

Newbie
Full Member
Jan 27, 2013
11
268
0
Welp, I got drawing working just fine with a detour. I'd really like to know why my VMT wasn't working though :[

 
Last edited:

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
Welp, I got drawing working just fine with a detour. I'd really like to know why my VMT wasn't working though :[

looks nice x)

well maybe there is a bug in the hooking class o_O try do hook before you do togglehook, and check the adresses and compare them :) (your version.adresses |my version.adresses | his version.adressses)
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods