#include "Inject.h" // // Extern Prototypes // extern void __cdecl LogText(const TCHAR*, ...); // // Global Variables // PROCESS_INFORMATION pi; STARTUPINFO si; //########################################################### //## InjectHook() //## //## Launches Fable.exe and injects into the process. //## //## Returns: FALSE(failed), TRUE(success) //########################################################### BOOL InjectHook() { // // Ensure Hook Module Exists // TCHAR tszHookPath[MAX_PATH]; _tfullpath( tszHookPath, "FableHook.dll", MAX_PATH ); if( GetFileAttributes( tszHookPath ) == 0xFFFFFFFF ) { LogText( "[ERROR] Hook was not found!" ); return FALSE; } // // Read Registry For Install Path // DWORD dwDataSize = NULL; HKEY hKey = NULL; TCHAR tszKey[MAX_PATH] = {0}; TCHAR tszGamePath[MAX_PATH] = {0}; _stprintf_s( tszKey, sizeof(tszKey), "SOFTWARE\\Microsoft\\Microsoft Games\\Fable\\1.0" ); if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, tszKey, NULL, KEY_READ, &hKey ) != ERROR_SUCCESS ) { LogText( "[ERROR](Reg): Failed to locate registry entry!" ); return FALSE; } else { DWORD dwType = REG_SZ; if( RegQueryValueEx( hKey, _T("SetupPath"), 0, &dwType, (PBYTE)(LPTSTR)NULL, &dwDataSize ) == ERROR_SUCCESS ) { RegQueryValueEx( hKey, _T("SetupPath"), 0, &dwType, (PBYTE)(LPTSTR)tszGamePath, &dwDataSize ); } else { LogText( "[ERROR](Reg): SetupPath Entry Missing!" ); return FALSE; } } RegCloseKey( hKey ); // // Create Clean Variables // TCHAR tszGameExe[MAX_PATH] = {0}; _tcscat_s( tszGameExe, sizeof(tszGamePath), tszGamePath ); _tcscat_s( tszGameExe, sizeof(tszGameExe), _T("Fable.exe") ); // // Setup Process Launch Variables // ZeroMemory( &si, sizeof(STARTUPINFO) ); #ifdef _DEBUG LogText( "GamePath: %s", tszGamePath ); LogText( "GameExe: %s", tszGameExe ); #endif // // Create Suspended Process // BOOL bResult = CreateProcess( tszGameExe, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED|NORMAL_PRIORITY_CLASS, NULL, tszGamePath, &si, &pi ); if( !bResult ) { LogText( "[ERROR] Failed to launch the process." ); return FALSE; } // // Create Remote Thread And Inject // int iLibModule = 0; LPVOID pLibRemote = VirtualAllocEx( pi.hProcess, NULL, sizeof(tszHookPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE ); WriteProcessMemory( pi.hProcess, pLibRemote, tszHookPath, sizeof(tszHookPath), NULL ); HANDLE hThread = CreateRemoteThread( pi.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)::GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryA"), pLibRemote, 0, NULL ); WaitForSingleObject( hThread, INFINITE ); GetExitCodeThread( hThread, (PDWORD)&iLibModule ); CloseHandle( hThread ); VirtualFreeEx( pi.hProcess, pLibRemote, sizeof(tszHookPath), MEM_RELEASE ); // // Check If Hook Loaded // if( !iLibModule ) { LogText( "[ERROR] Failed to load hook." ); LogText( "[ERROR] Killing suspended process." ); TerminateThread( pi.hThread, 0 ); return FALSE; } else { LogText( "[INFO] Injection successful! Enjoy!" ); ResumeThread( pi.hThread ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return TRUE; } // // Something Went Really Wrong If We Are Here // LogText( "[CRIT] Unknown error in injection!" ); return FALSE; }