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();
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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());
        }
Beispiel #4
0
        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);
        }
Beispiel #7
0
        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);
                }
            }
        }