public void Dispose() { // Order is important here. // If eject crashes the process, exception here throws and tests fail. Injector32.Eject(InjectModule32); Injector64.Eject(InjectModule64); Target32?.Kill(); Target32?.Dispose(); Target64?.Kill(); Target64?.Dispose(); }
private static void RuntimeHook(string[] args, int i, bool is64) { int.TryParse(args[i++], out int InTargetPID); int.TryParse(args[i++], out int InWakeUpTID); int.TryParse(args[i++], out int InInjectionOptions); string InLibraryPath_x86 = args[i++]; string InLibraryPath_x64 = args[i++]; //IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); int.TryParse(args[i++], out int hWnd); bool.TryParse(args[i++], out bool hookFocus); bool.TryParse(args[i++], out bool hideCursor); bool.TryParse(args[i++], out bool isDebug); string nucleusFolderPath = args[i++]; bool.TryParse(args[i++], out bool setWindow); bool.TryParse(args[i++], out bool preventWindowDeactivation); int.TryParse(args[i++], out int width); int.TryParse(args[i++], out int height); int.TryParse(args[i++], out int posx); int.TryParse(args[i++], out int posy); int.TryParse(args[i++], out int controllerIndex); bool.TryParse(args[i++], out bool setCursorPos); bool.TryParse(args[i++], out bool getCursorPos); bool.TryParse(args[i++], out bool getKeyState); bool.TryParse(args[i++], out bool getAsyncKeyState); bool.TryParse(args[i++], out bool getKeyboardState); bool.TryParse(args[i++], out bool filterRawInput); bool.TryParse(args[i++], out bool filterMouseMessages); bool.TryParse(args[i++], out bool legacyInput); bool.TryParse(args[i++], out bool updateAbsoluteFlagInMouseMessage); bool.TryParse(args[i++], out bool mouseVisibilitySendBack); bool.TryParse(args[i++], out bool reRegisterRawInput); bool.TryParse(args[i++], out bool reRegisterRawInputMouse); bool.TryParse(args[i++], out bool reRegisterRawInputKeyboard); bool.TryParse(args[i++], out bool hookXinput); bool.TryParse(args[i++], out bool dinputToXinputTranslation); string writePipeName = args[i++]; string readPipeName = args[i++]; int.TryParse(args[i++], out int allowedRawMouseHandle); int.TryParse(args[i++], out int allowedRawKeyboardHandle); var logPath = Encoding.Unicode.GetBytes(nucleusFolderPath); int logPathLength = logPath.Length; //int.TryParse(args[i++], out int InPassThruSize); var writePipeNameBytes = Encoding.Unicode.GetBytes(writePipeName); int writePipeNameLength = writePipeNameBytes.Length; var readPipeNameBytes = Encoding.Unicode.GetBytes(readPipeName); int readPipeNameLength = readPipeNameBytes.Length; int size = 256 + logPathLength + writePipeNameLength + readPipeNameLength; IntPtr intPtr = Marshal.AllocHGlobal(size); byte[] dataToSend = new byte[size]; int index = 0; dataToSend[index++] = (byte)(hWnd >> 24); dataToSend[index++] = (byte)(hWnd >> 16); dataToSend[index++] = (byte)(hWnd >> 8); dataToSend[index++] = (byte)(hWnd); dataToSend[index++] = (byte)(allowedRawMouseHandle >> 24); dataToSend[index++] = (byte)(allowedRawMouseHandle >> 16); dataToSend[index++] = (byte)(allowedRawMouseHandle >> 8); dataToSend[index++] = (byte)(allowedRawMouseHandle); dataToSend[index++] = (byte)(allowedRawKeyboardHandle >> 24); dataToSend[index++] = (byte)(allowedRawKeyboardHandle >> 16); dataToSend[index++] = (byte)(allowedRawKeyboardHandle >> 8); dataToSend[index++] = (byte)(allowedRawKeyboardHandle); byte Bool_1_0(bool x) => x ? (byte)1 : (byte)0; dataToSend[index++] = Bool_1_0(preventWindowDeactivation); dataToSend[index++] = Bool_1_0(setWindow); dataToSend[index++] = Bool_1_0(isDebug); dataToSend[index++] = Bool_1_0(hideCursor); dataToSend[index++] = Bool_1_0(hookFocus); dataToSend[index++] = Bool_1_0(setCursorPos); dataToSend[index++] = Bool_1_0(getCursorPos); dataToSend[index++] = Bool_1_0(getKeyState); dataToSend[index++] = Bool_1_0(getAsyncKeyState); dataToSend[index++] = Bool_1_0(getKeyboardState); dataToSend[index++] = Bool_1_0(filterRawInput); dataToSend[index++] = Bool_1_0(filterMouseMessages); dataToSend[index++] = Bool_1_0(legacyInput); dataToSend[index++] = Bool_1_0(updateAbsoluteFlagInMouseMessage); dataToSend[index++] = Bool_1_0(mouseVisibilitySendBack); dataToSend[index++] = Bool_1_0(reRegisterRawInput); dataToSend[index++] = Bool_1_0(reRegisterRawInputMouse); dataToSend[index++] = Bool_1_0(reRegisterRawInputKeyboard); dataToSend[index++] = Bool_1_0(hookXinput); dataToSend[index++] = Bool_1_0(dinputToXinputTranslation); dataToSend[index++] = (byte)(logPathLength >> 24); dataToSend[index++] = (byte)(logPathLength >> 16); dataToSend[index++] = (byte)(logPathLength >> 8); dataToSend[index++] = (byte)logPathLength; dataToSend[index++] = (byte)(writePipeNameLength >> 24); dataToSend[index++] = (byte)(writePipeNameLength >> 16); dataToSend[index++] = (byte)(writePipeNameLength >> 8); dataToSend[index++] = (byte)writePipeNameLength; dataToSend[index++] = (byte)(readPipeNameLength >> 24); dataToSend[index++] = (byte)(readPipeNameLength >> 16); dataToSend[index++] = (byte)(readPipeNameLength >> 8); dataToSend[index++] = (byte)readPipeNameLength; dataToSend[index++] = (byte)(width >> 24); dataToSend[index++] = (byte)(width >> 16); dataToSend[index++] = (byte)(width >> 8); dataToSend[index++] = (byte)width; dataToSend[index++] = (byte)(height >> 24); dataToSend[index++] = (byte)(height >> 16); dataToSend[index++] = (byte)(height >> 8); dataToSend[index++] = (byte)height; dataToSend[index++] = (byte)(posx >> 24); dataToSend[index++] = (byte)(posx >> 16); dataToSend[index++] = (byte)(posx >> 8); dataToSend[index++] = (byte)posx; dataToSend[index++] = (byte)(posy >> 24); dataToSend[index++] = (byte)(posy >> 16); dataToSend[index++] = (byte)(posy >> 8); dataToSend[index++] = (byte)posy; dataToSend[index++] = (byte)(controllerIndex >> 24); dataToSend[index++] = (byte)(controllerIndex >> 16); dataToSend[index++] = (byte)(controllerIndex >> 8); dataToSend[index++] = (byte)controllerIndex; Array.Copy(logPath, 0, dataToSend, index, logPathLength); Array.Copy(writePipeNameBytes, 0, dataToSend, index + logPathLength, writePipeNameLength); Array.Copy(readPipeNameBytes, 0, dataToSend, index + logPathLength + writePipeNameLength, readPipeNameLength); Marshal.Copy(dataToSend, 0, intPtr, size); try { if (is64) { Injector64.RhInjectLibrary((uint)InTargetPID, (uint)InWakeUpTID, (uint)InInjectionOptions, "", InLibraryPath_x64, intPtr, (uint)size); } else { Injector32.RhInjectLibrary((uint)InTargetPID, (uint)InWakeUpTID, (uint)InInjectionOptions, InLibraryPath_x86, "", intPtr, (uint)size); } } catch (Exception ex) { Log("ERROR - " + ex.Message); } }
private static void StartupHook(string[] args, int i, bool is64) { string InEXEPath = args[i++]; string InCommandLine = args[i++]; uint.TryParse(args[i++], out uint InProcessCreationFlags); uint.TryParse(args[i++], out uint InInjectionOptions); string InLibraryPath_x86 = args[i++]; string InLibraryPath_x64 = args[i++]; bool.TryParse(args[i++], out bool hookWindow); // E.g. FindWindow, etc bool.TryParse(args[i++], out bool renameMutex); string mutexToRename = args[i++]; bool.TryParse(args[i++], out bool setWindow); bool.TryParse(args[i++], out bool isDebug); string nucleusFolderPath = args[i++]; bool.TryParse(args[i++], out bool blockRaw); bool.TryParse(args[i++], out bool useCustomEnvironment); string playerNick = args[i++]; bool.TryParse(args[i++], out bool createSingle); string rawHid = args[i++]; int.TryParse(args[i++], out int width); int.TryParse(args[i++], out int height); int.TryParse(args[i++], out int posx); int.TryParse(args[i++], out int posy); string docpath = args[i++]; bool.TryParse(args[i++], out bool useDocs); //IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); //uint.TryParse(args[i++], out uint InPassThruSize); IntPtr envPtr = IntPtr.Zero; if (useCustomEnvironment) { Log("Setting up Nucleus environment"); string NucleusEnvironmentRoot = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); //string DocumentsRoot = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); IDictionary envVars = Environment.GetEnvironmentVariables(); var sb = new StringBuilder(); //var username = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile).Replace(@"C:\Users\", ""); string username = WindowsIdentity.GetCurrent().Name.Split('\\')[1]; envVars["USERPROFILE"] = $@"{NucleusEnvironmentRoot}\NucleusCoop\{playerNick}"; envVars["HOMEPATH"] = $@"\Users\{username}\NucleusCoop\{playerNick}"; envVars["APPDATA"] = $@"{NucleusEnvironmentRoot}\NucleusCoop\{playerNick}\AppData\Roaming"; envVars["LOCALAPPDATA"] = $@"{NucleusEnvironmentRoot}\NucleusCoop\{playerNick}\AppData\Local"; //Some games will crash if the directories don't exist Directory.CreateDirectory($@"{NucleusEnvironmentRoot}\NucleusCoop"); Directory.CreateDirectory(envVars["USERPROFILE"].ToString()); Directory.CreateDirectory(Path.Combine(envVars["USERPROFILE"].ToString(), "Documents")); Directory.CreateDirectory(envVars["APPDATA"].ToString()); Directory.CreateDirectory(envVars["LOCALAPPDATA"].ToString()); Directory.CreateDirectory(Path.GetDirectoryName(docpath) + $@"\NucleusCoop\{playerNick}\Documents"); if (useDocs) { if (!File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), @"utils\backup\User Shell Folders.reg"))) { //string mydocPath = key.GetValue("Personal").ToString(); ExportRegistry(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), @"utils\backup\User Shell Folders.reg")); } RegistryKey dkey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", true); dkey.SetValue("Personal", Path.GetDirectoryName(docpath) + $@"\NucleusCoop\{playerNick}\Documents", (RegistryValueKind)(int)RegType.ExpandString); } foreach (object envVarKey in envVars.Keys) { if (envVarKey != null) { string key = envVarKey.ToString(); string value = envVars[envVarKey].ToString(); sb.Append(key); sb.Append("="); sb.Append(value); sb.Append("\0"); } } sb.Append("\0"); byte[] envBytes = Encoding.Unicode.GetBytes(sb.ToString()); envPtr = Marshal.AllocHGlobal(envBytes.Length); Marshal.Copy(envBytes, 0, envPtr, envBytes.Length); Thread.Sleep(1000); } var logPath = Encoding.Unicode.GetBytes(nucleusFolderPath); int logPathLength = logPath.Length; var targetsBytes = Encoding.Unicode.GetBytes(mutexToRename); int targetsBytesLength = targetsBytes.Length; var rawHidBytes = Encoding.Unicode.GetBytes(rawHid); int rawHidBytesLength = rawHidBytes.Length; var playerNickBytes = Encoding.Unicode.GetBytes(playerNick); int playerNickLength = playerNickBytes.Length; int size = 48 + logPathLength + targetsBytesLength + rawHidBytesLength + playerNickLength; var data = new byte[size]; data[0] = hookWindow == true ? (byte)1 : (byte)0; data[1] = renameMutex == true ? (byte)1 : (byte)0; data[2] = setWindow == true ? (byte)1 : (byte)0; data[3] = isDebug == true ? (byte)1 : (byte)0; data[4] = blockRaw == true ? (byte)1 : (byte)0; data[5] = createSingle == true ? (byte)1 : (byte)0; data[6] = (byte)(rawHidBytesLength >> 24); data[7] = (byte)(rawHidBytesLength >> 16); data[8] = (byte)(rawHidBytesLength >> 8); data[9] = (byte)rawHidBytesLength; data[10] = (byte)(logPathLength >> 24); data[11] = (byte)(logPathLength >> 16); data[12] = (byte)(logPathLength >> 8); data[13] = (byte)logPathLength; data[14] = (byte)(targetsBytesLength >> 24); data[15] = (byte)(targetsBytesLength >> 16); data[16] = (byte)(targetsBytesLength >> 8); data[17] = (byte)targetsBytesLength; data[18] = (byte)(width >> 24); data[19] = (byte)(width >> 16); data[20] = (byte)(width >> 8); data[21] = (byte)width; data[22] = (byte)(height >> 24); data[23] = (byte)(height >> 16); data[24] = (byte)(height >> 8); data[25] = (byte)height; data[26] = (byte)(posx >> 24); data[27] = (byte)(posx >> 16); data[28] = (byte)(posx >> 8); data[29] = (byte)posx; data[30] = (byte)(posy >> 24); data[31] = (byte)(posy >> 16); data[32] = (byte)(posy >> 8); data[33] = (byte)posy; data[34] = (byte)(playerNickLength >> 24); data[35] = (byte)(playerNickLength >> 16); data[36] = (byte)(playerNickLength >> 8); data[37] = (byte)playerNickLength; Array.Copy(logPath, 0, data, 38, logPathLength); Array.Copy(targetsBytes, 0, data, 39 + logPathLength, targetsBytesLength); Array.Copy(rawHidBytes, 0, data, 40 + logPathLength + targetsBytesLength, rawHidBytesLength); Array.Copy(playerNickBytes, 0, data, 41 + logPathLength + targetsBytesLength + rawHidBytesLength, playerNickLength); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); IntPtr pid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))); bool isFailed = false; try { int result = -1; int attempts = 0; // 5 attempts to inject const int maxAttempts = 5; while (result != 0) { //if (procid > 0) //{ // string currDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // if (is64) // result = Injector64.RhInjectLibrary(procid, 0, 0, null, Path.Combine(currDir, "Nucleus.SHook64.dll"), ptr, (uint)size); // else // result = Injector32.RhInjectLibrary(procid, 0, 0, Path.Combine(currDir, "Nucleus.SHook32.dll"), null, ptr, (uint)size); // if (result != 0) // { // Log("Attempt " + (attempts + 1) + "/5 Failed to inject start up hook dll. Result code: " + result); // } //} //else //{ if (is64) { //Log("is64 " + InEXEPath + " " + InCommandLine + " " + InProcessCreationFlags + " " + envPtr + " " + InInjectionOptions + " " + InLibraryPath_x64 + " " + ptr + " " + (uint)size + " " + pid); result = Injector64.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, envPtr, InInjectionOptions, "", InLibraryPath_x64, ptr, (uint)size, pid); } else { //Log("isNOT64 " + InEXEPath + " " + InCommandLine + " " + InProcessCreationFlags + " " + envPtr + " " + InInjectionOptions + " " + InLibraryPath_x86 + " " + ptr + " " + (uint)size + " " + pid); result = Injector32.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, envPtr, InInjectionOptions, InLibraryPath_x86, "", ptr, (uint)size, pid); } Thread.Sleep(1000); Log("CreateAndInject result code: " + result); if (result != 0) { Log("Attempt " + (attempts + 1) + "/5 Failed to create process and inject start up hook dll. Result code: " + result); } //} Thread.Sleep(1000); if (++attempts == maxAttempts) { isFailed = true; break; } } Marshal.FreeHGlobal(pid); if (isFailed) { Log("CreateAndInject failed"); Console.WriteLine("injectfailed"); } else { //if (procid == 0) Log("CreateAndInject successful, returning " + Marshal.ReadInt32(pid)); Console.WriteLine(Marshal.ReadInt32(pid)); //else //Console.WriteLine(procid); } } catch (Exception ex) { Log(string.Format("ERROR - {0}", ex.Message)); Console.WriteLine("injectfailed"); } //Marshal.FreeHGlobal(pid); //Console.WriteLine(Marshal.ReadInt32(pid).ToString()); }
private static void StartupHook(string[] args, int i, bool is64) { string InEXEPath = args[i++]; string InCommandLine = args[i++]; uint.TryParse(args[i++], out uint InProcessCreationFlags); uint.TryParse(args[i++], out uint InInjectionOptions); string InLibraryPath_x86 = args[i++]; string InLibraryPath_x64 = args[i++]; bool.TryParse(args[i++], out bool hookWindow); // E.g. FindWindow, etc bool.TryParse(args[i++], out bool renameMutex); string mutexToRename = args[i++]; bool.TryParse(args[i++], out bool setWindow); bool.TryParse(args[i++], out bool isDebug); string nucleusFolderPath = args[i++]; bool.TryParse(args[i++], out bool blockRaw); bool.TryParse(args[i++], out bool useCustomEnvironment); string playerNick = args[i++]; bool.TryParse(args[i++], out bool createSingle); string rawHid = args[i++]; //IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); //uint.TryParse(args[i++], out uint InPassThruSize); IntPtr envPtr = IntPtr.Zero; if (useCustomEnvironment) { Log("Setting up Nucleus environment"); IDictionary envVars = Environment.GetEnvironmentVariables(); var sb = new StringBuilder(); var username = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile).Replace(@"C:\Users\", ""); envVars["USERPROFILE"] = $@"C:\Users\{username}\NucleusCoop\{playerNick}"; envVars["HOMEPATH"] = $@"\Users\{username}\NucleusCoop\{playerNick}"; envVars["APPDATA"] = $@"C:\Users\{username}\NucleusCoop\{playerNick}\AppData\Roaming"; envVars["LOCALAPPDATA"] = $@"C:\Users\{username}\NucleusCoop\{playerNick}\AppData\Local"; //Some games will crash if the directories don't exist Directory.CreateDirectory($@"C:\Users\{username}\NucleusCoop"); Directory.CreateDirectory(envVars["USERPROFILE"].ToString()); Directory.CreateDirectory(Path.Combine(envVars["USERPROFILE"].ToString(), "Documents")); Directory.CreateDirectory(envVars["APPDATA"].ToString()); Directory.CreateDirectory(envVars["LOCALAPPDATA"].ToString()); foreach (object envVarKey in envVars.Keys) { if (envVarKey != null) { string key = envVarKey.ToString(); string value = envVars[envVarKey].ToString(); sb.Append(key); sb.Append("="); sb.Append(value); sb.Append("\0"); } } sb.Append("\0"); byte[] envBytes = Encoding.Unicode.GetBytes(sb.ToString()); envPtr = Marshal.AllocHGlobal(envBytes.Length); Marshal.Copy(envBytes, 0, envPtr, envBytes.Length); } var logPath = Encoding.Unicode.GetBytes(nucleusFolderPath); int logPathLength = logPath.Length; var targetsBytes = Encoding.Unicode.GetBytes(mutexToRename); int targetsBytesLength = targetsBytes.Length; var rawHidBytes = Encoding.Unicode.GetBytes(rawHid); int rawHidBytesLength = rawHidBytes.Length; int size = 28 + logPathLength + targetsBytesLength + rawHidBytesLength; var data = new byte[size]; data[0] = hookWindow == true ? (byte)1 : (byte)0; data[1] = renameMutex == true ? (byte)1 : (byte)0; data[2] = setWindow == true ? (byte)1 : (byte)0; data[3] = isDebug == true ? (byte)1 : (byte)0; data[4] = blockRaw == true ? (byte)1 : (byte)0; data[5] = createSingle == true ? (byte)1 : (byte)0; data[6] = (byte)(rawHidBytesLength >> 24); data[7] = (byte)(rawHidBytesLength >> 16); data[8] = (byte)(rawHidBytesLength >> 8); data[9] = (byte)rawHidBytesLength; data[10] = (byte)(logPathLength >> 24); data[11] = (byte)(logPathLength >> 16); data[12] = (byte)(logPathLength >> 8); data[13] = (byte)logPathLength; data[14] = (byte)(targetsBytesLength >> 24); data[15] = (byte)(targetsBytesLength >> 16); data[16] = (byte)(targetsBytesLength >> 8); data[17] = (byte)targetsBytesLength; Array.Copy(logPath, 0, data, 18, logPathLength); Array.Copy(targetsBytes, 0, data, 19 + logPathLength, targetsBytesLength); Array.Copy(rawHidBytes, 0, data, 20 + logPathLength + targetsBytesLength, rawHidBytesLength); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); IntPtr pid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))); bool isFailed = false; try { int result = -1; int attempts = 0; // 5 attempts to inject const int maxAttempts = 5; while (result != 0) { //if (procid > 0) //{ // string currDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // if (is64) // result = Injector64.RhInjectLibrary(procid, 0, 0, null, Path.Combine(currDir, "Nucleus.SHook64.dll"), ptr, (uint)size); // else // result = Injector32.RhInjectLibrary(procid, 0, 0, Path.Combine(currDir, "Nucleus.SHook32.dll"), null, ptr, (uint)size); // if (result != 0) // { // Log("Attempt " + (attempts + 1) + "/5 Failed to inject start up hook dll. Result code: " + result); // } //} //else //{ if (is64) { result = Injector64.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, envPtr, InInjectionOptions, "", InLibraryPath_x64, ptr, (uint)size, pid); } else { result = Injector32.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, envPtr, InInjectionOptions, InLibraryPath_x86, "", ptr, (uint)size, pid); } Thread.Sleep(1000); Log("CreateAndInject result code: " + result); if (result != 0) { Log("Attempt " + (attempts + 1) + "/5 Failed to create process and inject start up hook dll. Result code: " + result); } //} Thread.Sleep(1000); if (++attempts == maxAttempts) { isFailed = true; break; } } Marshal.FreeHGlobal(pid); if (isFailed) { Log("CreateAndInject failed"); Console.WriteLine("injectfailed"); } else { //if (procid == 0) Log("CreateAndInject successful, returning " + Marshal.ReadInt32(pid)); Console.WriteLine(Marshal.ReadInt32(pid)); //else //Console.WriteLine(procid); } } catch (Exception ex) { Log(string.Format("ERROR - {0}", ex.Message)); Console.WriteLine("injectfailed"); } //Marshal.FreeHGlobal(pid); //Console.WriteLine(Marshal.ReadInt32(pid).ToString()); }
private static int CreateAndInjectStartupHook(string hookDllPath, string exePath, string base64CommandLineArgs, bool useAppdataSwitch, int appdataSwitchIndex, bool dinputHookEnabled, bool findWindowHookEnabled, byte controllerIndex, bool findMutexHookEnabled, string mutexTargets) { string cmdLineArgs = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(base64CommandLineArgs)); IntPtr pOutPID = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint))); //"hl2_singleton_mutex&&&&&ValveHalfLifeLauncherMutex&&&&&Overkill Engine Game" var targetsBytes = Encoding.Unicode.GetBytes(mutexTargets); int targetsBytesLength = targetsBytes.Length; int size = 64 + targetsBytesLength; var data = new byte[size]; data[0] = dinputHookEnabled ? (byte)1 : (byte)0; data[1] = findWindowHookEnabled ? (byte)1 : (byte)0; data[2] = controllerIndex; data[3] = useAppdataSwitch ? (byte)0 : (byte)1; data[4] = findMutexHookEnabled ? (byte)1 : (byte)0; data[5] = (byte)(targetsBytesLength >> 24); data[6] = (byte)(targetsBytesLength >> 16); data[7] = (byte)(targetsBytesLength >> 8); data[8] = (byte)targetsBytesLength; Array.Copy(targetsBytes, 0, data, 9, targetsBytesLength); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); if (!(appdataSwitchIndex > 0 && useAppdataSwitch)) { int ret = Environment.Is64BitProcess ? Injector64.RhCreateAndInject(exePath, cmdLineArgs, 0, 0, "", hookDllPath, ptr, (uint)size, pOutPID) : Injector32.RhCreateAndInject(exePath, cmdLineArgs, 0, 0, hookDllPath, "", ptr, (uint)size, pOutPID); return(ret); } var appdataIndex = "index" + appdataSwitchIndex; var sb = new StringBuilder(); IDictionary envVars = Environment.GetEnvironmentVariables(); var username = Environment.UserName; envVars["USERPROFILE"] = $@"C:\Users\{username}\UniversalSplitScreen\{appdataIndex}"; envVars["HOMEPATH"] = $@"\Users\{username}\UniversalSplitScreen\{appdataIndex}"; envVars["APPDATA"] = $@"C:\Users\{username}\UniversalSplitScreen\{appdataIndex}\AppData\Roaming"; envVars["LOCALAPPDATA"] = $@"C:\Users\{username}\UniversalSplitScreen\{appdataIndex}\AppData\Local"; //Some games will crash if the directories don't exist Directory.CreateDirectory(envVars["USERPROFILE"].ToString()); Directory.CreateDirectory(Path.Combine(envVars["USERPROFILE"].ToString(), "Documents")); Directory.CreateDirectory(envVars["APPDATA"].ToString()); Directory.CreateDirectory(envVars["LOCALAPPDATA"].ToString()); foreach (object envVarKey in envVars.Keys) { if (envVarKey != null) { string key = envVarKey.ToString(); string value = envVars[envVarKey].ToString(); sb.Append(key); sb.Append("="); sb.Append(value); sb.Append("\0"); } } sb.Append("\0"); byte[] envBytes = Encoding.Unicode.GetBytes(sb.ToString()); IntPtr envPtr = Marshal.AllocHGlobal(envBytes.Length); Marshal.Copy(envBytes, 0, envPtr, envBytes.Length); string directoryPath = Path.GetDirectoryName(exePath); STARTUPINFO startup = new STARTUPINFO(); startup.cb = Marshal.SizeOf(startup); //startup.dwFlags = 0x1;//STARTF_USESHOWWINDOW //startup.wShowWindow = 1;//SW_SHOWNORMAL bool success = CreateProcess(exePath, cmdLineArgs, IntPtr.Zero, IntPtr.Zero, false, 0x00000004 | 0x00000400, //Suspended | CREATE_UNICODE_ENVIRONMENT envPtr, directoryPath, ref startup, out PROCESS_INFORMATION processInformation); if (!success) { return(-1); } int injectResult = Environment.Is64BitProcess ? Injector64.RhInjectLibrary((uint)processInformation.dwProcessId, 0, 0, "", hookDllPath, ptr, (uint)size) : Injector32.RhInjectLibrary((uint)processInformation.dwProcessId, 0, 0, hookDllPath, "", ptr, (uint)size); ResumeThread(processInformation.hThread); return(injectResult); }
public static void Main(string[] args) { const int argsLengthHooksCPP = 20; const int argsLengthStartupHook = 10; //dllpath, exePath, base64CmdArgs, useAppdataSwitch, appdataSwitchIndex, dinputHookEnabled, findWindowHookEnabled, controllerIndex, findMutexHookEnabled, mutexTargets if (args.Length == argsLengthStartupHook) { bool Bfs(string s) => s.ToLower().Equals("true"); int ntFwh = CreateAndInjectStartupHook( args[0], args[1], args[2], Bfs(args[3]), int.Parse(args[4]), Bfs(args[5]), Bfs(args[6]), byte.Parse(args[7]), Bfs(args[8]), args[9] ); Environment.Exit(ntFwh); return; } if (args.Length != argsLengthHooksCPP) { throw new ArgumentException($"Need exactly {argsLengthHooksCPP} arguments"); } //Arguments int i = 0; int.TryParse(args[i++], out int pid); string injectionDllPath = args[i++]; int.TryParse(args[i++], out int _hWnd); IntPtr hWnd = (IntPtr)_hWnd; string ipcChannelNameRead = args[i++]; string ipcChannelNameWrite = args[i++]; int.TryParse(args[i++], out int controllerIndex); int.TryParse(args[i++], out int allowedMouseHandle); bool updateAbsoluteFlagInMouseMessage = args[i++].ToLower().Equals("true"); bool useLegacyInput = args[i++].ToLower().Equals("true"); bool nextBool() => args[i++].ToLower().Equals("true"); bool HookGetCursorPos = nextBool(); bool HookGetForegroundWindow = nextBool(); bool HookGetAsyncKeyState = nextBool(); bool HookGetKeyState = nextBool(); bool HookGetKeyboardState = nextBool(); bool HookCallWindowProcW = nextBool(); bool HookRegisterRawInputDevices = nextBool(); bool HookSetCursorPos = nextBool(); bool HookXInput = nextBool(); bool hookMouseVisibility = nextBool(); bool HookDInput = nextBool(); const int size = 1024; byte[] data = new byte[size]; byte[] toByteArray(string str) { List <byte> c = str.ToCharArray().Select(_x => (byte)_x).ToList(); for (int _i = c.Count; _i < 256; _i++) { c.Add(0); } return(c.ToArray()); } void writeInt(int num, int offset) { data[offset] = (byte)(num >> 24); data[offset + 1] = (byte)(num >> 16); data[offset + 2] = (byte)(num >> 8); data[offset + 3] = (byte)(num); } void writeBool(bool b, int offset) { data[offset] = b == true ? (byte)1 : (byte)0; } var str1 = toByteArray(ipcChannelNameRead); for (int j = 0; j < str1.Length; j++) { data[j] = str1[j]; } var str2 = toByteArray(ipcChannelNameWrite); for (int j = 0; j < str1.Length; j++) { data[256 + j] = str2[j]; } writeInt((int)hWnd, 512); writeInt(controllerIndex, 516); writeInt(allowedMouseHandle, 520); int x = 524; writeBool(updateAbsoluteFlagInMouseMessage, x++); writeBool(HookGetCursorPos, x++); writeBool(HookGetForegroundWindow, x++); writeBool(HookGetAsyncKeyState, x++); writeBool(HookGetKeyState, x++); writeBool(HookGetKeyboardState, x++); writeBool(HookCallWindowProcW, x++); writeBool(HookRegisterRawInputDevices, x++); writeBool(HookSetCursorPos, x++); writeBool(HookXInput, x++); writeBool(useLegacyInput, x++); writeBool(hookMouseVisibility, x++); writeBool(HookDInput, x++); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); int nt = 0; if (Environment.Is64BitProcess) { nt = Injector64.RhInjectLibrary((uint)pid, 0, 0, "", injectionDllPath, ptr, (uint)size); } else { nt = Injector32.RhInjectLibrary((uint)pid, 0, 0, injectionDllPath, "", ptr, (uint)size); } //Set exit code Environment.Exit((int)nt); }
static void Main(string[] args) { bool is64 = Environment.Is64BitProcess; int i = 0; int.TryParse(args[i++], out int Tier); if (Tier == 0) { string InEXEPath = args[i++]; string InCommandLine = args[i++]; uint.TryParse(args[i++], out uint InProcessCreationFlags); uint.TryParse(args[i++], out uint InInjectionOptions); string InLibraryPath_x86 = args[i++]; string InLibraryPath_x64 = args[i++]; bool.TryParse(args[i++], out bool hookWindow); // E.g. FindWindow, etc bool.TryParse(args[i++], out bool renameMutex); string mutexToRename = args[i++]; bool.TryParse(args[i++], out bool setWindow); bool.TryParse(args[i++], out bool isDebug); string nucleusFolderPath = args[i++]; bool.TryParse(args[i++], out bool blockRaw); //IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); //uint.TryParse(args[i++], out uint InPassThruSize); var logPath = Encoding.Unicode.GetBytes(nucleusFolderPath); int logPathLength = logPath.Length; var targetsBytes = Encoding.Unicode.GetBytes(mutexToRename); int targetsBytesLength = targetsBytes.Length; int size = 27 + logPathLength + targetsBytesLength; var data = new byte[size]; data[0] = hookWindow == true ? (byte)1 : (byte)0; data[1] = renameMutex == true ? (byte)1 : (byte)0; data[2] = setWindow == true ? (byte)1 : (byte)0; data[3] = isDebug == true ? (byte)1 : (byte)0; data[4] = blockRaw == true ? (byte)1 : (byte)0; data[10] = (byte)(logPathLength >> 24); data[11] = (byte)(logPathLength >> 16); data[12] = (byte)(logPathLength >> 8); data[13] = (byte)logPathLength; data[14] = (byte)(targetsBytesLength >> 24); data[15] = (byte)(targetsBytesLength >> 16); data[16] = (byte)(targetsBytesLength >> 8); data[17] = (byte)targetsBytesLength; Array.Copy(logPath, 0, data, 18, logPathLength); Array.Copy(targetsBytes, 0, data, 19 + logPathLength, targetsBytesLength); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); IntPtr pid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))); try { int result = -1; int attempts = 0; // 5 attempts to inject while (result != 0) { if (is64) { result = Injector64.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, InInjectionOptions, "", InLibraryPath_x64, ptr, (uint)size, pid); } else { result = Injector32.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, InInjectionOptions, InLibraryPath_x86, "", ptr, (uint)size, pid); } Thread.Sleep(1000); attempts++; if (attempts == 4) { break; } } Marshal.FreeHGlobal(pid); Console.WriteLine(Marshal.ReadInt32(pid).ToString()); } catch (Exception ex) { Log(string.Format("ERROR - {0}", ex.Message)); } /** * Outdated. Need the CreateAndInject method originally from Inject32 * * * string InEXEPath = args[i++]; * string InCommandLine = args[i++]; * uint.TryParse(args[i++], out uint InProcessCreationFlags); * uint.TryParse(args[i++], out uint InInjectionOptions); * string InLibraryPath_x86 = args[i++]; * string InLibraryPath_x64 = args[i++]; * IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); * uint.TryParse(args[i++], out uint InPassThruSize); * IntPtr pid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint))); * * try * { * int result = -1; //RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, InInjectionOptions, InLibraryPath_x86, InLibraryPath_x64, InPassThruBuffer, InPassThruSize, pid); * int attempts = 0; // 5 attempts to inject * while (result != 0) * { * if (is64) * result = Injector64.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, InInjectionOptions, "", InLibraryPath_x64, InPassThruBuffer, InPassThruSize, pid); * else * result = Injector32.RhCreateAndInject(InEXEPath, InCommandLine, InProcessCreationFlags, InInjectionOptions, InLibraryPath_x86, "", InPassThruBuffer, InPassThruSize, pid); * * Thread.Sleep(1000); * attempts++; * * if (attempts == 4) * break; * } * Marshal.FreeHGlobal(pid); * * Console.WriteLine(Marshal.ReadInt32(pid).ToString()); * } * catch (Exception ex) * { * Log("ERROR - " + ex.Message); * }*/ } else if (Tier == 1) { int.TryParse(args[i++], out int InTargetPID); int.TryParse(args[i++], out int InWakeUpTID); int.TryParse(args[i++], out int InInjectionOptions); string InLibraryPath_x86 = args[i++]; string InLibraryPath_x64 = args[i++]; //IntPtr InPassThruBuffer = Marshal.StringToHGlobalUni(args[i++]); int.TryParse(args[i++], out int hWnd); bool.TryParse(args[i++], out bool hookFocus); bool.TryParse(args[i++], out bool hideCursor); bool.TryParse(args[i++], out bool isDebug); string nucleusFolderPath = args[i++]; bool.TryParse(args[i++], out bool setWindow); bool.TryParse(args[i++], out bool preventWindowDeactivation); var logPath = Encoding.Unicode.GetBytes(nucleusFolderPath); int logPathLength = logPath.Length; //int.TryParse(args[i++], out int InPassThruSize); int size = 42 + logPathLength; IntPtr intPtr = Marshal.AllocHGlobal(size); byte[] dataToSend = new byte[size]; dataToSend[0] = (byte)(hWnd >> 24); dataToSend[1] = (byte)(hWnd >> 16); dataToSend[2] = (byte)(hWnd >> 8); dataToSend[3] = (byte)(hWnd); dataToSend[4] = preventWindowDeactivation == true ? (byte)1 : (byte)0; dataToSend[5] = setWindow == true ? (byte)1 : (byte)0; dataToSend[6] = isDebug == true ? (byte)1 : (byte)0; dataToSend[7] = hideCursor == true ? (byte)1 : (byte)0; dataToSend[8] = hookFocus == true ? (byte)1 : (byte)0; dataToSend[9] = (byte)(logPathLength >> 24); dataToSend[10] = (byte)(logPathLength >> 16); dataToSend[11] = (byte)(logPathLength >> 8); dataToSend[12] = (byte)logPathLength; Array.Copy(logPath, 0, dataToSend, 13, logPathLength); Marshal.Copy(dataToSend, 0, intPtr, size); try { if (is64) { Injector64.RhInjectLibrary((uint)InTargetPID, (uint)InWakeUpTID, (uint)InInjectionOptions, "", InLibraryPath_x64, intPtr, (uint)size); } else { Injector32.RhInjectLibrary((uint)InTargetPID, (uint)InWakeUpTID, (uint)InInjectionOptions, InLibraryPath_x86, "", intPtr, (uint)size); } } catch (Exception ex) { Log("ERROR - " + ex.Message); } } }