public Task StartAsync(Tool tool, ITorSharpProxy proxy) { IntPtr desktopHandle = WindowsUtility.CreateDesktop(DesktopName); // embrace the madness -- it seems Windows always wants exactly one instance of "ctfmon.exe" in the new desktop var ctfmonStartInfo = new ProcessStartInfo { FileName = "ctfmon.exe", WorkingDirectory = "." }; WindowsApi.PROCESS_INFORMATION ctfmonProcess = WindowsUtility.CreateProcess(proxy, ctfmonStartInfo, DesktopName); AssociateWithJob(ctfmonProcess, false); // start the desired process var arguments = string.Join(" ", tool.Settings.GetArguments(tool)); var startInfo = new ProcessStartInfo { FileName = tool.ExecutablePath, Arguments = arguments, WorkingDirectory = tool.WorkingDirectory }; WindowsApi.PROCESS_INFORMATION targetProcess = WindowsUtility.CreateProcess(proxy, startInfo, DesktopName); AssociateWithJob(targetProcess, true); return(Task.FromResult((object)null)); }
public static WindowsApi.PROCESS_INFORMATION CreateProcess(ITorSharpProxy proxy, ProcessStartInfo startInfo, string desktopName = null, int?millisecondsToWait = 100) { // Source: https://stackoverflow.com/a/59387440/3286975 var startupInfo = new WindowsApi.STARTUPINFO(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpDesktop = desktopName; var processInformation = new WindowsApi.PROCESS_INFORMATION(); string command = startInfo.FileName + " " + startInfo.Arguments; WindowsApi.SECURITY_ATTRIBUTES saAttr = new WindowsApi.SECURITY_ATTRIBUTES { nLength = (uint)Marshal.SizeOf(typeof(WindowsApi.SECURITY_ATTRIBUTES)), bInheritHandle = 0x1, lpSecurityDescriptor = IntPtr.Zero }; WindowsApi.CreatePipe(ref out_read, ref out_write, ref saAttr, 0); WindowsApi.CreatePipe(ref err_read, ref err_write, ref saAttr, 0); WindowsApi.SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0); WindowsApi.SetHandleInformation(err_read, HANDLE_FLAG_INHERIT, 0); bool result = WindowsApi.CreateProcess(null, command, IntPtr.Zero, IntPtr.Zero, true, WindowsApi.NORMAL_PRIORITY_CLASS, IntPtr.Zero, startInfo.WorkingDirectory, ref startupInfo, ref processInformation); var thread = new Thread(() => RedirectStd(proxy)); thread.Start(); if (result) { if (millisecondsToWait.HasValue) { WindowsApi.WaitForInputIdle(processInformation.hProcess, (uint)millisecondsToWait.Value); } WindowsApi.CloseHandle(processInformation.hThread); return(processInformation); } return(new WindowsApi.PROCESS_INFORMATION()); }
private static void RedirectStd(ITorSharpProxy proxy) { // Source: https://stackoverflow.com/a/59387440/3286975 byte[] out_buf = new byte[BUFSIZE]; byte[] err_buf = new byte[BUFSIZE]; int dwRead = 0; string out_str = ""; string err_str = ""; bool isOutputSet = proxy.GetHandler(true) != null; bool isErrorSet = proxy.GetHandler(false) != null; while (true) { bool bSuccess; if (isOutputSet) { bSuccess = WindowsApi.ReadFile(out_read, out_buf, BUFSIZE, ref dwRead, IntPtr.Zero); if (!bSuccess || dwRead == 0) { break; } out_str += System.Text.Encoding.Default.GetString(out_buf); out_str = PushCallback(proxy, out_str, true); } if (isErrorSet) { bSuccess = WindowsApi.ReadFile(out_read, err_buf, BUFSIZE, ref dwRead, IntPtr.Zero); if (!bSuccess || dwRead == 0) { break; } err_str += System.Text.Encoding.Default.GetString(err_buf); err_str = PushCallback(proxy, err_str, true); } } WindowsApi.CloseHandle(out_read); WindowsApi.CloseHandle(err_read); WindowsApi.CloseHandle(out_write); WindowsApi.CloseHandle(err_write); }
private static string PushCallback(ITorSharpProxy proxy, string str, bool isOutStream) { var lines = str.Split(); foreach (var line in lines) { var instance = (DataReceivedEventArgs)Activator.CreateInstance(typeof(DataReceivedEventArgs), line); if (isOutStream) { ((TorSharpProxy)proxy).HandleOnOutput(null, instance); } else { ((TorSharpProxy)proxy).HandleOnError(null, instance); } } return(lines.Last()); }
public TorSharpProxyHostedService( IOptions <TriasConfiguration> triasConfiguration, IHttpClientFactory httpClientFactory, IIpGeolocation ipGeolocation, ILogger <TorSharpProxyHostedService> logger ) { _triasConfiguration = triasConfiguration; _httpClientFactory = httpClientFactory; _ipGeolocation = ipGeolocation; _logger = logger; var config = triasConfiguration.Value; _proxy = new TorSharpProxy(config.TorSharpSettings); var proxyHttpClientHandler = new HttpClientHandler { Proxy = new WebProxy(new Uri($"http://localhost:{config.TorSharpSettings.PrivoxySettings.Port}")) }; _proxyHttpClient = new HttpClient(proxyHttpClientHandler); }
public static DataReceivedEventHandler GetHandler(this ITorSharpProxy proxy, bool isOutStream) { return((DataReceivedEventHandler)proxy.GetType() .GetField(isOutStream ? "OnOutput" : "OnError", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(proxy)); }
public Task StartAsync(Tool tool, ITorSharpProxy proxy) { // start the desired process var arguments = string.Join(" ", tool.Settings.GetArguments(tool)); var environmentVariables = tool.Settings.GetEnvironmentVariables(tool); var startInfo = new ProcessStartInfo { FileName = tool.ExecutablePath, Arguments = arguments, WorkingDirectory = tool.WorkingDirectory, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, }; foreach (var pair in environmentVariables) { startInfo.EnvironmentVariables[pair.Key] = pair.Value; } var process = Process.Start(startInfo); var onOutput = proxy.GetHandler(true); if (onOutput != null) { process.OutputDataReceived += onOutput; } else { process.OutputDataReceived += (sender, e) => { Console.WriteLine(e.Data); } }; var onError = proxy.GetHandler(false); if (onError != null) { process.ErrorDataReceived += onError; } else { process.ErrorDataReceived += (sender, e) => { Console.Error.WriteLine(e.Data); } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); if (process == null) { throw new TorSharpException($"Unable to start the process '{tool.ExecutablePath}'."); } _processes.Add(process); return(CompletedTask); }