Exemplo n.º 1
0
        /// <summary>
        /// Create a new process wrapper with an executable path and working directory.
        /// </summary>
        /// <param name="executablePath">Path to executable</param>
        /// <param name="workingDirectory">Starting directory for executable. May be left empty to inherit from parent</param>
        public ProcessHost(string executablePath, string workingDirectory)
        {
            if (!HostIsCompatible())
            {
                throw new NotSupportedException("The host operating system is not compatible");
            }

            _executablePath   = executablePath;
            _workingDirectory = DefaultToCurrentIfEmpty(workingDirectory);

            StdIn  = new Pipe(Pipe.Direction.In);
            StdErr = new Pipe(Pipe.Direction.Out);
            StdOut = new Pipe(Pipe.Direction.Out);

            _lastExitCode = 0;

            _si = new Kernel32.Startupinfo
            {
                wShowWindow = 0,
                dwFlags     = Kernel32.StartfUsestdhandles | Kernel32.StartfUseshowwindow,
                hStdOutput  = StdOut.WriteHandle,
                hStdError   = StdErr.WriteHandle,
                hStdInput   = StdIn.ReadHandle
            };

            _si.cb = (uint)Marshal.SizeOf(_si);
            _pi    = new Kernel32.ProcessInformation();
        }
Exemplo n.º 2
0
        public static void Run(Settings settings, string clientDirectory, string bin, long ip, ushort port)
        {
            var binpath = Path.Combine(clientDirectory, bin);

            var startupInfo = new Kernel32.Startupinfo();
            var processInfo = new Kernel32.ProcessInformation();

            //TODO -- what to do if !success?
            var success = Kernel32.CreateProcess(binpath, string.Format("\"{0}\" {1} {2}", binpath.Trim(), ip, port),
                                                 IntPtr.Zero, IntPtr.Zero, false,
                                                 Kernel32.ProcessCreationFlags.CreateSuspended | Kernel32.ProcessCreationFlags.CreateDefaultErrorMode,
                                                 IntPtr.Zero, null, ref startupInfo, out processInfo);

            var tHandle = processInfo.HThread;

            DllInjector.GetInstance.BInject(processInfo.DwProcessId, Path.Combine(clientDirectory, "login.dll"));
            Kernel32.ResumeThread(tHandle);
            System.Threading.Thread.Sleep(1000);

            // open the process after it is created so we can add the appropriate flags to write to the process
            var hndProc = Kernel32.OpenProcess((uint)(Kernel32.ProcessAccessFlags.CreateThread | Kernel32.ProcessAccessFlags.VirtualMemoryOperation
                                                      | Kernel32.ProcessAccessFlags.VirtualMemoryRead | Kernel32.ProcessAccessFlags.VirtualMemoryWrite
                                                      | Kernel32.ProcessAccessFlags.QueryInformation), 0, processInfo.DwProcessId);

            Kernel32.CloseHandle(tHandle);

            Kernel32.SuspendThread(hndProc);

            // Remove darkness
            if (settings.DisableDark)
            {
                Kernel32.WriteProcessMemory(hndProc, (IntPtr)0x0046690B, new byte[] { 0x90, 0xE9 }, 2, 0);
            }

            // Mob level highlight toggle
            if (settings.EnableMobColours)
            {
                Kernel32.WriteProcessMemory(hndProc, (IntPtr)0x0046786E, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }, 6, 0);
            }

            // Don't know if the constant suspend/resume is needed, but WinXP was being funnky and this works
            // Needed to get the lance master poly working properly
            var zelgoPak = File.ReadAllBytes(Path.Combine(clientDirectory, "zelgo.pak"));

            Kernel32.WriteProcessMemory(hndProc, (IntPtr)0x004B6CE0, new byte[] { 0xEB }, 1, 0);
            Kernel32.WriteProcessMemory(hndProc, (IntPtr)0x00504538, zelgoPak, (uint)zelgoPak.Length - 1, 0);
            Kernel32.WriteProcessMemory(hndProc, (IntPtr)0x006DA508, new byte[] { 0x0F, 0x27 }, 2, 0);
            Kernel32.ResumeThread(hndProc);

            Kernel32.CloseHandle(hndProc);
            hndProc = IntPtr.Zero;

            System.Threading.Thread.Sleep(1000);
        }
