예제 #1
0
        /// <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;
        }
예제 #2
0
 private NamedPipeServer(string pipeName, IPipePlatform platform, Action <IConnection> handleConnection)
 {
     _pipeName         = pipeName;
     _platform         = platform;
     _handleConnection = handleConnection;
     _isStopping       = false;
 }
예제 #3
0
 private NamedPipeServer(string pipeName, IPipePlatform platform, Action <ITransportChannel> handleTransportConnection)
 {
     _pipeName = pipeName;
     _platform = platform;
     _handleTransportConnection = handleTransportConnection;
     _connectionStopped         = false;
 }
예제 #4
0
        /// <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;
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 /// <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);
 }
예제 #9
0
 /// <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);
 }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
 public static INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform)
 {
     return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, HandleRequest));
 }
예제 #13
0
 private static INamedPipe CreateServer(string namedPipeName, IPipePlatform pipePlatform, Action <IMessage, ITransportChannel> handleRequest)
 {
     return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, handleRequest));
 }
예제 #14
0
        /// <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);
                }
            }
        }
예제 #15
0
 private static INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform, Action <string, IPC.IConnection> handleRequest)
 {
     return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, handleRequest));
 }
예제 #16
0
 /// <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));
 }
예제 #17
0
        /// <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);
                }
            }
        }
예제 #18
0
 private INamedPipeServer CreateServer(string namedPipeName, IPipePlatform pipePlatform)
 {
     _pipeName = namedPipeName;
     return(NamedPipeServer.StartNewServer(namedPipeName, pipePlatform, HandleConnection));
 }
예제 #19
0
 /// <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)));
 }