/// <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(); }
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); }
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); }