Exemplo n.º 3
0
        public static void Run(Settings settings, string bin, long ip, ushort port)
        {
            var binpath = Path.Combine(settings.ClientDirectory, bin);

            var startupInfo = new Kernel32.Startupinfo();

            _processInfo = new Kernel32.ProcessInformation();

            //TODO -- what to do if !success?
            var success = Kernel32.CreateProcess(binpath, string.Format("\"{0}\" {1} {2}", binpath.Trim(), ip, port),
                                                 IntPtr.Zero, IntPtr.Zero, false,
                                                 Kernel32.ProcessCreationFlags.CreateSuspended | Kernel32.ProcessCreationFlags.CreateDefaultErrorMode,
                                                 IntPtr.Zero, null, ref startupInfo, out _processInfo);

            var tHandle = _processInfo.HThread;

            // TODO: need a better way to hook/suspend the client after themida unpack
            var tries = 10;

            byte[] patchWatchFor  = { 0x75, 0x3B };
            var    patchWatchBuff = new byte[2];

            Kernel32.ResumeThread(tHandle);
            System.Threading.Thread.Sleep(500);

            while (tries > 0)
            {
                Kernel32.SuspendThread(tHandle);
                Kernel32.ReadProcessMemory(_processInfo.HProcess, (IntPtr)0x0045CF2F, patchWatchBuff, (uint)patchWatchBuff.Length, 0);

                if (ByteArrayCompare(patchWatchBuff, patchWatchFor))
                {
                    // Fix Runtime Expired
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0045CF2F, new byte[] { 0xEB }, 1, 0);

                    // Fix GameGuard
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0045E3AC, new byte[] { 0x90, 0xE9 }, 2, 0);
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x004DE45A, new byte[] { 0x90, 0x90 }, 2, 0);
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0045BA71, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }, 6, 0);
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0045EABA, new byte[] { 0xEB }, 1, 0);

                    // Don't let Lin.bin install NPKCMSVC Windows Service
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x00474AC4, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x84, 0xC0, 0x5E, 0x5B, 0xEB }, 10, 0);

                    // Remove darkness
                    if (settings.DisableDark)
                    {
                        byte[] write7 = { 0x90, 0xE9 };
                        Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0046690B, new byte[] { 0x90, 0xE9 }, 2, 0);
                    }

                    // TODO: A checkbox to enable/disable like darkness?
                    // Mob name with color
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x0046786E, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }, 6, 0);

                    // Load list.spr with lancemaster fix
                    string zelgoPakPath = Path.Combine(settings.ClientDirectory, (string)"zelgo.pak");
                    if (File.Exists(zelgoPakPath))
                    {
                        byte[] zelgoPak = File.ReadAllBytes(zelgoPakPath);
                        Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x004B6CE0, new byte[] { 0xEB }, 1, 0);
                        Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x00504538, zelgoPak, (uint)zelgoPak.Length, 0);
                        Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x006DA508, new byte[] { 0x0F, 0x27 }, (uint)2, 0);
                    }

                    // Codepage??
                    Kernel32.WriteProcessMemory(_processInfo.HProcess, (IntPtr)0x00483B8E, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }, 6, 0);

                    Kernel32.ResumeThread(tHandle);
                    break;
                }

                Kernel32.ResumeThread(tHandle);
                System.Threading.Thread.Sleep(500);
                tries--;
            }

            Kernel32.ResumeThread(tHandle);
        }
