diff --git a/.gitattributes b/.gitattributes index 686a95d..655c714 100644 --- a/.gitattributes +++ b/.gitattributes @@ -44,12 +44,16 @@ uMod_DXMain/uMod_ArrayHandler.cpp -text uMod_DXMain/uMod_ArrayHandler.h -text uMod_DXMain/uMod_DX10_dll_DIRECT_INJECTION.def -text uMod_DXMain/uMod_DX10_dll_HOOK_INJECTION.def -text +uMod_DXMain/uMod_DX9_10_dll_DIRECT_INJECTION.def -text uMod_DXMain/uMod_DX9_dll_DIRECT_INJECTION.def -text uMod_DXMain/uMod_DX9_dll_HOOK_INJECTION.def -text uMod_DXMain/uMod_DX9_dll_NO_INJECTION.def -text uMod_DXMain/uMod_DXMain_dll.cpp -text uMod_DXMain/uMod_DXMain_dll.h -text uMod_DXMain/uMod_Defines.h -text +uMod_DXMain/uMod_Detour.cpp -text +uMod_DXMain/uMod_Detour.h -text +uMod_DXMain/uMod_DetourEntry.h -text uMod_DXMain/uMod_Main.h -text uMod_DXMain/uMod_TextureClient.cpp -text uMod_DXMain/uMod_TextureClient.h -text diff --git a/uMod_DX10/uMod_DX10_dll.cpp b/uMod_DX10/uMod_DX10_dll.cpp index d74572e..1405433 100644 --- a/uMod_DX10/uMod_DX10_dll.cpp +++ b/uMod_DX10/uMod_DX10_dll.cpp @@ -34,15 +34,17 @@ along with Universal Modding Engine. If not, see /* * global variable which are not linked external */ +#if INJECTION_METHOD==NO_INJECTION HINSTANCE gl_hOriginal_DX10_Dll = NULL; HINSTANCE gl_hOriginal_DX101_Dll = NULL; +#endif +#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION typedef HRESULT (APIENTRY *D3D10CreateDeviceAndSwapChain_type)( IDXGIAdapter*, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D10Device**); typedef HRESULT (APIENTRY *D3D10CreateDeviceAndSwapChain1_type)( IDXGIAdapter*, D3D10_DRIVER_TYPE, HMODULE, UINT, D3D10_FEATURE_LEVEL1, UINT, DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D10Device1**); -#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION -D3D10CreateDeviceAndSwapChain_type D3D10CreateDeviceAndSwapChain_fn = NULL; -D3D10CreateDeviceAndSwapChain1_type D3D10CreateDeviceAndSwapChain1_fn = NULL; +uMod_Detour_Entry Detour_D3D10CreateDeviceAndSwapChain(5); +uMod_Detour_Entry Detour_D3D10CreateDeviceAndSwapChain1(5); #endif @@ -54,34 +56,46 @@ D3D10CreateDeviceAndSwapChain1_type D3D10CreateDeviceAndSwapChain1_fn = NULL; void InitDX10(void) { + +#if INJECTION_METHOD==NO_INJECTION LoadOriginal_DX10_Dll(); +#endif #if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION - // we detour the original D3D10CreateDeviceAndSwapChain to our uMod_D3D10CreateDeviceAndSwapChain - if (gl_hOriginal_DX10_Dll!=NULL) - { - D3D10CreateDeviceAndSwapChain_fn = (D3D10CreateDeviceAndSwapChain_type) GetProcAddress(gl_hOriginal_DX10_Dll, "D3D10CreateDeviceAndSwapChain"); - if (D3D10CreateDeviceAndSwapChain_fn!=NULL) - { - Message("Detour: D3D10CreateDeviceAndSwapChain\n"); - D3D10CreateDeviceAndSwapChain_fn = (D3D10CreateDeviceAndSwapChain_type)DetourFunc( (BYTE*)D3D10CreateDeviceAndSwapChain_fn, (BYTE*)uMod_D3D10CreateDeviceAndSwapChain, number_of_byte); - } - } - if (gl_hOriginal_DX101_Dll!=NULL) - { - D3D10CreateDeviceAndSwapChain1_fn = (D3D10CreateDeviceAndSwapChain1_type) GetProcAddress(gl_hOriginal_DX101_Dll, "D3D10CreateDeviceAndSwapChain1"); - if (D3D10CreateDeviceAndSwapChain1_fn!=NULL) - { - Message("Detour: D3D10CreateDeviceAndSwapChain1\n"); - D3D10CreateDeviceAndSwapChain1_fn = (D3D10CreateDeviceAndSwapChain1_type)DetourFunc( (BYTE*)D3D10CreateDeviceAndSwapChain1_fn, (BYTE*)uMod_D3D10CreateDeviceAndSwapChain1, 5); - } - } + char buffer[MAX_PATH]; + wchar_t buffer_w[MAX_PATH]; + GetSystemDirectory(buffer,MAX_PATH); //get the system directory, we need to open the original d3d9.dll + swprintf_s( buffer_w, MAX_PATH, L"%s\\d3d10.dll", buffer); + strcat_s( buffer, MAX_PATH,"\\d3d10.dll"); + + Detour_D3D10CreateDeviceAndSwapChain.SetFunctionName( "D3D10CreateDeviceAndSwapChain"); + Detour_D3D10CreateDeviceAndSwapChain.SetTargetFunction( uMod_D3D10CreateDeviceAndSwapChain); + Detour_D3D10CreateDeviceAndSwapChain.SetLibName( "d3d10.dll"); + Detour_D3D10CreateDeviceAndSwapChain.SetFullLibName( buffer); + Detour_D3D10CreateDeviceAndSwapChain.SetLibName( L"d3d10.dll"); // set also for wide character + Detour_D3D10CreateDeviceAndSwapChain.SetFullLibName( buffer_w); // set also for wide character + + GetSystemDirectory(buffer,MAX_PATH); //get the system directory, we need to open the original d3d9.dll + swprintf_s( buffer_w, MAX_PATH, L"%s\\d3d10_1.dll", buffer); + strcat_s( buffer, MAX_PATH,"\\d3d10_1.dll"); + + Detour_D3D10CreateDeviceAndSwapChain1.SetFunctionName( "D3D10CreateDeviceAndSwapChain1"); + Detour_D3D10CreateDeviceAndSwapChain1.SetTargetFunction( uMod_D3D10CreateDeviceAndSwapChain1); + Detour_D3D10CreateDeviceAndSwapChain1.SetLibName( "d3d10_1.dll"); + Detour_D3D10CreateDeviceAndSwapChain1.SetFullLibName( buffer); + Detour_D3D10CreateDeviceAndSwapChain1.SetLibName( L"d3d10_1.dll"); // set also for wide character + Detour_D3D10CreateDeviceAndSwapChain1.SetFullLibName( buffer_w); // set also for wide character + + GlobalDetour.AddEntry(&Detour_D3D10CreateDeviceAndSwapChain); + GlobalDetour.AddEntry(&Detour_D3D10CreateDeviceAndSwapChain1); + #endif } void ExitDX10(void) { +#if INJECTION_METHOD==NO_INJECTION // Release the system's d3d9.dll if (gl_hOriginal_DX10_Dll!=NULL) { @@ -94,7 +108,15 @@ void ExitDX10(void) FreeLibrary(gl_hOriginal_DX101_Dll); gl_hOriginal_DX101_Dll = NULL; } +#endif + +#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION +#endif } + + + +#if INJECTION_METHOD==NO_INJECTION void LoadOriginal_DX10_Dll(void) { char buffer[MAX_PATH]; @@ -119,8 +141,6 @@ void LoadOriginal_DX10_Dll(void) } - -#if INJECTION_METHOD==NO_INJECTION /* * We do not inject, the game loads this dll by itself thus we must include the Direct3DCreate9 function */ @@ -254,10 +274,8 @@ HRESULT APIENTRY uMod_D3D10CreateDeviceAndSwapChain( ID3D10Device **ppDevice ) { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginal_DX10_Dll, "D3D10CreateDeviceAndSwapChain"), (BYTE*)D3D10CreateDeviceAndSwapChain_fn, number_of_byte); - D3D10CreateDeviceAndSwapChain_fn = (D3D10CreateDeviceAndSwapChain_type) GetProcAddress( gl_hOriginal_DX10_Dll, "D3D10CreateDeviceAndSwapChain"); - - HRESULT ret = D3D10CreateDeviceAndSwapChain_fn(pAdapter,DriverType,Software,Flags,SDKVersion,pSwapChainDesc, ppSwapChain, ppDevice); + Detour_D3D10CreateDeviceAndSwapChain.Retour(); + HRESULT ret = Detour_D3D10CreateDeviceAndSwapChain.Function()(pAdapter,DriverType,Software,Flags,SDKVersion,pSwapChainDesc, ppSwapChain, ppDevice); if (ret==S_OK) { uMod_ID3D10Device *dev = new uMod_ID3D10Device( *ppDevice, gl_TextureServer); @@ -270,7 +288,7 @@ HRESULT APIENTRY uMod_D3D10CreateDeviceAndSwapChain( } } else Message("D3D10CreateDeviceAndSwapChain: Failed\n"); - D3D10CreateDeviceAndSwapChain_fn = (D3D10CreateDeviceAndSwapChain_type)DetourFunc( (BYTE*)D3D10CreateDeviceAndSwapChain_fn, (BYTE*)uMod_D3D10CreateDeviceAndSwapChain, number_of_byte); + Detour_D3D10CreateDeviceAndSwapChain.Detour(); return ret; } @@ -286,10 +304,8 @@ HRESULT APIENTRY uMod_D3D10CreateDeviceAndSwapChain1( ID3D10Device1 **ppDevice ) { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginal_DX101_Dll, "D3D10CreateDeviceAndSwapChain1"), (BYTE*)D3D10CreateDeviceAndSwapChain1_fn, 5); - D3D10CreateDeviceAndSwapChain1_fn = (D3D10CreateDeviceAndSwapChain1_type) GetProcAddress( gl_hOriginal_DX101_Dll, "D3D10CreateDeviceAndSwapChain1"); - - HRESULT ret = D3D10CreateDeviceAndSwapChain1_fn(pAdapter,DriverType,Software,Flags,HardwareLevel,SDKVersion,pSwapChainDesc, ppSwapChain, ppDevice); + Detour_D3D10CreateDeviceAndSwapChain1.Retour(); + HRESULT ret = Detour_D3D10CreateDeviceAndSwapChain1.Function()(pAdapter,DriverType,Software,Flags,HardwareLevel,SDKVersion,pSwapChainDesc, ppSwapChain, ppDevice); if (ret==S_OK) { uMod_ID3D10Device1 *dev = new uMod_ID3D10Device1( *ppDevice, gl_TextureServer); @@ -302,9 +318,7 @@ HRESULT APIENTRY uMod_D3D10CreateDeviceAndSwapChain1( } } else Message("D3D10CreateDeviceAndSwapChain1: Failed\n"); - - D3D10CreateDeviceAndSwapChain1_fn = (D3D10CreateDeviceAndSwapChain1_type)DetourFunc( (BYTE*)D3D10CreateDeviceAndSwapChain1_fn, (BYTE*)uMod_D3D10CreateDeviceAndSwapChain1, 5); - + Detour_D3D10CreateDeviceAndSwapChain1.Detour(); return (ret); } diff --git a/uMod_DX10/uMod_DX10_dll.h b/uMod_DX10/uMod_DX10_dll.h index 14201cc..169b731 100644 --- a/uMod_DX10/uMod_DX10_dll.h +++ b/uMod_DX10/uMod_DX10_dll.h @@ -23,10 +23,17 @@ along with Universal Modding Engine. If not, see #include "../uMod_DXMain/uMod_Main.h" -void LoadOriginal_DX10_Dll(void); void InitDX10(); void ExitDX10(); +#if INJECTION_METHOD==NO_INJECTION +/** + * Load the official d3d10.dll from the system path. + */ +void LoadOriginal_DX10_Dll(void); +#endif + + #if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION HRESULT APIENTRY uMod_D3D10CreateDeviceAndSwapChain( diff --git a/uMod_DX10/uMod_IDXGISwapChain.cpp b/uMod_DX10/uMod_IDXGISwapChain.cpp index fd3c421..02fbdcd 100644 --- a/uMod_DX10/uMod_IDXGISwapChain.cpp +++ b/uMod_DX10/uMod_IDXGISwapChain.cpp @@ -23,7 +23,7 @@ along with Universal Modding Engine.If not, see . uMod_IDXGISwapChain::uMod_IDXGISwapChain(IDXGISwapChain *pOriginal, uMod_ID3D10Device *dev) { - Message( "IDXGISwapChain::IDXGISwapChain( %lu, %lu): %lu\n", pOriginal, dev, this); + Message( "uMod_IDXGISwapChain::uMod_IDXGISwapChain( %lu, %lu): %lu\n", pOriginal, dev, this); m_IDXGISwapChain = pOriginal; u_ID3D10Device = dev; RefCounter = 1; @@ -37,7 +37,7 @@ uMod_IDXGISwapChain::~uMod_IDXGISwapChain() HRESULT STDMETHODCALLTYPE uMod_IDXGISwapChain::QueryInterface( REFIID riid, void** ppvObject) { *ppvObject = NULL; - Message( "IDXGISwapChain::QueryInterface(): %lu\n", this); + Message( "uMod_IDXGISwapChain::QueryInterface(): %lu\n", this); HRESULT hRes = m_IDXGISwapChain->QueryInterface(riid, ppvObject); if (*ppvObject == m_IDXGISwapChain) @@ -51,12 +51,14 @@ HRESULT STDMETHODCALLTYPE uMod_IDXGISwapChain::QueryInterface( REFIID riid, void ULONG STDMETHODCALLTYPE uMod_IDXGISwapChain::AddRef(void) { + Message( "uMod_IDXGISwapChain::AddRef(): %lu\n", this); RefCounter++; return m_IDXGISwapChain->AddRef(); } ULONG STDMETHODCALLTYPE uMod_IDXGISwapChain::Release( void) { + Message( "uMod_IDXGISwapChain::Release(): %lu\n", this); if (--RefCounter==0) //if our counter drops to zero, the real device will be deleted, so we clean up before { // we must not release the fake textures, cause they are released if the target textures are released @@ -111,11 +113,13 @@ HRESULT STDMETHODCALLTYPE uMod_IDXGISwapChain::GetDevice( REFIID riid, void **pp HRESULT STDMETHODCALLTYPE uMod_IDXGISwapChain::Present( UINT SyncInterval, UINT Flags) { + Message( "uMod_IDXGISwapChain::Present(): %lu\n", this); return m_IDXGISwapChain->Present( SyncInterval, Flags); } HRESULT STDMETHODCALLTYPE uMod_IDXGISwapChain::GetBuffer( UINT Buffer, REFIID riid, void **ppSurface) { + Message( "uMod_IDXGISwapChain::GetBuffer(): %lu\n", this); return m_IDXGISwapChain->GetBuffer( Buffer, riid, ppSurface); } diff --git a/uMod_DX9/uMod_DX9_dll.cpp b/uMod_DX9/uMod_DX9_dll.cpp index fd34280..bf54f9f 100644 --- a/uMod_DX9/uMod_DX9_dll.cpp +++ b/uMod_DX9/uMod_DX9_dll.cpp @@ -33,58 +33,93 @@ along with Universal Modding Engine. If not, see /* * global variable which are not linked external */ +#if INJECTION_METHOD==NO_INJECTION HINSTANCE gl_hOriginal_DX9_Dll = NULL; +#endif + + +#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION typedef IDirect3D9 *(APIENTRY *Direct3DCreate9_type)(UINT); typedef HRESULT (APIENTRY *Direct3DCreate9Ex_type)(UINT SDKVersion, IDirect3D9Ex **ppD3D); -#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION -Direct3DCreate9_type Direct3DCreate9_fn = NULL; // we need to store the pointer to the original Direct3DCreate9 function after we have done a detour -Direct3DCreate9Ex_type Direct3DCreate9Ex_fn = NULL; // we need to store the pointer to the original Direct3DCreate9 function after we have done a detour +uMod_Detour_Entry Detour_Direct3DCreate9(5); +uMod_Detour_Entry Detour_Direct3DCreate9Ex(5); + #endif - -/* - * global variable which are linked external - */ - void InitDX9(void) { - LoadOriginal_DX9_Dll(); #if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION - // we detour the original Direct3DCreate9 to our MyDirect3DCreate9 - if (gl_hOriginal_DX9_Dll!=NULL) - { - Direct3DCreate9_fn = (Direct3DCreate9_type) GetProcAddress(gl_hOriginal_DX9_Dll, "Direct3DCreate9"); - if (Direct3DCreate9_fn!=NULL) - { - Message("Detour: Direct3DCreate9\n"); - Direct3DCreate9_fn = (Direct3DCreate9_type)DetourFunc( (BYTE*)Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9, 5); - } - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type) GetProcAddress(gl_hOriginal_DX9_Dll, "Direct3DCreate9Ex"); - if (Direct3DCreate9Ex_fn!=NULL) - { - Message("Detour: Direct3DCreate9Ex\n"); - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)DetourFunc( (BYTE*)Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex, 7); - } + char buffer[MAX_PATH]; + wchar_t buffer_w[MAX_PATH]; + GetSystemDirectory(buffer,MAX_PATH); //get the system directory, we need to open the original d3d9.dll + + swprintf_s( buffer_w, MAX_PATH, L"%s\\d3d9.dll", buffer); + strcat_s( buffer, MAX_PATH,"\\d3d9.dll"); + + Detour_Direct3DCreate9.SetFunctionName( "Direct3DCreate9"); + Detour_Direct3DCreate9.SetTargetFunction( uMod_Direct3DCreate9); + Detour_Direct3DCreate9.SetLibName( "d3d9.dll"); + Detour_Direct3DCreate9.SetFullLibName( buffer); + Detour_Direct3DCreate9.SetLibName( L"d3d9.dll"); // set also for wide character + Detour_Direct3DCreate9.SetFullLibName( buffer_w); // set also for wide character + + Detour_Direct3DCreate9Ex.SetFunctionName( "Direct3DCreate9Ex"); + Detour_Direct3DCreate9Ex.SetTargetFunction( uMod_Direct3DCreate9Ex); + Detour_Direct3DCreate9Ex.SetLibName( "d3d9.dll"); + Detour_Direct3DCreate9Ex.SetFullLibName( buffer); + Detour_Direct3DCreate9Ex.SetLibName( L"d3d9.dll"); // set also for wide character + Detour_Direct3DCreate9Ex.SetFullLibName( buffer_w); // set also for wide character + + GlobalDetour.AddEntry(&Detour_Direct3DCreate9); + GlobalDetour.AddEntry(&Detour_Direct3DCreate9Ex); + //char buffer[MAX_PATH]; + //if (gl_hOriginal_DX9_Dll==NULL) + { + GetSystemDirectory(buffer,MAX_PATH); //get the system directory, we need to open the original d3d9.dll + + // Append dll name + strcat_s( buffer, MAX_PATH,"\\d3d9.dll"); + + // try to load the system's d3d9.dll + HANDLE gl_hOriginal_DX9_Dll = LoadLibrary(buffer); } #endif + +#if INJECTION_METHOD==NO_INJECTION + LoadOriginal_DX9_Dll(); +#endif } void ExitDX9(void) { // Release the system's d3d9.dll +#if INJECTION_METHOD==NO_INJECTION if (gl_hOriginal_DX9_Dll!=NULL) { FreeLibrary(gl_hOriginal_DX9_Dll); gl_hOriginal_DX9_Dll = NULL; } +#endif + + +#if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION +#endif + } + + + +#if INJECTION_METHOD==NO_INJECTION +/* + * We do not inject, the game loads this dll by itself thus we must include the Direct3DCreate9 function + */ void LoadOriginal_DX9_Dll(void) { char buffer[MAX_PATH]; @@ -100,12 +135,6 @@ void LoadOriginal_DX9_Dll(void) } } - -#if INJECTION_METHOD==NO_INJECTION -/* - * We do not inject, the game loads this dll by itself thus we must include the Direct3DCreate9 function - */ - IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) { Message("WINAPI Direct3DCreate9\n"); @@ -218,6 +247,9 @@ DWORD WINAPI D3DPERF_GetStatus( void ) #endif + + + #if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION /* @@ -226,95 +258,44 @@ DWORD WINAPI D3DPERF_GetStatus( void ) IDirect3D9 *APIENTRY uMod_Direct3DCreate9(UINT SDKVersion) { - Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9); - - // in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines - // but somehow, for me it only works, if I retour the function and calling afterward the original function - - // BEGIN - - LoadOriginal_DX9_Dll(); - - RetourFunc((BYTE*) GetProcAddress( gl_hOriginal_DX9_Dll, "Direct3DCreate9"), (BYTE*)Direct3DCreate9_fn, 5); - Direct3DCreate9_fn = (Direct3DCreate9_type) GetProcAddress( gl_hOriginal_DX9_Dll, "Direct3DCreate9"); - -/* - if (Direct3DCreate9Ex_fn!=NULL) - { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9Ex"), (BYTE*)Direct3DCreate9Ex_fn, 7); - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9Ex"); - } - */ - // END + Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Detour_Direct3DCreate9.Function(), uMod_Direct3DCreate9); IDirect3D9 *pIDirect3D9_orig = NULL; - if (Direct3DCreate9_fn) - { - pIDirect3D9_orig = Direct3DCreate9_fn(SDKVersion); //creating the original IDirect3D9 object - } - else return (NULL); - uMod_IDirect3D9 *pIDirect3D9; + uMod_IDirect3D9 *pIDirect3D9 = NULL; + + Detour_Direct3DCreate9.Retour(); + + pIDirect3D9_orig = Detour_Direct3DCreate9.Function()(SDKVersion); //creating the original IDirect3D9 object + if (pIDirect3D9_orig) { pIDirect3D9 = new uMod_IDirect3D9( pIDirect3D9_orig, gl_TextureServer); //creating our uMod_IDirect3D9 object } + Detour_Direct3DCreate9.Detour(); - // we detour again - Direct3DCreate9_fn = (Direct3DCreate9_type)DetourFunc( (BYTE*) Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9,5); - /* - if (Direct3DCreate9Ex_fn!=NULL) - { - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)DetourFunc( (BYTE*) Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex,7); - } -*/ return (pIDirect3D9); //return our object instead of the "real one" } + HRESULT APIENTRY uMod_Direct3DCreate9Ex( UINT SDKVersion, IDirect3D9Ex **ppD3D) { - Message( "uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex); - - // in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines - // but somehow, for me it only works, if I retour the function and calling afterward the original function - - // BEGIN - - LoadOriginal_DX9_Dll(); - /* - if (Direct3DCreate9_fn!=NULL) - { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9"), (BYTE*)Direct3DCreate9_fn, 5); - Direct3DCreate9_fn = (Direct3DCreate9_type) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9"); - } -*/ - RetourFunc((BYTE*) GetProcAddress( gl_hOriginal_DX9_Dll, "Direct3DCreate9Ex"), (BYTE*)Direct3DCreate9Ex_fn, 7); - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type) GetProcAddress( gl_hOriginal_DX9_Dll, "Direct3DCreate9Ex"); - // END + Message( "uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Detour_Direct3DCreate9Ex.Function(), uMod_Direct3DCreate9Ex); IDirect3D9Ex *pIDirect3D9Ex_orig = NULL; - HRESULT ret; - if (Direct3DCreate9Ex_fn) - { - ret = Direct3DCreate9Ex_fn(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object - } - else return (D3DERR_NOTAVAILABLE); + uMod_IDirect3D9Ex *pIDirect3D9Ex = NULL; + HRESULT ret = D3DERR_NOTAVAILABLE; + + Detour_Direct3DCreate9Ex.Retour(); + ret = Detour_Direct3DCreate9Ex.Function()(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object if (ret!=S_OK) return (ret); - uMod_IDirect3D9Ex *pIDirect3D9Ex; if (pIDirect3D9Ex_orig) { pIDirect3D9Ex = new uMod_IDirect3D9Ex( pIDirect3D9Ex_orig, gl_TextureServer); //creating our uMod_IDirect3D9 object } + Detour_Direct3DCreate9Ex.Detour(); - // we detour again -/* - if (Direct3DCreate9_fn!=NULL) - { - Direct3DCreate9_fn = (Direct3DCreate9_type)DetourFunc( (BYTE*) Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9,5); - } - */ - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)DetourFunc( (BYTE*) Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex,7); ppD3D = (IDirect3D9Ex**) &pIDirect3D9Ex; //return our object instead of the "real one" return (ret); } diff --git a/uMod_DX9/uMod_DX9_dll.h b/uMod_DX9/uMod_DX9_dll.h index 2175d64..8b627d5 100644 --- a/uMod_DX9/uMod_DX9_dll.h +++ b/uMod_DX9/uMod_DX9_dll.h @@ -23,20 +23,17 @@ along with Universal Modding Engine. If not, see #include "../uMod_DXMain/uMod_Main.h" + + +void InitDX9(); +void ExitDX9(); + +#if INJECTION_METHOD==NO_INJECTION /** * Load the official d3d9.dll from the system path. */ void LoadOriginal_DX9_Dll(void); - -/** - * Initialize dx9 -> loads d3d9.dll and set detour if this dll is compiled for "Direct Injection" or "Hook Injection" - */ -void InitDX9(); - -/** - * Unload the d3d9.dll - */ -void ExitDX9(); +#endif #if INJECTION_METHOD==DIRECT_INJECTION || INJECTION_METHOD==HOOK_INJECTION diff --git a/uMod_DX9/uMod_IDirect3DDevice9.cpp b/uMod_DX9/uMod_IDirect3DDevice9.cpp index 18734f7..8188ea5 100644 --- a/uMod_DX9/uMod_IDirect3DDevice9.cpp +++ b/uMod_DX9/uMod_IDirect3DDevice9.cpp @@ -491,11 +491,13 @@ BOOL uMod_IDirect3DDevice9::ShowCursor(BOOL bShow) HRESULT uMod_IDirect3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) { + Message("uMod_IDirect3DDevice9::CreateAdditionalSwapChain() %p\n", this); return(m_pIDirect3DDevice9->CreateAdditionalSwapChain(pPresentationParameters,pSwapChain)); } HRESULT uMod_IDirect3DDevice9::GetSwapChain(UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) { + Message("uMod_IDirect3DDevice9::GetSwapChain() %p\n", this); return(m_pIDirect3DDevice9->GetSwapChain(iSwapChain,pSwapChain)); } @@ -971,7 +973,7 @@ HRESULT uMod_IDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width,UINT Heigh HRESULT uMod_IDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) { - //Message( PRE_MESSAGE "::SetRenderTarget( %u, %p): %p\n", RenderTargetIndex, pRenderTarget, this); + Message( PRE_MESSAGE "::SetRenderTarget( %u, %p): %p\n", RenderTargetIndex, pRenderTarget, this); { IDirect3DSurface9 *back_buffer; NormalRendering = false; diff --git a/uMod_DX9/uMod_IDirect3DSurface9.cpp b/uMod_DX9/uMod_IDirect3DSurface9.cpp index 34de687..0c838d0 100644 --- a/uMod_DX9/uMod_IDirect3DSurface9.cpp +++ b/uMod_DX9/uMod_IDirect3DSurface9.cpp @@ -50,14 +50,14 @@ HRESULT uMod_IDirect3DSurface9::QueryInterface(REFIID riid, void** ppvObj) ULONG uMod_IDirect3DSurface9::AddRef() { - //Message( "uMod_IDirect3DSurface9::AddRef(): %p\n", this); + Message( "uMod_IDirect3DSurface9::AddRef(): %p\n", this); RefCounter++; return m_D3Dsurf->AddRef(); } ULONG uMod_IDirect3DSurface9::Release() { - //Message( "uMod_IDirect3DSurface9::Release(): %p\n", this); + Message( "uMod_IDirect3DSurface9::Release(): %p\n", this); // this object might be created by uMod_IDirect3DTexture9::GetSurfaceLevel // thus the RefCounter might be zero although m_D3Dsurf->Release() does not delete // the m_D3Dsurf object @@ -75,19 +75,19 @@ HRESULT uMod_IDirect3DSurface9::GetDevice( IDirect3DDevice9** ppDevice) HRESULT uMod_IDirect3DSurface9::SetPrivateData( REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) { - //Message( "uMod_IDirect3DSurface9::SetPrivateData(): %p\n", this); + Message( "uMod_IDirect3DSurface9::SetPrivateData(): %p\n", this); return m_D3Dsurf->SetPrivateData( refguid, pData, SizeOfData, Flags); } HRESULT uMod_IDirect3DSurface9::GetPrivateData( REFGUID refguid,void* pData,DWORD* pSizeOfData) { - //Message( "uMod_IDirect3DSurface9::GetPrivateData(): %p\n", this); + Message( "uMod_IDirect3DSurface9::GetPrivateData(): %p\n", this); return m_D3Dsurf->GetPrivateData( refguid, pData, pSizeOfData); } HRESULT uMod_IDirect3DSurface9::FreePrivateData( REFGUID refguid) { - //Message( "uMod_IDirect3DSurface9::FreePrivateData(): %p\n", this); + Message( "uMod_IDirect3DSurface9::FreePrivateData(): %p\n", this); return m_D3Dsurf->FreePrivateData( refguid); } @@ -116,7 +116,7 @@ D3DRESOURCETYPE uMod_IDirect3DSurface9::GetType() HRESULT uMod_IDirect3DSurface9::GetContainer( REFIID riid,void** ppContainer) { - //Message( "uMod_IDirect3DSurface9::GetContainer(): %p\n", this); + Message( "uMod_IDirect3DSurface9::GetContainer(): %p\n", this); HRESULT ret = m_D3Dsurf->GetContainer( riid, ppContainer); //return the uMod_IDirect3DTexture9 object @@ -136,38 +136,37 @@ HRESULT uMod_IDirect3DSurface9::GetContainer( REFIID riid,void** ppContainer) HRESULT uMod_IDirect3DSurface9::GetDesc( D3DSURFACE_DESC *pDesc) { - //Message( "uMod_IDirect3DSurface9::GetDesc(): %p\n", this); + Message( "uMod_IDirect3DSurface9::GetDesc(): %p\n", this); return m_D3Dsurf->GetDesc( pDesc); } HRESULT uMod_IDirect3DSurface9::LockRect( D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) { - //Message( "uMod_IDirect3DSurface9::LockRect(): %p\n", this); + Message( "uMod_IDirect3DSurface9::LockRect(): %p\n", this); return m_D3Dsurf->LockRect( pLockedRect, pRect, Flags); } HRESULT uMod_IDirect3DSurface9::UnlockRect() { - //Message( "uMod_IDirect3DSurface9::UnlockRect(): %p\n", this); + Message( "uMod_IDirect3DSurface9::UnlockRect(): %p\n", this); HRESULT ret = m_D3Dsurf->UnlockRect(); if (m_D3DTex!=NULL && !m_D3DTex->FAKE) m_D3DTex->Dirty=1; else if (m_D3DCubeTex!=NULL && !m_D3DCubeTex->FAKE) m_D3DCubeTex->Dirty = 1; - return ret; } HRESULT uMod_IDirect3DSurface9::GetDC( HDC *phdc) { - //Message( "uMod_IDirect3DSurface9::GetDC(): %p\n", this); + Message( "uMod_IDirect3DSurface9::GetDC(): %p\n", this); return m_D3Dsurf->GetDC( phdc); } HRESULT uMod_IDirect3DSurface9::ReleaseDC( HDC hdc) { - //Message( "uMod_IDirect3DSurface9::ReleaseDC(): %p\n", this); + Message( "uMod_IDirect3DSurface9::ReleaseDC(): %p\n", this); HRESULT ret = m_D3Dsurf->ReleaseDC( hdc); if (m_D3DTex!=NULL && !m_D3DTex->FAKE) diff --git a/uMod_DXMain/makefile.gcc b/uMod_DXMain/makefile.gcc index 0647bb0..e3b8fde 100644 --- a/uMod_DXMain/makefile.gcc +++ b/uMod_DXMain/makefile.gcc @@ -79,6 +79,7 @@ objects = \ ${obj}\uMod_ArrayHandler.$(DX_XX_File).${obj_suff} \ ${obj}\uMod_TextureClient.$(DX_XX_File).${obj_suff} \ ${obj}\uMod_TextureServer.$(DX_XX_File).${obj_suff} \ + ${obj}\uMod_Detour.$(DX_XX_File).${obj_suff} \ ${obj}\uMod_DXMain_dll.$(DX_XX_File).${obj_suff} \ \ ${obj}\uMod_DX9_dll.${obj_suff} \ @@ -103,6 +104,8 @@ objects = \ headers = uMod_Main.h \ uMod_DXMain_dll.h \ + uMod_Detour.h \ + uMod_DetourEntry.h \ uMod_Defines.h \ uMod_TextureFunction.h \ uMod_ArrayHandler.h \ @@ -137,6 +140,9 @@ ${bin}\d3d9.dll: ${objects} ${obj}\uMod_DXMain_dll.$(DX_XX_File).${obj_suff}: uMod_DXMain_dll.cpp ${headers} ${CXX} ${CFLAGS} /c $< /Fo$@ +${obj}\uMod_Detour.$(DX_XX_File).${obj_suff}: uMod_Detour.cpp ${headers} + ${CXX} ${CFLAGS} /c $< /Fo$@ + ${obj}\uMod_ArrayHandler.$(DX_XX_File).${obj_suff}: uMod_ArrayHandler.cpp ${headers} ${CXX} ${CFLAGS} /c $< /Fo$@ diff --git a/uMod_DXMain/makefile.vc b/uMod_DXMain/makefile.vc index 3711d7e..ee011ef 100644 --- a/uMod_DXMain/makefile.vc +++ b/uMod_DXMain/makefile.vc @@ -79,6 +79,7 @@ objects = \ $(obj)\uMod_ArrayHandler.$(DX_XX_File).$(obj_suff) \ $(obj)\uMod_TextureClient.$(DX_XX_File).$(obj_suff) \ $(obj)\uMod_TextureServer.$(DX_XX_File).$(obj_suff) \ + $(obj)\uMod_Detour.$(DX_XX_File).$(obj_suff) \ $(obj)\uMod_DXMain_dll.$(DX_XX_File).$(obj_suff) \ \ $(obj)\uMod_DX9_dll.$(obj_suff) \ @@ -103,6 +104,8 @@ objects = \ headers = uMod_Main.h \ uMod_DXMain_dll.h \ + uMod_Detour.h \ + uMod_DetourEntry.h \ uMod_Defines.h \ uMod_TextureFunction.h \ uMod_ArrayHandler.h \ @@ -137,6 +140,9 @@ $(bin)\d3d9.dll: $(objects) $(obj)\uMod_DXMain_dll.$(DX_XX_File).$(obj_suff): uMod_DXMain_dll.cpp $(headers) $(CXX) $(CFLAGS) /c uMod_DXMain_dll.cpp /Fo$@ +$(obj)\uMod_Detour.$(DX_XX_File).$(obj_suff): uMod_Detour.cpp $(headers) + $(CXX) $(CFLAGS) /c uMod_Detour.cpp /Fo$@ + $(obj)\uMod_ArrayHandler.$(DX_XX_File).$(obj_suff): uMod_ArrayHandler.cpp $(headers) $(CXX) $(CFLAGS) /c uMod_ArrayHandler.cpp /Fo$@ diff --git a/uMod_DXMain/uMod_DX9_10_dll_DIRECT_INJECTION.def b/uMod_DXMain/uMod_DX9_10_dll_DIRECT_INJECTION.def new file mode 100644 index 0000000..65c1d46 --- /dev/null +++ b/uMod_DXMain/uMod_DX9_10_dll_DIRECT_INJECTION.def @@ -0,0 +1,7 @@ +LIBRARY "uMod_d3d9_DI" +EXPORTS + uMod_Direct3DCreate9 @1 + uMod_Direct3DCreate9Ex @2 + uMod_D3D10CreateDeviceAndSwapChain @3 + uMod_D3D10CreateDeviceAndSwapChain1 @4 + Nothing @5 \ No newline at end of file diff --git a/uMod_DXMain/uMod_DXMain_dll.cpp b/uMod_DXMain/uMod_DXMain_dll.cpp index 7e4c710..f3e9e9d 100644 --- a/uMod_DXMain/uMod_DXMain_dll.cpp +++ b/uMod_DXMain/uMod_DXMain_dll.cpp @@ -102,6 +102,7 @@ void InitInstance(HINSTANCE hModule) gl_TextureServer = new uMod_TextureServer(game); //create the server which listen on the pipe and prepare the update for the texture clients + GlobalDetour.Init(); #ifdef DEF_USE_DX9 InitDX9(); #endif @@ -146,6 +147,7 @@ void ExitInstance() ExitDX10(); #endif + GlobalDetour.Exit(); CloseMessage(); } diff --git a/uMod_DXMain/uMod_Detour.cpp b/uMod_DXMain/uMod_Detour.cpp new file mode 100644 index 0000000..3b846dd --- /dev/null +++ b/uMod_DXMain/uMod_Detour.cpp @@ -0,0 +1,206 @@ +/* +This file is part of Universal Modding Engine. + + +Universal Modding Engine is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Universal Modding Engine is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Universal Modding Engine. If not, see . +*/ + +#include "uMod_Detour.h" +#include "uMod_Main.h" + + + +uMod_Detour::uMod_Detour() : NumOfEntries(0), Entries(NULL), + Detour_FreeLibrary(5), + Detour_LoadLibraryA(5), + Detour_LoadLibraryW(5), + Detour_LoadLibraryExA(5), + Detour_LoadLibraryExW(5) +{ + +} + +uMod_Detour::~uMod_Detour() +{ + if (Entries!=NULL) delete [] Entries; +} + + +void uMod_Detour::Init(void) +{ + Detour_FreeLibrary.SetOrigFunction(FreeLibrary); + Detour_FreeLibrary.SetTargetFunction(uMod_FreeLibrary); + Detour_FreeLibrary.Detour(); + + Detour_LoadLibraryA.SetOrigFunction(LoadLibraryA); + Detour_LoadLibraryA.SetTargetFunction(uMod_LoadLibraryA); + Detour_LoadLibraryA.Detour(); + + Detour_LoadLibraryW.SetOrigFunction(LoadLibraryW); + Detour_LoadLibraryW.SetTargetFunction(uMod_LoadLibraryW); + Detour_LoadLibraryW.Detour(); + + Detour_LoadLibraryExA.SetOrigFunction(LoadLibraryExA); + Detour_LoadLibraryExA.SetTargetFunction(uMod_LoadLibraryExA); + Detour_LoadLibraryExA.Detour(); + + Detour_LoadLibraryExW.SetOrigFunction(LoadLibraryExW); + Detour_LoadLibraryExW.SetTargetFunction(uMod_LoadLibraryExW); + Detour_LoadLibraryExW.Detour(); + + + //for (int i=0; iDetour(); +} + +void uMod_Detour::Exit(void) +{ + Detour_FreeLibrary.Retour(); + Detour_LoadLibraryA.Retour(); + Detour_LoadLibraryW.Retour(); + Detour_LoadLibraryExA.Retour(); + Detour_LoadLibraryExW.Retour(); + + //for (int i=0; iRetour(); +} + +int uMod_Detour::AddEntry( uMod_Detour_Entry_Base* entry) +{ + uMod_Detour_Entry_Base** temp = new uMod_Detour_Entry_Base*[NumOfEntries+1]; + + if (Entries!=NULL) + { + for (int i=0; iFreeLib( plib); +} + +void uMod_Detour::TestLib(const char* lib_name, HMODULE plib) +{ + Message("uMod_Detour::TestLib( %s, %p )\n", lib_name, plib); + if (lib_name==NULL) return; + if (plib==NULL) return; + + for (int i=0; iTestLib( lib_name, plib); +} + +void uMod_Detour::TestLib(const wchar_t* lib_name, HMODULE plib) +{ + Message("uMod_Detour::TestLib( %ls, %p )\n", lib_name, plib); + if (lib_name==NULL) return; + if (plib==NULL) return; + + for (int i=0; iTestLib( lib_name, plib); +} + + +uMod_Detour GlobalDetour; + + +BOOL WINAPI uMod_FreeLibrary( HMODULE hModule) +{ + GlobalDetour.Detour_FreeLibrary.Retour(); //retour the FreeLibrary function + + BOOL ret = FreeLibrary( hModule); // now call the original function + Message("%d = uMod_FreeLibrary( %p )\n", ret, hModule); + + GlobalDetour.FreeLib(hModule); // notify all detoured function, that this library was once more freed + + GlobalDetour.Detour_FreeLibrary.Detour(); // detour again the FreeLibrary function + + return ret; +} + +HMODULE WINAPI uMod_LoadLibraryA( LPCSTR lpFileName) +{ + GlobalDetour.Detour_LoadLibraryA.Retour(); //retour the LoadLibraryA function + + HMODULE ret = LoadLibraryA( lpFileName); // now call the original function + Message("%p = uMod_LoadLibraryA( %s )\n", ret, lpFileName); + + GlobalDetour.TestLib( lpFileName, ret); // notify all detoured function, that this library was once more loaded + + GlobalDetour.Detour_LoadLibraryA.Detour(); // detour again the LoadLibraryA function + + return ret; +} + +HMODULE WINAPI uMod_LoadLibraryW( LPCWSTR lpFileName) +{ + GlobalDetour.Detour_LoadLibraryW.Retour(); //retour the LoadLibraryW function + + HMODULE ret = LoadLibraryW( lpFileName); // now call the original function + GlobalDetour.TestLib( lpFileName, ret); // notify all detoured function, that this library was once more loaded + Message("%p = uMod_LoadLibraryW( %ls )\n", ret, lpFileName); + + GlobalDetour.Detour_LoadLibraryW.Detour(); // detour again the LoadLibraryW function + + return ret; +} + +HMODULE WINAPI uMod_LoadLibraryExA( LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + GlobalDetour.Detour_LoadLibraryExA.Retour(); //retour the LoadLibraryExA function + + HMODULE ret = LoadLibraryExA( lpFileName, hFile, dwFlags); // now call the original function + Message("%p = uMod_LoadLibraryExA( %s, %p, %d)\n", ret, lpFileName, hFile, dwFlags); + + if (dwFlags==0) + { + GlobalDetour.TestLib( lpFileName, ret); // notify all detoured function, that this library was once more loaded + } + + GlobalDetour.Detour_LoadLibraryExA.Detour(); // detour again the LoadLibraryExA function + + return ret; +} + +HMODULE WINAPI uMod_LoadLibraryExW( LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + GlobalDetour.Detour_LoadLibraryExW.Retour(); //retour the LoadLibraryExA function + + HMODULE ret = LoadLibraryExW( lpFileName, hFile, dwFlags); // now call the original function + Message("%p = uMod_LoadLibraryExW( %ls, %p, %d)\n", ret, lpFileName, hFile, dwFlags); + + if (dwFlags==0) + { + GlobalDetour.TestLib( lpFileName, ret); // notify all detoured function, that this library was once more loaded + } + + GlobalDetour.Detour_LoadLibraryExW.Detour(); // detour again the LoadLibraryExA function + + return ret; +} + diff --git a/uMod_DXMain/uMod_Detour.h b/uMod_DXMain/uMod_Detour.h new file mode 100644 index 0000000..1f1bb69 --- /dev/null +++ b/uMod_DXMain/uMod_Detour.h @@ -0,0 +1,72 @@ +/* +This file is part of Universal Modding Engine. + + +Universal Modding Engine is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Universal Modding Engine is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Universal Modding Engine. If not, see . +*/ + +#ifndef UMOD_DETOUR_H_ +#define UMOD_DETOUR_H_ + +#include "uMod_DetourEntry.h" +#include + +#ifdef __CDT_PARSER__ +#define NULL 0 +#endif + +typedef BOOL (WINAPI *FreeLibrary_type)( HMODULE hModule); +typedef HMODULE (WINAPI *LoadLibraryA_type)( LPCSTR lpFileName); +typedef HMODULE (WINAPI *LoadLibraryW_type)( LPCWSTR lpFileName); +typedef HMODULE (WINAPI *LoadLibraryExA_type)( LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags); +typedef HMODULE (WINAPI *LoadLibraryExW_type)( LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags); + +BOOL WINAPI uMod_FreeLibrary( HMODULE hModule); +HMODULE WINAPI uMod_LoadLibraryA( LPCSTR lpFileName); +HMODULE WINAPI uMod_LoadLibraryW( LPCWSTR lpFileName); +HMODULE WINAPI uMod_LoadLibraryExA( LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags); +HMODULE WINAPI uMod_LoadLibraryExW( LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags); + +class uMod_Detour +{ +public: + uMod_Detour(); + ~uMod_Detour(); + + + void Init(); + void Exit(); + + int AddEntry( uMod_Detour_Entry_Base* entry); + + + void FreeLib( HMODULE plib); + void TestLib(const char* lib_name, HMODULE plib); + void TestLib(const wchar_t* lib_name, HMODULE plib); + + + uMod_Detour_Entry Detour_FreeLibrary; + uMod_Detour_Entry Detour_LoadLibraryA; + uMod_Detour_Entry Detour_LoadLibraryW; + uMod_Detour_Entry Detour_LoadLibraryExA; + uMod_Detour_Entry Detour_LoadLibraryExW; + +private: + int NumOfEntries; + uMod_Detour_Entry_Base** Entries; +}; + +extern uMod_Detour GlobalDetour; + +#endif /* UMOD_DETOUR_H_ */ diff --git a/uMod_DXMain/uMod_DetourEntry.h b/uMod_DXMain/uMod_DetourEntry.h new file mode 100644 index 0000000..04e34b2 --- /dev/null +++ b/uMod_DXMain/uMod_DetourEntry.h @@ -0,0 +1,324 @@ +/* + * uMod_DetourEntry.h + * + * Created on: 13.01.2013 + * Author: marts + */ + +#ifndef UMOD_DETOURENTRY_H_ +#define UMOD_DETOURENTRY_H_ + +#include "uMod_Main.h" + +#ifdef __CDT_PARSER__ +#define NULL 0 +#endif + +class uMod_Detour_Entry_Base +{ +public: + uMod_Detour_Entry_Base() {} + virtual ~uMod_Detour_Entry_Base() {} + + virtual void TestLib(const char* lib_name, HMODULE plib) = 0; + virtual void TestLib(const wchar_t* lib_name, HMODULE plib) = 0; + virtual void FreeLib(HMODULE plib) = 0; + + + virtual void Detour(void) = 0; + virtual void Retour(void) = 0; +}; + + + + +template +class uMod_Detour_Entry : public uMod_Detour_Entry_Base +{ +public: + uMod_Detour_Entry(const int num_bytes); + virtual ~uMod_Detour_Entry(); + + + virtual void TestLib(const char* lib_name, HMODULE plib); + virtual void TestLib(const wchar_t* lib_name, HMODULE plib); + virtual void FreeLib(HMODULE plib); + + virtual void Detour(void); + virtual void Retour(void); + bool CheckForDetour(); + + int SetFunctionName( const char* name) {return SetName( FunctionName, name);} + int SetLibName( const char* name) {return SetName( LibName, name);} + int SetFullLibName( const char* name) {return SetName( FullLibName, name);} + + int SetLibName( const wchar_t* name) {return SetName( LibNameW, name);} + int SetFullLibName( const wchar_t* name) {return SetName( FullLibNameW, name);} + + void SetOrigFunction(T func) {OrigFunction = func;} + void SetTargetFunction(T func) {TargetFunction = func;} + + T Function(void) const {return OrigFunction;} + +private: + + + int SetName( char* &member_var, const char* name); + int SetName( wchar_t* &member_var, const wchar_t* name); + + char* FunctionName; + char* LibName; + char* FullLibName; + + wchar_t* LibNameW; + wchar_t* FullLibNameW; + + HMODULE PLibrary; + int RefCounter; + + + + const int NumBytes; + T OrigFunction; + T TargetFunction; + + BYTE* DetourFunction; + bool IsDetoured; + bool IsFailed; +}; + + + +template +uMod_Detour_Entry::uMod_Detour_Entry(const int num_bytes) : FunctionName(NULL), LibName(NULL), FullLibName(NULL), + LibNameW(NULL), FullLibNameW(NULL), PLibrary(NULL), + NumBytes(num_bytes), OrigFunction(NULL), TargetFunction(NULL), DetourFunction(NULL), IsDetoured(false), IsFailed(false) +{ +} + + +template +uMod_Detour_Entry::~uMod_Detour_Entry() +{ + if (FunctionName!=NULL) delete [] FunctionName; + if (LibName!=NULL) delete [] LibName; + if (FullLibName!=NULL) delete [] FullLibName; + if (LibNameW!=NULL) delete [] LibNameW; + if (FullLibNameW!=NULL) delete [] FullLibNameW; + if (DetourFunction!=NULL) delete [] DetourFunction; +} + + +template +void uMod_Detour_Entry::TestLib(const char* lib_name, HMODULE plib) +{ + if (lib_name==NULL) return; + if (plib==NULL) return; + if (FunctionName==NULL) return; + if (LibName==NULL) return; + + if (PLibrary==plib) + { + RefCounter++; + //return; + } + + int len=0; + while (lib_name[len]) len++; + while (len>=0 && (lib_name[len]!='/' && lib_name[len]!='\\')) len--; + len++; + + if (_stricmp( &lib_name[len], LibName)==0) + { + bool set_detour = true; + if (FullLibName!=NULL) + { + set_detour = false; + GlobalDetour.Detour_LoadLibraryA.Retour(); + GlobalDetour.Detour_FreeLibrary.Retour(); + HMODULE test_handle = LoadLibraryA( FullLibName); //get handle of original library + if (test_handle==NULL || test_handle==plib) set_detour = true; // test if library (loaded by the game) is the original one or a fake one + //if (test_handle!=NULL) FreeLibrary( test_handle); // free the library (we don't want top disturb our own RefCounter) + GlobalDetour.Detour_LoadLibraryA.Detour(); + GlobalDetour.Detour_FreeLibrary.Detour(); + } + + if (!set_detour) return; // it is not the official library (or FullLibName is not set) + if (CheckForDetour()) return; + + OrigFunction = (T) GetProcAddress(plib, FunctionName); + if (OrigFunction==NULL) return; // this library does not contain the function we want to detour + + + Message("uMod_Detour_Entry::TestLib( %s, %p ) set detour -> %s \n", lib_name, plib, FunctionName); + + RefCounter = 1; + PLibrary = plib; + + IsDetoured = false; + IsFailed = false; + Detour(); + } +} + +template +void uMod_Detour_Entry::TestLib(const wchar_t* lib_name, HMODULE plib) +{ + if (lib_name==NULL) return; + if (plib==NULL) return; + if (FunctionName==NULL) return; + if (LibNameW==NULL) return; + + if (PLibrary==plib) + { + RefCounter++; +// return; + } + + int len=0; + while (lib_name[len]) len++; + while (len>=0 && (lib_name[len]!='/' && lib_name[len]!='\\' )) len--; + len++; + + if (_wcsicmp( &lib_name[len], LibNameW)==0) + { + bool set_detour = true; + if (FullLibNameW!=NULL) + { + set_detour = false; + + GlobalDetour.Detour_LoadLibraryW.Retour(); + GlobalDetour.Detour_FreeLibrary.Retour(); + HMODULE test_handle = LoadLibraryW( FullLibNameW); //get handle of original library + if (test_handle==NULL || test_handle==plib) set_detour = true; // test if library (loaded by the game) is the original one or a fake one + if (test_handle!=NULL) FreeLibrary( test_handle); // free the library (we don't want top disturb our own RefCounter) + + GlobalDetour.Detour_LoadLibraryW.Detour(); + GlobalDetour.Detour_FreeLibrary.Detour(); + } + + if (!set_detour) return; // it is not the official library (or FullLibName is not set) + if (CheckForDetour()) return; + + OrigFunction = (T) GetProcAddress(plib, FunctionName); + if (OrigFunction==NULL) return; // this library does not contain the function we want to detour + + + Message("uMod_Detour_Entry::TestLib( %ls, %p ) set detour -> %s \n", lib_name, plib, FunctionName); + + RefCounter = 1; + PLibrary = plib; + + IsDetoured = false; + IsFailed = false; + Detour(); + } +} + +template +void uMod_Detour_Entry::FreeLib(HMODULE plib) +{ + if (plib==NULL) return; + if (plib==PLibrary) RefCounter--; + if (RefCounter<=0) PLibrary = NULL; +} + +template +void uMod_Detour_Entry::Detour(void) +{ + if (IsDetoured || IsFailed) return; + if (DetourFunction==NULL) + { + DetourFunction = new BYTE[NumBytes+5]; + } + BYTE *jmp = DetourFunction; + BYTE *src = (BYTE*) OrigFunction; + const BYTE *dst = (BYTE*) TargetFunction; + const int len = NumBytes; + + DWORD dwback = 0; + //(jmp, len+5, PAGE_EXECUTE_READWRITE, &dwback); //This is the addition needed for Windows 7 RC + if(!VirtualProtect(src, NumBytes, PAGE_READWRITE, &dwback)) IsFailed = true; + if(!memcpy(jmp, src, len)) IsFailed = true; + jmp += len; + jmp[0] = 0xE9; + *(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5; + //memset(src, 0x90, len); + src[0] = 0xE9; + *(DWORD*)(src+1) = (DWORD)(dst - src) - 5; + if(!VirtualProtect(src, len, dwback, &dwback)) IsFailed = true; + + IsDetoured = true; +} + +template +void uMod_Detour_Entry::Retour(void) +{ + if (!IsDetoured || IsFailed) return; + + BYTE *src = (BYTE*) OrigFunction; + BYTE *restore = DetourFunction; + const int len = NumBytes; + DWORD dwback; + if(!VirtualProtect(src, len, PAGE_READWRITE, &dwback)) IsFailed = true; + if(!memcpy(src, restore, len)) IsFailed = true; + restore[0] = 0xE9; + *(DWORD*)(restore+1) = (DWORD)(src - restore) - 5; + + if(!VirtualProtect(src, len, dwback, &dwback)) IsFailed = true; + + IsDetoured = false; +} + + +template +bool uMod_Detour_Entry::CheckForDetour() +{ + if (DetourFunction==NULL) return false; + + //BYTE *jmp = DetourFunction; + BYTE *src = (BYTE*) OrigFunction; + const BYTE *dst = (BYTE*) TargetFunction; + //const int len = NumBytes; + + if (src[0] != 0xE9) return false; + if ( *(DWORD*)(src+1) != (DWORD)(dst - src) - 5) return false; + + return true; +} + +template +int uMod_Detour_Entry::SetName( char* &member_var, const char* name) +{ + if (member_var!=NULL) delete [] member_var; + member_var = NULL; + int len=0; + while (name[len]) len++; + len++; + + member_var = new char[len]; + len = 0; + + while (name[len]) {member_var[len] = name[len]; len++;} + member_var[len] = 0; + return 0; +} + +template +int uMod_Detour_Entry::SetName( wchar_t* &member_var, const wchar_t* name) +{ + if (member_var!=NULL) delete [] member_var; + member_var = NULL; + int len=0; + while (name[len]) len++; + len++; + + member_var = new wchar_t[len]; + len = 0; + + while (name[len]) {member_var[len] = name[len]; len++;} + member_var[len] = 0; + return 0; +} + +#endif /* UMOD_DETOURENTRY_H_ */ diff --git a/uMod_DXMain/uMod_Main.h b/uMod_DXMain/uMod_Main.h index 7a136f0..41535d2 100644 --- a/uMod_DXMain/uMod_Main.h +++ b/uMod_DXMain/uMod_Main.h @@ -52,6 +52,8 @@ along with Universal Modding Engine. If not, see #include "uMod_TextureFunction.h" +#include "uMod_DetourEntry.h" +#include "uMod_Detour.h" #include "uMod_DXMain_dll.h" diff --git a/uMod_GUI/uMod_Main.h b/uMod_GUI/uMod_Main.h index 8bd3b06..be386fa 100644 --- a/uMod_GUI/uMod_Main.h +++ b/uMod_GUI/uMod_Main.h @@ -140,7 +140,7 @@ enum #define ABORT_SERVER L"uMod_Abort_Server" #define uMod_d3d9_Hook_dll L"uMod_d3d9_HI.dll" -#define uMod_d3d9_DI_dll L"uMod_d3d9_DI.dll" +#define uMod_d3d9_DI_dll L"uMod_d3d9_10_DI.dll" #include "uMod_Settings.h" #include "uMod_ModElement.h"