1
Hello I have the following code snippet
#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#pragma comment(lib, "d3d8.lib")
#pragma comment(lib, "d3dx8.lib")
typedef HRESULT(WINAPI* CreateDevice_Prototype) (LPDIRECT3D8, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*);
typedef HRESULT(WINAPI* Reset_Prototype) (LPDIRECT3DDEVICE8, D3DPRESENT_PARAMETERS*);
typedef HRESULT(WINAPI* EndScene_Prototype) (LPDIRECT3DDEVICE8);
typedef HRESULT(WINAPI* DrawIndexedPrimitive_Prototype)(LPDIRECT3DDEVICE8, D3DPRIMITIVETYPE, UINT, UINT, UINT, UINT);
CreateDevice_Prototype CreateDevice_Pointer = NULL;
Reset_Prototype Reset_Pointer = NULL;
EndScene_Prototype EndScene_Pointer = NULL;
DrawIndexedPrimitive_Prototype DrawIndexedPrimitive_Pointer = NULL;
HRESULT WINAPI CreateDevice_Detour(LPDIRECT3D8, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*);
HRESULT WINAPI Reset_Detour(LPDIRECT3DDEVICE8, D3DPRESENT_PARAMETERS*);
HRESULT WINAPI EndScene_Detour(LPDIRECT3DDEVICE8);
HRESULT WINAPI DrawIndexedPrimitive_Detour(LPDIRECT3DDEVICE8, D3DPRIMITIVETYPE, UINT, UINT, UINT, UINT);
PDWORD Direct3D_VMTable = NULL;
HRESULT WINAPI InstallD3DHook(VOID);
void ResetHook(LPDIRECT3DDEVICE8);
void EndSceneHook(LPDIRECT3DDEVICE8);
HRESULT WINAPI InstallD3DHook(VOID)
{
LPDIRECT3D8 Direct3D_Object = Direct3DCreate8(D3D_SDK_VERSION);
if (Direct3D_Object == NULL)
return D3DERR_INVALIDCALL;
Direct3D_VMTable = (PDWORD)*(PDWORD)Direct3D_Object;
Direct3D_Object->Release();
DWORD dwProtect;
if (VirtualProtect(&Direct3D_VMTable[15], sizeof(DWORD), PAGE_READWRITE, &dwProtect) != 0)
{
*(PDWORD)&CreateDevice_Pointer = Direct3D_VMTable[15];
*(PDWORD)&Direct3D_VMTable[15] = (DWORD)CreateDevice_Detour;
if (VirtualProtect(&Direct3D_VMTable[15], sizeof(DWORD), dwProtect, &dwProtect) == 0)
return D3DERR_INVALIDCALL;
}
else
return D3DERR_INVALIDCALL;
return D3D_OK;
}
which works perfectly, however, by using the same code within a class like the below:
#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#pragma comment(lib, "d3d8.lib")
#pragma comment(lib, "d3dx8.lib")
class Hook
{
private:
typedef HRESULT(WINAPI* CreateDevice_Prototype) (LPDIRECT3D8, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*);
typedef HRESULT(WINAPI* Reset_Prototype) (LPDIRECT3DDEVICE8, D3DPRESENT_PARAMETERS*);
typedef HRESULT(WINAPI* EndScene_Prototype) (LPDIRECT3DDEVICE8);
typedef HRESULT(WINAPI* DrawIndexedPrimitive_Prototype)(LPDIRECT3DDEVICE8, D3DPRIMITIVETYPE, UINT, UINT, UINT, UINT);
CreateDevice_Prototype CreateDevice_Pointer = NULL;
Reset_Prototype Reset_Pointer = NULL;
EndScene_Prototype EndScene_Pointer = NULL;
DrawIndexedPrimitive_Prototype DrawIndexedPrimitive_Pointer = NULL;
HRESULT WINAPI CreateDevice_Detour(LPDIRECT3D8, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*);
HRESULT WINAPI Reset_Detour(LPDIRECT3DDEVICE8, D3DPRESENT_PARAMETERS*);
HRESULT WINAPI EndScene_Detour(LPDIRECT3DDEVICE8);
HRESULT WINAPI DrawIndexedPrimitive_Detour(LPDIRECT3DDEVICE8, D3DPRIMITIVETYPE, UINT, UINT, UINT, UINT);
PDWORD Direct3D_VMTable = NULL;
public:
HRESULT WINAPI InstallD3DHook(VOID);
void ResetHook(LPDIRECT3DDEVICE8);
void EndSceneHook(LPDIRECT3DDEVICE8);
};
HRESULT WINAPI Hook::InstallD3DHook(VOID)
{
LPDIRECT3D8 Direct3D_Object = Direct3DCreate8(D3D_SDK_VERSION);
if (Direct3D_Object == NULL)
return D3DERR_INVALIDCALL;
Direct3D_VMTable = (PDWORD)*(PDWORD)Direct3D_Object;
Direct3D_Object->Release();
DWORD dwProtect;
if (VirtualProtect(&Direct3D_VMTable[15], sizeof(DWORD), PAGE_READWRITE, &dwProtect) != 0)
{
*(PDWORD)&CreateDevice_Pointer = Direct3D_VMTable[15];
*(PDWORD)&Direct3D_VMTable[15] = (DWORD)CreateDevice_Detour;
if (VirtualProtect(&Direct3D_VMTable[15], sizeof(DWORD), dwProtect, &dwProtect) == 0)
return D3DERR_INVALIDCALL;
}
else
return D3DERR_INVALIDCALL;
return D3D_OK;
}
i get the following error on line:
(PDWORD)&Direct3d_vmtable[15] = (DWORD)Createdevice_detour;
logo in the cast (DWORD):
typdef unsigned long DWORD
conversão de tipo inválida
someone could explain to me the reason for such a mistake??
Possible duplicate of Pointer to method
– josuegomes
@josuegomes thanks for the help, but I did not understand how my problem, is similar to what you quoted.
– Renan Moura
Pointers to member functions cannot be used where pointers to free functions are used. Basically a pointer to a member function cannot be used without the object. You are trying to pass a pointer to a member function for Directx and Directx should call that pointer at some point. How will Directx know which object this member function applies to? There is no way. See more here: https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
– josuegomes
Excellent explanation, thanks again for the help friend
– Renan Moura
You will have to use a free function as an intermediate. The intermediate function is that it is assigned to
Direct3D_VMTable[15]
. The intermediate function then callshook.CreateDeviceDetour()
– josuegomes
Anyway it’s strange this architecture. Why do you want to use a class? C++ is a multi-paradigm language.
– josuegomes
thinking well is even strange haha , but whatever way, thank you very much for your time, all good friend.
– Renan Moura