Exemplo n.º 4
0
        public static int Main(string[] args)
        {
#if DEBUG
            IntPtr hConsole = IntPtr.Zero;
            if (Kernel32.AllocConsole())
            {
                hConsole = Kernel32.GetConsoleWindow();
                User32.SetLayeredWindowAttributes(hConsole, 0u, 225, 2);
            }
            User32.ShowWindow(hConsole, 5);
            Console.ForegroundColor = ConsoleColor.Green;
            Tracer.TraceWrite      += TraceWrite;
#endif
            Console.CancelKeyPress += ConsoleCancel;
            Kernel32.Win32FindDataW findFileData = new Kernel32.Win32FindDataW();
            IntPtr hSearch = Kernel32.FindFirstFileW("lotrsec.big", ref findFileData);
            if (hSearch == (IntPtr)(-1))
            {
                StringBuilder fileName = new StringBuilder(Kernel32.MAX_PATH);
                Kernel32.GetModuleFileNameW(IntPtr.Zero, fileName, Kernel32.MAX_PATH);
                for (int idx = fileName.Length - 1; idx != 0; --idx)
                {
                    if (fileName[idx] == '\\')
                    {
                        fileName[idx] = '\0';
                        break;
                    }
                }
                Kernel32.SetCurrentDirectoryW(fileName.ToString());
            }
            else
            {
                Kernel32.FindClose(hSearch);
            }
            string        config    = null;
            string        modconifg = null;
            List <string> argList   = new List <string>(args.Length);
            for (int idx = 0; idx < args.Length; ++idx)
            {
                if (string.Equals(args[idx], "-config"))
                {
                    if (idx == args.Length - 1)
                    {
                        MessageBox.Show("Invalid config parameter. A path needs to be set.");
                        return(-1);
                    }
                    config = args[idx++ + 1];
                }
                if (string.Equals(args[idx], "-modconfig"))
                {
                    if (idx == args.Length - 1)
                    {
                        MessageBox.Show("Invalid modconfig parameter. A path needs to be set.");
                        return(-1);
                    }
                    modconifg = args[idx++ + 1];
                }
                else
                {
                    argList.Add(args[idx]);
                }
            }
            args = argList.ToArray();
            Kernel32.StartupInfoW       si = new Kernel32.StartupInfoW(true);
            Kernel32.ProcessInformation pi = new Kernel32.ProcessInformation();
            int            overallTries    = 0;
            int            tries           = 0;
            Registry       registry        = new Registry();
            string         executablePath  = System.IO.Path.Combine(registry.InstallPath, "data", "ra3_1.12.game");
            ExecutableType executableType  = ExecutableType.Unknown;
            using (System.IO.Stream stream = new System.IO.FileStream(executablePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
            {
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                uint hash = Nanocore.Core.FastHash.GetHashCode(buffer);
                switch (hash)
                {
                case 0xCFAAD44Bu:
                case 0xE6D223E6u:
                case 0xCF5817CCu:
                    executableType = ExecutableType.Steam;
                    break;

                case 0xE7AF6A35u:
                case 0x2F121290u:
                    executableType = ExecutableType.Origin;
                    break;

                case 0xA05DEB39:     // this has the 4gb thing applied, need to check the original
                    executableType = ExecutableType.Retail;
                    break;

                case 0xBFE68CAD:     // should I care? this is mostly here because origins and reloaded exe have the same size
                    executableType = ExecutableType.ReLOADeD;
                    break;
                }
            }
            if (executableType == ExecutableType.Unknown)
            {
                MessageBox.Show("A version of the game is installed. Please get the game from an official source.");
                return(-1);
            }
            else if (executableType == ExecutableType.Retail)
            {
                MessageBox.Show("The retail or an old origin version is installed. If you are using Origin please update the game. Retail versions cannot be supported due to SecuROM.");
                return(-1);
            }
            while (!_isConsoleCancel)
            {
                ++tries;
                if (tries > 20)
                {
                    if (MessageBox.Show("Windows caching interferred with injecting into the game, do you want to try again?", "Error", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        overallTries += tries;
                        tries         = 1;
                    }
                    else
                    {
                        break;
                    }
                }
                try
                {
                    Kernel32.CreateProcessW(null, $"\"{executablePath}\" {string.Join(" ", args)} -config \"{config ?? System.IO.Path.Combine(registry.InstallPath, $"RA3_{registry.Language}_1.12.skudef")}\" {(modconifg is null ? string.Empty : $"-modconfig \"{modconifg}\"")}",
                                            IntPtr.Zero,
                                            IntPtr.Zero,
                                            true,
                                            4,
                                            IntPtr.Zero,
                                            null,
                                            ref si,
                                            ref pi);
                    EZHook.Inject(pi.DwProcessId, "Nanocore.dll", pi.DwThreadId, executableType);
                }
Exemplo n.º 5
0
        //////////////////////////////////////////////////////////////////////////////////////////////////////////
        //                                  Start, Stop, Pause, Resume, etc                                     //
        //////////////////////////////////////////////////////////////////////////////////////////////////////////


        #region Start/Stop/Pause/Resume/etc

        /// <summary>
        /// Start the process.
        /// </summary>
        /// <exception cref="Win32Exception"></exception>
        internal void StartProcess(string username)
        {
            //CloseProcess old instances
            StopProcess();

            var    startupInfo        = new Kernel32.StartupInfo();
            var    processInformation = new Kernel32.ProcessInformation();
            IntPtr environment        = IntPtr.Zero;


            //Flags that specify the priority and creation method of the process
            Kernel32.CreationFlags creationFlags = Kernel32.CreationFlags.CreateUnicodeEnvironment | //Windows 7+ always using the unicode environment
                                                   Kernel32.CreationFlags.CreateNewConsole |
                                                   _serviceDefinition.ProcessPriority.ConvertToCreationFlag();

            //Set the startupinfo
            startupInfo.cb      = (uint)Marshal.SizeOf(startupInfo);
            startupInfo.desktop = "winsta0\\default";

            //Create command line arguments
            var cmdLine = "";

            if (string.Equals(Path.GetExtension(_serviceDefinition.BinaryPath), ".bat", StringComparison.OrdinalIgnoreCase))
            {
                cmdLine = "cmd.exe /c";
            }

            cmdLine += BuildDoubleQuotedString(_serviceDefinition.BinaryPath);

            if (!string.IsNullOrWhiteSpace(_serviceDefinition.Arguments))
            {
                cmdLine += " " + _serviceDefinition.Arguments;
            }

            try
            {
                if (string.IsNullOrWhiteSpace(username))
                {
                    //Set last start in user session
                    _lastStartInUserSession = false;
                    _lastSessionUsername    = string.Empty;

                    if (!Kernel32.CreateProcess(
                            null,
                            cmdLine,
                            null,
                            null,
                            false,
                            creationFlags,
                            IntPtr.Zero, //TODO: Change
                            Path.GetDirectoryName(_serviceDefinition.BinaryPath),
                            ref startupInfo,
                            out processInformation))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    //Set last start in user session
                    _lastStartInUserSession = true;
                    _lastSessionUsername    = username;

                    //Get user token
                    using (SafeAccessTokenHandle token = TokenHelper.GetPrimaryTokenByUsername(username))
                    {
                        if (token == null)
                        {
                            throw new Exception("GetPrimaryTokenByUsername: No valid session found.");
                        }

                        //Create environment block
                        if (!Userenv.CreateEnvironmentBlock(ref environment, token, false))
                        {
                            throw new Exception("StartInUserSession: CreateEnvironmentBlock failed.");
                        }

                        WindowsIdentity.RunImpersonated(token, () =>
                        {
                            if (!Advapi32.CreateProcessAsUser(
                                    token,
                                    null,
                                    cmdLine,
                                    null,
                                    null,
                                    false,
                                    creationFlags,
                                    environment,
                                    Path.GetDirectoryName(_serviceDefinition.BinaryPath),
                                    ref startupInfo,
                                    out processInformation))
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }
                        });
                    }
                }
            }
            finally
            {
                if (environment != IntPtr.Zero)
                {
                    Userenv.DestroyEnvironmentBlock(environment);
                }

                if (processInformation.processHandle != IntPtr.Zero)
                {
                    Kernel32.CloseHandle(processInformation.processHandle);
                }

                if (processInformation.threadHandle != IntPtr.Zero)
                {
                    Kernel32.CloseHandle(processInformation.threadHandle);
                }
            }

            //Get process and enable raising events
            _process = Process.GetProcessById((int)processInformation.processId);
            _process.EnableRaisingEvents = true;
            _process.Exited += ProcessOnExited;

            //Assign process to job
            if (KillChildProcessJob.IsSupportedWindowsVersion)
            {
                _killChildProcessJob.AssignProcess(_process);
            }

            _lastRestartTime = DateTime.UtcNow;

            //Trigger event to update pid
            OnUpdateProcessPid(processInformation.processId);
        }