/// <summary> /// Create a process, inject the .NET Core runtime into it and load a .NET assembly. /// </summary> /// <param name="processConfig"></param> /// <param name="config32">Native modules required for starting CoreCLR in 32-bit applications.</param> /// <param name="config64">Native modules required for starting CoreCLR in 64-bit applications.</param> /// <param name="remoteHook">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="outProcessId">Process ID of the newly created process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking library in the target process.</param> public static void CreateAndInject( ProcessCreationConfig processConfig, CoreHookNativeConfig config32, CoreHookNativeConfig config64, RemoteHookingConfig remoteHook, IPipePlatform pipePlatform, out int outProcessId, params object[] passThruArguments ) { var process = Process.Start(processConfig.ExecutablePath); if (process == null) { throw new InvalidOperationException( $"Failed to start the executable at {processConfig.ExecutablePath}"); } var config = process.Is64Bit() ? config64 : config32; remoteHook.HostLibrary = config.HostLibrary; remoteHook.CoreCLRPath = config.CoreCLRPath; remoteHook.CoreCLRLibrariesPath = config.CoreCLRLibrariesPath; remoteHook.DetourLibrary = config.DetourLibrary; InjectEx( GetCurrentProcessId(), process.Id, remoteHook, pipePlatform, passThruArguments); outProcessId = process.Id; }
private NamedPipeServer(string pipeName, IPipePlatform platform, Action <IConnection> handleConnection) { _pipeName = pipeName; _platform = platform; _handleConnection = handleConnection; _isStopping = false; }
private NamedPipeServer(string pipeName, IPipePlatform platform, Action <ITransportChannel> handleTransportConnection) { _pipeName = pipeName; _platform = platform; _handleTransportConnection = handleTransportConnection; _connectionStopped = false; }
/// <summary> /// Create a process, inject the .NET Core runtime into it and load a .NET assembly. /// </summary> /// <param name="processConfig">Arguments used for starting the new process.</param> /// <param name="nativeModulesConfig32">Native modules required for starting CoreCLR in 32-bit applications.</param> /// <param name="nativeModulesConfig64">Native modules required for starting CoreCLR in 64-bit applications.</param> /// <param name="remoteInjectorConfig">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="createdProcessId">Process ID of the newly created process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking library in the target process.</param> public static void CreateAndInject( ProcessCreationConfiguration processConfig, NativeModulesConfiguration nativeModulesConfig32, NativeModulesConfiguration nativeModulesConfig64, RemoteInjectorConfiguration remoteInjectorConfig, IPipePlatform pipePlatform, out int createdProcessId, params object[] passThruArguments ) { var process = Process.Start(processConfig.ExecutablePath); if (process == null) { throw new InvalidOperationException( $"Failed to start the executable at {processConfig.ExecutablePath}"); } remoteInjectorConfig.SetNativeConfig( process.Is64Bit() ? nativeModulesConfig64 : nativeModulesConfig32); Inject( GetCurrentProcessId(), process.Id, remoteInjectorConfig, pipePlatform, passThruArguments); createdProcessId = process.Id; }
/// <summary> /// Initialize a new pipe server. /// </summary> /// <param name="pipeName">The name of the pipe server.</param> /// <param name="platform">Method for initializing a new pipe-based server.</param> /// <param name="handleRequest">Event handler called when receiving a new connection.</param> /// <returns>An instance of the new pipe server.</returns> private static NamedPipeServer CreateNewServer(string pipeName, IPipePlatform platform, Action <ITransportChannel> handleRequest) { if (pipeName.Length > MaxPipeNameLength) { throw new PipeMessageLengthException(pipeName, MaxPipeNameLength); } var pipeServer = new NamedPipeServer(pipeName, platform, handleRequest); pipeServer.Connect(); return(pipeServer); }
public static INamedPipeServer StartNewServer(string pipeName, IPipePlatform platform, Action <IConnection> handleConnection) { if (pipeName.Length > MaxPipeNameLength) { throw new PipeMessageLengthException(pipeName, MaxPipeNameLength); } var pipeServer = new NamedPipeServer(pipeName, platform, handleConnection); pipeServer.OpenListeningPipe(); return(pipeServer); }
public static INamedPipe StartNewServer(string pipeName, IPipePlatform platform, Action <IMessage, ITransportChannel> handleRequest) { if (pipeName.Length > MaxPipeNameLength) { throw new PipeMessageLengthException(pipeName, MaxPipeNameLength); } var pipeServer = new NamedPipeServer(pipeName, platform, connection => HandleTransportConnection(connection, handleRequest)); pipeServer.Connect(); return(pipeServer); }
/// <summary> /// Start CoreCLR and execute a .NET assembly in a target process. /// </summary> /// <param name="targetProcessId">The process ID of the process to inject the .NET assembly into.</param> /// <param name="remoteInjectorConfig">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking library in the target process.</param> public static void Inject( int targetProcessId, RemoteInjectorConfiguration remoteInjectorConfig, IPipePlatform pipePlatform, params object[] passThruArguments) { Inject( GetCurrentProcessId(), targetProcessId, remoteInjectorConfig, pipePlatform, passThruArguments); }
/// <summary> /// Start CoreCLR and execute a .NET assembly in a target process. /// </summary> /// <param name="targetPID">The process ID of the process to inject the .NET assembly into.</param> /// <param name="remoteHookConfig">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking library in the target process.</param> public static void Inject( int targetPID, RemoteHookingConfig remoteHookConfig, IPipePlatform pipePlatform, params object[] passThruArguments) { InjectEx( GetCurrentProcessId(), targetPID, remoteHookConfig, pipePlatform, passThruArguments); }
public static RpcService CreateRpcService( string namedPipeName, IPipePlatform pipePlatform, ISessionFeature session, Type rpcService, Func <RequestContext, Func <Task>, Task> handler) { var service = new RpcService(session, rpcService, handler); Task.Factory.StartNew(() => service.CreateServer(namedPipeName, pipePlatform), TaskCreationOptions.LongRunning); return(service); }
public static RpcService CreateRpcService( string namedPipeName, IPipePlatform pipePlatform, ISessionFeature session, Type rpcService, Func <RequestContext, Func <Task>, Task> handler) { var service = new RpcService(session, rpcService, handler); _rpcServerThread = new Thread(() => service.CreateServer(namedPipeName, pipePlatform)) { IsBackground = true }; _rpcServerThread.Start(); return(service); }
public static INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform) { return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, HandleRequest)); }
private static INamedPipe CreateServer(string namedPipeName, IPipePlatform pipePlatform, Action <IMessage, ITransportChannel> handleRequest) { return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, handleRequest)); }
/// <summary> /// Start CoreCLR and execute a .NET assembly in a target process. /// </summary> /// <param name="hostPID">Process ID of the process communicating with the target process.</param> /// <param name="targetPID">The process ID of the process to inject the .NET assembly into.</param> /// <param name="remoteHookConfig">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking library in the target process.</param> public static void InjectEx( int hostPID, int targetPID, RemoteHookingConfig remoteHookConfig, IPipePlatform pipePlatform, params object[] passThruArguments) { string injectionPipeName = remoteHookConfig.InjectionPipeName; if (string.IsNullOrWhiteSpace(injectionPipeName)) { throw new ArgumentException("Invalid injection pipe name"); } InjectionHelper.BeginInjection(targetPID); using (InjectionHelper.CreateServer(injectionPipeName, pipePlatform)) { try { var remoteInfo = new ManagedRemoteInfo { HostPID = hostPID }; var format = new BinaryFormatter(); var arguments = new List <object>(); if (passThruArguments != null) { foreach (var arg in passThruArguments) { using (var ms = new MemoryStream()) { format.Serialize(ms, arg); arguments.Add(ms.ToArray()); } } } remoteInfo.UserParams = arguments.ToArray(); using (var passThruStream = new MemoryStream()) { var libraryPath = remoteHookConfig.PayloadLibrary; PrepareInjection( remoteInfo, new UserDataBinaryFormatter(), libraryPath, passThruStream, injectionPipeName); // Inject the corerundll into the process, start the CoreCLR // and use the CoreLoad dll to resolve the dependencies of the hooking library // and then call the IEntryPoint.Run method located in the hooking library try { var process = GetProcessById(targetPID); var length = (int)passThruStream.Length; using (var binaryLoader = GetBinaryLoader(process)) { binaryLoader.Load(process, remoteHookConfig.HostLibrary, new[] { remoteHookConfig.DetourLibrary }); binaryLoader.ExecuteRemoteFunction(process, new RemoteFunctionCall { Arguments = new BinaryLoaderSerializer(GetBinaryLoaderConfig()) { Arguments = new BinaryLoaderArguments { Verbose = remoteHookConfig.VerboseLog, PayloadFileName = remoteHookConfig.CLRBootstrapLibrary, CoreRootPath = remoteHookConfig.CoreCLRPath, CoreLibrariesPath = remoteHookConfig.CoreCLRLibrariesPath } }, FunctionName = new FunctionName { Module = remoteHookConfig.HostLibrary, Function = GetCoreCLRStartFunctionName() }, }); binaryLoader.ExecuteRemoteManagedFunction(process, new RemoteManagedFunctionCall { ManagedFunction = CoreHookLoaderDel, FunctionName = new FunctionName { Module = remoteHookConfig.HostLibrary, Function = GetCoreCLRExecuteManagedFunctionName() }, Arguments = new RemoteFunctionArguments { Is64BitProcess = process.Is64Bit(), UserData = binaryLoader.CopyMemoryTo(process, passThruStream.GetBuffer(), length), UserDataSize = length } } ); InjectionHelper.WaitForInjection(targetPID); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } } finally { InjectionHelper.EndInjection(targetPID); } } }
private static INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform, Action <string, IPC.IConnection> handleRequest) { return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, handleRequest)); }
/// <summary> /// Initialize a new pipe server. /// </summary> /// <param name="pipeName">The name of the pipe server.</param> /// <param name="platform">Method for initializing a new pipe-based server.</param> /// <param name="handleRequest">Event handler called when receiving a new connection.</param> /// <returns>An instance of the new pipe server.</returns> public static INamedPipe StartNewServer(string pipeName, IPipePlatform platform, Action <ITransportChannel> handleRequest) { return(CreateNewServer(pipeName, platform, handleRequest)); }
/// <summary> /// Start CoreCLR and execute a .NET assembly in a target process. /// </summary> /// <param name="localProcessId">Process ID of the process communicating with the target process.</param> /// <param name="targetProcessId">The process ID of the process to inject the .NET assembly into.</param> /// <param name="remoteInjectorConfig">Configuration settings for starting CoreCLR and executing .NET assemblies.</param> /// <param name="pipePlatform">Class for creating pipes for communication with the target process.</param> /// <param name="passThruArguments">Arguments passed to the .NET hooking plugin once it is loaded in the target process.</param> public static void Inject( int localProcessId, int targetProcessId, RemoteInjectorConfiguration remoteInjectorConfig, IPipePlatform pipePlatform, params object[] passThruArguments) { if (string.IsNullOrWhiteSpace(remoteInjectorConfig.InjectionPipeName)) { throw new ArgumentException("Invalid injection pipe name"); } InjectionHelper.BeginInjection(targetProcessId); using (InjectionHelper.CreateServer(remoteInjectorConfig.InjectionPipeName, pipePlatform)) { try { var remoteInfoFormatter = new UserDataBinaryFormatter(); // Initialize the arguments passed to the CoreHook plugin. var remoteInfo = CreateRemoteInfo(localProcessId, remoteInfoFormatter, passThruArguments); using (var pluginArgumentsStream = new MemoryStream()) { // Serialize the plugin information such as the DLL path // and the plugin arguments, which are copied to the remote process. CreatePluginArguments( remoteInfo, remoteInfoFormatter, remoteInjectorConfig.PayloadLibrary, pluginArgumentsStream, remoteInjectorConfig.InjectionPipeName); // Inject the CoreCLR hosting module into the process, start the CoreCLR // and use the CoreLoad dll to resolve the dependencies of the hooking library // and then call the IEntryPoint.Run method located in the hooking library. try { var process = GetProcessById(targetProcessId); var pluginArgumentsLength = (int)pluginArgumentsStream.Length; using (var assemblyLoader = CreateAssemblyLoader(process)) { var pathConfig = GetPathConfig(); // Load the CoreCLR hosting module in the remote process. assemblyLoader.LoadModule(remoteInjectorConfig.HostLibrary); // Load the function detour module into remote process. assemblyLoader.LoadModule(remoteInjectorConfig.DetourLibrary); // Initialize CoreCLR in the remote process using the native CoreCLR hosting module. assemblyLoader.CreateThread( new RemoteFunctionCall { Arguments = new HostFunctionArguments(pathConfig, new HostArguments { Verbose = remoteInjectorConfig.VerboseLog, PayloadFileName = remoteInjectorConfig.ClrBootstrapLibrary, CoreRootPath = remoteInjectorConfig.ClrRootPath, CoreLibrariesPath = remoteInjectorConfig.ClrLibrariesPath }), FunctionName = new FunctionName { Module = remoteInjectorConfig.HostLibrary, Function = GetClrStartFunctionName() }, }); // Execute a .NET function in the remote process now that CoreCLR is started. assemblyLoader.CreateThread(new RemoteFunctionCall { Arguments = new AssemblyFunctionArguments( pathConfig, CoreHookLoaderDelegate, new PluginConfigurationArguments( process.Is64Bit(), assemblyLoader.CopyMemory(pluginArgumentsStream.GetBuffer(), pluginArgumentsLength), pluginArgumentsLength) ), FunctionName = new FunctionName { Module = remoteInjectorConfig.HostLibrary, Function = GetClrExecuteManagedFunctionName() } }, false); InjectionHelper.WaitForInjection(targetProcessId); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } finally { InjectionHelper.EndInjection(targetProcessId); } } }
private INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform) { _pipeName = namedPipeName; return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, HandleConnection)); }
/// <summary> /// Initialize a new pipe server. /// </summary> /// <param name="pipeName">The name of the pipe server.</param> /// <param name="platform">Method for initializing a new pipe-based server.</param> /// <param name="handleRequest">Event handler called when receiving a new message from a client.</param> /// <returns>An instance of the new pipe server.</returns> public static INamedPipe StartNewServer(string pipeName, IPipePlatform platform, Action <IStringMessage, ITransportChannel> handleRequest) { return(CreateNewServer(pipeName, platform, connection => HandleTransportConnection(connection, handleRequest))); }