From 2ac1570bf29f32e3bbe8d14873515dd74df66dcd Mon Sep 17 00:00:00 2001 From: "alexey.min" Date: Sat, 4 Feb 2012 07:51:41 +0000 Subject: [PATCH] d3d9 proxy radar loader project --- L2Detect2.vcxproj | 2 + d3d9_proxy_loader.vcxproj | 108 +++++++++++++++ d3d9_proxy_loader.vcxproj.filters | 25 ++++ d3d9_proxy_loader/DllMain.cpp | 159 +++++++++++++++++++++++ d3d9_proxy_loader/d3d9_proxy.h | 8 ++ d3d9_proxy_loader/logger/Logger.cpp | 195 ++++++++++++++++++++++++++++ d3d9_proxy_loader/logger/Logger.h | 37 ++++++ d3d9_proxy_loader/pch.cpp | 1 + d3d9_proxy_loader/pch.h | 35 +++++ d3d9_proxy_loader/proxydll.def | 4 + unlegits.sln | 6 + 11 files changed, 580 insertions(+) create mode 100644 d3d9_proxy_loader.vcxproj create mode 100644 d3d9_proxy_loader.vcxproj.filters create mode 100644 d3d9_proxy_loader/DllMain.cpp create mode 100644 d3d9_proxy_loader/d3d9_proxy.h create mode 100644 d3d9_proxy_loader/logger/Logger.cpp create mode 100644 d3d9_proxy_loader/logger/Logger.h create mode 100644 d3d9_proxy_loader/pch.cpp create mode 100644 d3d9_proxy_loader/pch.h create mode 100644 d3d9_proxy_loader/proxydll.def diff --git a/L2Detect2.vcxproj b/L2Detect2.vcxproj index 09d88ea..f9c1ac3 100644 --- a/L2Detect2.vcxproj +++ b/L2Detect2.vcxproj @@ -47,6 +47,8 @@ false d3d9 d3d9 + .;$(IncludePath) + .;$(IncludePath) diff --git a/d3d9_proxy_loader.vcxproj b/d3d9_proxy_loader.vcxproj new file mode 100644 index 0000000..49295b6 --- /dev/null +++ b/d3d9_proxy_loader.vcxproj @@ -0,0 +1,108 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB} + Win32Proj + d3d9_proxy_loader + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + true + d3d9 + _build\d3d9_proxy_loader_Debug\ + _build\d3d9_proxy_loader_Debug\ + .\d3d9_proxy_loader;$(IncludePath) + + + false + d3d9 + _build\d3d9_proxy_loader_Release\ + _build\d3d9_proxy_loader_Release\ + .\d3d9_proxy_loader;$(IncludePath) + + + + + + Level4 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9_PROXY_LOADER_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Windows + true + d3d9.lib;%(AdditionalDependencies) + .\d3d9_proxy_loader\proxydll.def + + + + + Level4 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9_PROXY_LOADER_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + pch.h + + + Windows + true + true + true + d3d9.lib;%(AdditionalDependencies) + .\d3d9_proxy_loader\proxydll.def + + + + + + + Create + + + + + + + + + + + + + + \ No newline at end of file diff --git a/d3d9_proxy_loader.vcxproj.filters b/d3d9_proxy_loader.vcxproj.filters new file mode 100644 index 0000000..e7379ee --- /dev/null +++ b/d3d9_proxy_loader.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + + + logger + + + + + + logger + + + + + + + + + {6e4bccdb-ba9d-4a27-8866-bbded29f1eb0} + + + \ No newline at end of file diff --git a/d3d9_proxy_loader/DllMain.cpp b/d3d9_proxy_loader/DllMain.cpp new file mode 100644 index 0000000..2e99d86 --- /dev/null +++ b/d3d9_proxy_loader/DllMain.cpp @@ -0,0 +1,159 @@ +#include "pch.h" +#include "d3d9_proxy.h" + +// global variables +#pragma data_seg (".d3d9_shared") +HINSTANCE gl_hOriginalDll; +HINSTANCE gl_hThisInstance; +HINSTANCE gl_hL2Detect; +#pragma data_seg () + +FILE *g_fLog = NULL; + + +BOOL WINAPI DllMain( HINSTANCE hInstDLL, DWORD reason, LPVOID lpvReserved ) +{ + lpvReserved = NULL; + switch( reason ) + { + case DLL_PROCESS_ATTACH: + { + gl_hThisInstance = hInstDLL; + DisableThreadLibraryCalls( hInstDLL ); + D3D9Proxy_Initialize(); + } break; + case DLL_PROCESS_DETACH: + { + D3D9Proxy_Uninitialize(); + } break; + } + return TRUE; +} + + +void D3D9Proxy_Initialize() +{ + // init Logger + ErrorLogger_Init(); + ErrorLogger_Enable( true ); +#ifdef _DEBUG + ErrorLogger_EnableLoggingToConsole( true ); +#endif + g_fLog = fopen( "D3D9Proxy.log", "wt" ); + ErrorLogger_SetLogFile( g_fLog ); + ErrorLogger_SetAutoPrependErrorType( true ); +#ifdef _DEBUG + ErrorLogger_SetWarnMessageLevel( LOG_DEBUGDUMP ); +#else + ErrorLogger_SetWarnMessageLevel( LOG_WARNING ); +#endif + log_error( LOG_OK, "D3D9Proxy_Initialize() called.\n" ); + + // Initialisation + gl_hOriginalDll = NULL; + gl_hThisInstance = NULL; + gl_hL2Detect = NULL; +} + + +void D3D9Proxy_Uninitialize() +{ + log_error( LOG_OK, "D3D9Proxy_Uninitialize() called.\n" ); + + // Release the system's d3d9.dll + if( gl_hOriginalDll ) + { + ::FreeLibrary( gl_hOriginalDll ); + gl_hOriginalDll = NULL; + log_error( LOG_DEBUG, "gl_hOriginalDll (d3d9) unloaded.\n" ); + } + + // Release L2Detect DLL + if( gl_hL2Detect ) + { + ::FreeLibrary( gl_hL2Detect ); + gl_hL2Detect = NULL; + log_error( LOG_DEBUG, "gl_hL2Detect (L2Detect) unloaded.\n" ); + } + + // close logger + log_error( LOG_OK, "Closing log. Last message! Bye!\n=======================\n" ); + ErrorLogger_FlushLogFile(); + ErrorLogger_Enable( false ); +#ifdef _DEBUG + ErrorLogger_EnableLoggingToConsole( false ); +#endif + if( g_fLog ) + { + ErrorLogger_SetLogFile( NULL ); + fflush( g_fLog ); + fclose( g_fLog ); + g_fLog = NULL; + } +} + + +void D3D9Proxy_LoadL2Detect() +{ + if( gl_hL2Detect != NULL ) + return; + + gl_hL2Detect = LoadLibraryW( L"L2Detect_d.dll" ); + if( gl_hL2Detect == NULL ) + { + gl_hL2Detect = LoadLibraryW( L"L2Detect.dll" ); + if( gl_hL2Detect == NULL ) + log_error( LOG_ERROR, "Failed to load radar DLL! Tried to find L2Detect_d / L2Detect dlls.\n" ); + else + log_error( LOG_OK, "Loaded L2Detect.dll at 0x%08X\n", gl_hL2Detect ); + } + else + log_error( LOG_OK, "Loaded L2Detect_d.dll (debug version) at 0x%08X\n", gl_hL2Detect ); +} + + +void LoadOriginalDll() +{ + wchar_t buffer[MAX_PATH]; + buffer[0] = 0; + // Getting path to system dir and to d3d8.dll + ::GetSystemDirectory( buffer, MAX_PATH ); + // Append dll name + wcscat( buffer, L"\\d3d9.dll" ); + // try to load the system's d3d9.dll, if pointer empty + if( !gl_hOriginalDll ) gl_hOriginalDll = ::LoadLibrary( buffer ); + // Debug + if( !gl_hOriginalDll ) + { + log_error( LOG_ERROR, "LoadOriginalDll(): Original d3d9.dll not loaded!\n"); + ErrorLogger_FlushLogFile(); + ::ExitProcess(0); + } +} + + +// Exported function (faking d3d9.dll's one-and-only export) +IDirect3D9* WINAPI Direct3DCreate9( UINT SDKVersion ) +{ + if( !gl_hOriginalDll ) LoadOriginalDll(); // looking for the "right d3d9.dll" + + // Hooking IDirect3D Object from Original Library + typedef IDirect3D9 *(WINAPI* D3D9_Type)(UINT SDKVersion); + D3D9_Type D3DCreate9_fn = (D3D9_Type)GetProcAddress( gl_hOriginalDll, "Direct3DCreate9" ); + + // Debug + if( !D3DCreate9_fn ) + { + log_error( LOG_ERROR, "Direct3DCreate9(): Pointer to original Direct3DCreate9 function not received!\n" ); + ErrorLogger_FlushLogFile(); + ::ExitProcess(0); // exit the hard way + } + + D3D9Proxy_LoadL2Detect(); + + // Request pointer from Original Dll. + IDirect3D9 *pIDirect3D9_orig = D3DCreate9_fn( SDKVersion ); + + // Return pointer to hooking Object instead of "real one" + return pIDirect3D9_orig; +} diff --git a/d3d9_proxy_loader/d3d9_proxy.h b/d3d9_proxy_loader/d3d9_proxy.h new file mode 100644 index 0000000..60bd1de --- /dev/null +++ b/d3d9_proxy_loader/d3d9_proxy.h @@ -0,0 +1,8 @@ +#pragma once + +extern HINSTANCE gl_hThisInstance; +extern HINSTANCE gl_hOriginalDll; + +void D3D9Proxy_Initialize(); +void D3D9Proxy_Uninitialize(); +void D3D9Proxy_LoadL2Detect(); \ No newline at end of file diff --git a/d3d9_proxy_loader/logger/Logger.cpp b/d3d9_proxy_loader/logger/Logger.cpp new file mode 100644 index 0000000..46ba399 --- /dev/null +++ b/d3d9_proxy_loader/logger/Logger.cpp @@ -0,0 +1,195 @@ +#include "pch.h" +#include "Logger.h" + +// global ErrorLogger vars +bool g_error_logger_enabled; +bool g_error_logger_enabled_console; +FILE *g_error_logger_file; +bool g_error_logger_auto_prepend; +CRITICAL_SECTION g_error_logger_cs; +HANDLE g_error_logger_stdout; +// strings +char g_error_logger_strtype_unknown[16]; +char g_error_logger_strtype[LOG_LEVELS][16]; +// +LOG_LEVEL g_errorLogger_WarnMessageLevel; + +void ErrorLogger_InitStrings() +{ + strcpy( g_error_logger_strtype_unknown, "[??] " ); + strcpy( g_error_logger_strtype[LOG_OK], "[++] " ); + strcpy( g_error_logger_strtype[LOG_ERROR], "[--] " ); + strcpy( g_error_logger_strtype[LOG_WARNING], "[WARN] " ); + strcpy( g_error_logger_strtype[LOG_USERAI], "[AI] " ); + strcpy( g_error_logger_strtype[LOG_PACKETNAME], "[PACK] " ); + strcpy( g_error_logger_strtype[LOG_DEBUG], "[DBG] " ); + strcpy( g_error_logger_strtype[LOG_DEBUGDUMP], "[DUMP] " ); +} + +void ErrorLogger_Init() +{ + g_error_logger_enabled = false; + g_error_logger_enabled_console = false; + g_error_logger_file = stdout; + g_error_logger_auto_prepend = false; + g_error_logger_stdout = INVALID_HANDLE_VALUE; + g_errorLogger_WarnMessageLevel = LOG_DEBUG; + InitializeCriticalSection( &g_error_logger_cs ); + ErrorLogger_InitStrings(); +} + +void ErrorLogger_Enable( bool bEnable ) +{ + g_error_logger_enabled = bEnable; +} + +void ErrorLogger_SetWarnMessageLevel( LOG_LEVEL level ) +{ + g_errorLogger_WarnMessageLevel = level; +} + +void ErrorLogger_EnableLoggingToConsole( bool bEnable ) +{ + EnterCriticalSection( &g_error_logger_cs ); + if( bEnable ) + { + if( g_error_logger_enabled_console == false ) AllocConsole(); + g_error_logger_stdout = GetStdHandle( STD_OUTPUT_HANDLE ); + } + else + { + g_error_logger_stdout = INVALID_HANDLE_VALUE; + if( g_error_logger_enabled_console == true ) FreeConsole(); + } + g_error_logger_enabled_console = bEnable; + LeaveCriticalSection( &g_error_logger_cs ); +} + +void ErrorLogger_SetLogFile( FILE *f ) +{ + EnterCriticalSection( &g_error_logger_cs ); + if( !f ) g_error_logger_file = stdout; else g_error_logger_file = f; + LeaveCriticalSection( &g_error_logger_cs ); +} + +FILE *ErrorLogger_GetLogFile() +{ + return g_error_logger_file; +} + +void ErrorLogger_FlushLogFile() +{ + EnterCriticalSection( &g_error_logger_cs ); + if( g_error_logger_file ) fflush( g_error_logger_file ); + LeaveCriticalSection( &g_error_logger_cs ); +} + +void ErrorLogger_SetAutoPrependErrorType( bool bPrepend ) +{ + g_error_logger_auto_prepend = bPrepend; +} + +int log_error( LOG_LEVEL logLevel, const char *_Format, ... ) +{ + if( !g_error_logger_enabled ) return 0; + int ret = 0; + if( (logLevel < 0) || (!_Format) ) return 0; + if( logLevel > g_errorLogger_WarnMessageLevel ) return 0; + EnterCriticalSection( &g_error_logger_cs ); + va_list l; + va_start( l, _Format ); + if( g_error_logger_auto_prepend ) + { + char *szPrepend = g_error_logger_strtype_unknown; + if( (logLevel >= LOG_OK) && (logLevel <= LOGLEVEL_LAST) ) + szPrepend = g_error_logger_strtype[logLevel]; + fprintf( g_error_logger_file, "%s", szPrepend ); + // also write to console, if enabled + if( g_error_logger_enabled_console ) + { + DWORD numWritten = 0; + WriteConsoleA( g_error_logger_stdout, szPrepend, (DWORD)strlen(szPrepend), &numWritten, NULL ); + } + } + ret = vfprintf( g_error_logger_file, _Format, l ); + // also write to console, if enabled + if( g_error_logger_enabled_console ) + { + char *cbuffer = (char *)malloc( 20480 ); // 20 Kb >_< + if( cbuffer ) + { + va_list l2; + va_start( l2, _Format ); + vsprintf( cbuffer, _Format, l2 ); + DWORD numWritten = 0; + WriteConsoleA( g_error_logger_stdout, cbuffer, (DWORD)strlen(cbuffer), &numWritten, NULL ); + free( cbuffer ); + } + } + LeaveCriticalSection( &g_error_logger_cs ); + return ret; +} + +// forces NO prepend even if set to +int log_error_np( LOG_LEVEL logLevel, const char *_Format, ... ) +{ + if( !g_error_logger_enabled ) return 0; + int ret = 0; + if( (logLevel < 0) || (!_Format) ) return 0; + if( logLevel > g_errorLogger_WarnMessageLevel ) return 0; + EnterCriticalSection( &g_error_logger_cs ); + va_list l; + va_start( l, _Format ); + // no prepend, just vfprintf + ret = vfprintf( g_error_logger_file, _Format, l ); + // also write to console, if enabled? + if( g_error_logger_enabled_console ) + { + char *cbuffer = (char *)malloc( 20480 ); + if( cbuffer ) + { + va_list l2; + va_start( l2, _Format ); + vsprintf( cbuffer, _Format, l2 ); + DWORD numWritten = 0; + WriteConsoleA( g_error_logger_stdout, cbuffer, (DWORD)strlen(cbuffer), &numWritten, NULL ); + free( cbuffer ); + } + } + LeaveCriticalSection( &g_error_logger_cs ); + return ret; +} + +//int log_console( LOG_LEVEL logLevel, const char *_Format, ... ) +//{ +// if( !g_error_logger_enabled_console ) return 0; +//} +// +//int log_console_np( LOG_LEVEL logLevel, const char *_Format, ... ) +//{ +// if( !g_error_logger_enabled_console ) return 0; +//} + +void ErrorLogger_FormatLastError( char *msg, size_t nMaxCount, DWORD error_code ) +{ + FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, 0/*MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)*/, msg, nMaxCount, NULL ); +} + +void ErrorLogger_LogLastError( char *comment, DWORD error_code ) +{ + char errbuf[512]; + errbuf[0] = 0; + ErrorLogger_FormatLastError( errbuf, 511, error_code ); + errbuf[511] = 0; + size_t ll = strlen( errbuf ); + if( ll > 0 ) + { + if( errbuf[ll-1] == '\n' || errbuf[ll-1] == '\r' ) errbuf[ll-1] = 0; + if( ll > 1 ) + { + if( errbuf[ll-2] == '\n' || errbuf[ll-2] == '\r' ) errbuf[ll-2] = 0; + } + } + log_error( LOG_ERROR, "%s: error code: %u (%s)\n", comment, (unsigned int)error_code, errbuf ); +} diff --git a/d3d9_proxy_loader/logger/Logger.h b/d3d9_proxy_loader/logger/Logger.h new file mode 100644 index 0000000..db4fdcd --- /dev/null +++ b/d3d9_proxy_loader/logger/Logger.h @@ -0,0 +1,37 @@ +#ifndef FL_ERRORLOGGER_H_ +#define FL_ERRORLOGGER_H_ + +typedef enum eLOG_LEVEL +{ + LOG_OK = 0, + LOG_ERROR, // 1 + LOG_WARNING, // 2 + LOG_USERAI, // 3 + LOG_PACKETNAME, // 4 + LOG_DEBUG, // 5 + LOG_DEBUGDUMP, // 6 + LOGLEVEL_LAST = LOG_DEBUGDUMP +} LOG_LEVEL; + +#define LOG_LEVELS 7 + +void ErrorLogger_Init(); +void ErrorLogger_Enable( bool bEnable ); +void ErrorLogger_EnableLoggingToConsole( bool bEnable ); +void ErrorLogger_SetLogFile( FILE *f ); +FILE *ErrorLogger_GetLogFile(); +void ErrorLogger_FlushLogFile(); + +void ErrorLogger_SetWarnMessageLevel( LOG_LEVEL level ); +void ErrorLogger_SetAutoPrependErrorType( bool bPrepend ); + +int log_error( LOG_LEVEL logLevel, const char *_Format, ... ); +int log_error_np( LOG_LEVEL logLevel, const char *_Format, ... ); // forces NO prepend even if set to + +//int log_console( LOG_LEVEL logLevel, const char *_Format, ... ); +//int log_console_np( LOG_LEVEL logLevel, const char *_Format, ... ); + +void ErrorLogger_FormatLastError( char *msg, size_t nMaxCount, DWORD error_code ); +void ErrorLogger_LogLastError( char *comment, DWORD error_code ); + +#endif /*FL_ERRORLOGGER_H_*/ diff --git a/d3d9_proxy_loader/pch.cpp b/d3d9_proxy_loader/pch.cpp new file mode 100644 index 0000000..9e6b2e0 --- /dev/null +++ b/d3d9_proxy_loader/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/d3d9_proxy_loader/pch.h b/d3d9_proxy_loader/pch.h new file mode 100644 index 0000000..59835b0 --- /dev/null +++ b/d3d9_proxy_loader/pch.h @@ -0,0 +1,35 @@ +#define WINVER 0x0501 +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0600 +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_DEPRECATE + +// C++ RTL +#include +#include +#include +#include +#include + +// WinAPI +#include +#include +#include +#include +#include +#include +#include + +// STL +#include +#include +#include +#include + +// logger +#include "logger/Logger.h" + +// local Direct3D 9 Interface +#include +//#include + diff --git a/d3d9_proxy_loader/proxydll.def b/d3d9_proxy_loader/proxydll.def new file mode 100644 index 0000000..cc73e25 --- /dev/null +++ b/d3d9_proxy_loader/proxydll.def @@ -0,0 +1,4 @@ +LIBRARY "d3d9" + +EXPORTS + Direct3DCreate9 @1 diff --git a/unlegits.sln b/unlegits.sln index f31bbd0..ac9807b 100644 --- a/unlegits.sln +++ b/unlegits.sln @@ -17,6 +17,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "L2C_Login", "L2C_Login.vcxp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "L2C_Server", "L2C_Server.vcxproj", "{72DC0189-0628-48FC-AA67-A7A279A2A171}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d9_proxy_loader", "d3d9_proxy_loader.vcxproj", "{AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -55,6 +57,10 @@ Global {72DC0189-0628-48FC-AA67-A7A279A2A171}.Debug|Win32.Build.0 = Debug|Win32 {72DC0189-0628-48FC-AA67-A7A279A2A171}.Release|Win32.ActiveCfg = Release|Win32 {72DC0189-0628-48FC-AA67-A7A279A2A171}.Release|Win32.Build.0 = Release|Win32 + {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}.Debug|Win32.Build.0 = Debug|Win32 + {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}.Release|Win32.ActiveCfg = Release|Win32 + {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE