Clone of Akilla's acserver @ https://github.com/deregtd/ACServer

ClientInject.cpp 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // ClientInject.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #include "ClientInject.h"
  5. #include <atlbase.h>
  6. #include <stdio.h>
  7. #include <winsock2.h>
  8. static bool bRegisteredInAC = false;
  9. static bool bInitialized = false;
  10. static HMODULE g_hModule = NULL;
  11. BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
  12. {
  13. if ( ul_reason_for_call == DLL_PROCESS_ATTACH )
  14. {
  15. g_hModule = hModule;
  16. DisableThreadLibraryCalls ( hModule );
  17. // Check out the project we're in - if it's client.exe, hook stuff up
  18. TCHAR szFilename[ MAX_PATH ];
  19. ::GetModuleFileName( NULL, szFilename, MAX_PATH );
  20. LPTSTR strProcessName = ::_tcsrchr( szFilename, _T( '\\' ) );
  21. strProcessName[ 7 ] = _T( '\0' );
  22. // if( ::_tcsicmp( strProcessName + 1, _T( "client" ) ) == 0 )
  23. bRegisteredInAC = true;
  24. }
  25. return TRUE;
  26. }
  27. // one instance for all processes
  28. #pragma data_seg( "InjectDll" )
  29. bool g_bError = false;
  30. HWND g_hwAC = 0;
  31. HHOOK g_hHook = NULL;
  32. DWORD g_dwIP = 0;
  33. DWORD g_sConnPort = 0;
  34. DWORD g_szUsername = 0,
  35. g_szUsername1 = 0,
  36. g_szUsername2 = 0,
  37. g_szUsername3 = 0,
  38. g_szUsername4 = 0,
  39. g_szUsername5 = 0,
  40. g_szUsername6 = 0,
  41. g_szUsername7 = 0,
  42. g_szUsername8 = 0,
  43. g_szUsername9 = 0;
  44. DWORD g_szPassword = 0,
  45. g_szPassword1 = 0,
  46. g_szPassword2 = 0,
  47. g_szPassword3 = 0,
  48. g_szPassword4 = 0,
  49. g_szPassword5 = 0,
  50. g_szPassword6 = 0,
  51. g_szPassword7 = 0,
  52. g_szPassword8 = 0,
  53. g_szPassword9 = 0;
  54. #pragma data_seg()
  55. typedef void (*AdapterInitFn)( DWORD dwIP, char *, char *, short );
  56. // The hook function - all it does is continue calls
  57. LRESULT CALLBACK hookCBTProc( int nCode, WPARAM wParam, LPARAM lParam )
  58. {
  59. LRESULT lr = ::CallNextHookEx ( g_hHook, nCode, wParam, lParam );
  60. if ( !bRegisteredInAC )
  61. return lr;
  62. if ( bInitialized )
  63. // Prevent recursion from wiping us out
  64. return lr;
  65. if (nCode != HCBT_CREATEWND)
  66. return lr;
  67. CBT_CREATEWND *cbtcw = (CBT_CREATEWND *) lParam;
  68. CREATESTRUCT *cs = cbtcw->lpcs;
  69. char gwt[256]; GetWindowText((HWND) wParam, gwt, 255);
  70. if (stricmp(cs->lpszName, "Error") == 0)
  71. {
  72. g_bError = true;
  73. HANDLE hEvent = ::OpenEvent ( EVENT_ALL_ACCESS, FALSE, _T( "ACEmuClientExecuted" ) );
  74. if ( hEvent != NULL )
  75. {
  76. ::SetEvent ( hEvent );
  77. ::CloseHandle ( hEvent );
  78. }
  79. g_hwAC = (HWND) wParam;
  80. return lr;
  81. }
  82. if (stricmp(cs->lpszName, "Asheron's Call") != 0)
  83. return lr;
  84. g_hwAC = (HWND) wParam;
  85. bInitialized = true;
  86. // Assume client adapter is in the same directly as this DLL
  87. TCHAR szPath[ MAX_PATH ];
  88. ::GetModuleFileName ( g_hModule, szPath, MAX_PATH );
  89. LPTSTR strModuleName = ::_tcsrchr( szPath, _T( '\\' ) );
  90. ::_tcscpy ( strModuleName + 1, _T( "ClientAdapter.dll" ) );
  91. HMODULE hMod = ::LoadLibrary ( szPath );
  92. if ( hMod != NULL )
  93. {
  94. AdapterInitFn fninit = reinterpret_cast< AdapterInitFn > ( ::GetProcAddress ( hMod, _T( "InitClientAdapter" ) ) );
  95. if ( fninit != NULL )
  96. fninit ( g_dwIP, reinterpret_cast< char * > ( &g_szUsername ), reinterpret_cast< char * > ( &g_szPassword ), (short) g_sConnPort );
  97. } else {
  98. MessageBox(NULL, "Error loading CLIENTADAPTER.DLL! Make sure it's in the same directory as the login client!", "ClientInject Error", MB_OK);
  99. }
  100. // Otherwise, set the event indicating startup and return
  101. HANDLE hEvent = ::OpenEvent ( EVENT_ALL_ACCESS, FALSE, _T( "ACEmuClientExecuted" ) );
  102. if ( hEvent != NULL )
  103. {
  104. ::SetEvent ( hEvent );
  105. ::CloseHandle ( hEvent );
  106. }
  107. return lr;
  108. }
  109. void executeClient ( DWORD dwIP, char *szUsername, char *szPassword, short ConnPort, char *szClientPath )
  110. {
  111. // Install the global hook, injecting this DLL into every other process
  112. HANDLE hEvent = ::CreateEvent ( NULL, TRUE, FALSE, _T( "ACEmuClientExecuted" ) );
  113. g_dwIP = dwIP;
  114. ::strcpy ( reinterpret_cast< char * > ( &g_szUsername ), szUsername );
  115. ::strcpy ( reinterpret_cast< char * > ( &g_szPassword ), szPassword );
  116. g_sConnPort = ConnPort;
  117. g_hHook = ::SetWindowsHookEx ( WH_CBT, hookCBTProc, g_hModule, 0 );
  118. if ( g_hHook == NULL )
  119. {
  120. DWORD dwError = ::GetLastError ();
  121. }
  122. // Locate and execute the client.exe process with a fancy command line
  123. TCHAR szCommandLine[ 2048 ];
  124. in_addr addr;
  125. addr.S_un.S_addr = dwIP;
  126. char *addrout = inet_ntoa ( addr );
  127. ::_stprintf ( szCommandLine, _T( "%s -h %s -p %i" ), szClientPath,
  128. addrout, ConnPort );
  129. STARTUPINFO si = { sizeof ( STARTUPINFO ), };
  130. PROCESS_INFORMATION pi;
  131. HKEY keyout;
  132. RegCreateKey(HKEY_CURRENT_USER, "Software\\AcEmu\\Client", &keyout);
  133. if (keyout)
  134. {
  135. TCHAR szServer[ 255 ];
  136. sprintf(szServer, "Couldn't Execute Client");
  137. RegSetValue(keyout, "ExitMessage", REG_SZ, szServer, strlen(szServer));
  138. RegCloseKey(keyout);
  139. }
  140. char szClientPathDir[255];
  141. strcpy(szClientPathDir, szClientPath);
  142. *strrchr(szClientPathDir,'\\') = 0;
  143. if ( CreateProcess ( NULL, szCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, szClientPathDir, &si, &pi ) )
  144. {
  145. // Wait for client startup
  146. ::WaitForSingleObject ( hEvent, INFINITE );
  147. ::CloseHandle ( pi.hThread );
  148. ::CloseHandle ( pi.hProcess );
  149. } else {
  150. MessageBox(NULL, "Error Launching Client", "Login Client", MB_OK);
  151. ::UnhookWindowsHookEx( g_hHook );
  152. g_hHook = NULL;
  153. return;
  154. }
  155. // Cleanup
  156. ::UnhookWindowsHookEx( g_hHook );
  157. g_hHook = NULL;
  158. /* if (g_bError)
  159. {
  160. char thisdir[255], backtologin[255];
  161. GetModuleFileName(g_hModule, thisdir, 255);
  162. *strrchr(thisdir,'\\') = 0;
  163. sprintf(backtologin, "%s\\ClientLogon.exe",thisdir);
  164. WinExec(backtologin, SW_SHOW);
  165. return;
  166. }
  167. */
  168. Sleep(1);
  169. if (g_bError)
  170. {
  171. for ( ;; )
  172. {
  173. char lala[256];
  174. int tpw = GetWindowText(g_hwAC, lala, 255);
  175. if (!tpw)
  176. break;
  177. Sleep(500);
  178. }
  179. } else {
  180. for ( ;; )
  181. {
  182. char lala[256];
  183. int tpw = GetClassName(g_hwAC, lala, 255);
  184. if (!tpw)
  185. break;
  186. Sleep(500);
  187. }
  188. }
  189. if (!g_bError)
  190. {
  191. //Read exit message from client
  192. RegCreateKey(HKEY_CURRENT_USER, "Software\\AcEmu\\Client", &keyout);
  193. if (keyout)
  194. {
  195. TCHAR szServer[ 255 ]; long dwSize = 255;
  196. if (RegQueryValue(keyout, "ExitMessage", szServer, &dwSize) == ERROR_SUCCESS)
  197. {
  198. if (stricmp(szServer, "Success") != 0)
  199. MessageBox(NULL, szServer, "Client Message", MB_OK | MB_ICONEXCLAMATION);
  200. }
  201. RegCloseKey(keyout);
  202. }
  203. }
  204. char thisdir[255], backtologin[255];
  205. GetModuleFileName(g_hModule, thisdir, 255);
  206. *strrchr(thisdir,'\\') = 0;
  207. sprintf(backtologin, "%s\\ClientLogon.exe",thisdir);
  208. WinExec(backtologin, SW_SHOW);
  209. }