예제 #1
0
        /// <summary>
        /// Create the config class that is passed to the CLR bootstrap library to be loaded.
        /// The <paramref name="remoteInfo"/> holds information such as what hooking module to load.
        /// </summary>
        /// <param name="remoteInfo">The configuration that is serialized and passed to CoreLoad.</param>
        /// <param name="userDataFormatter">Serializes the <paramref name="remoteInfo"/> data.</param>
        /// <param name="pluginPath">The plugin to be loaded and executed in the target process.</param>
        /// <param name="argumentsStream">The stream that holds the the serialized <paramref name="remoteInfo"/> class.</param>
        /// <param name="injectionPipeName">The pipe name used for notifying the host process that the hook plugin has been loaded in the target process.</param>
        private static void CreatePluginArguments(
            ManagedRemoteInfo remoteInfo,
            IUserDataFormatter userDataFormatter,
            string pluginPath,
            Stream argumentsStream,
            string injectionPipeName)
        {
            if (string.IsNullOrWhiteSpace(pluginPath))
            {
                throw new ArgumentException("The injection library was not valid");
            }

            if (File.Exists(pluginPath))
            {
                pluginPath = Path.GetFullPath(pluginPath);
            }

            remoteInfo.UserLibrary = pluginPath;

            if (File.Exists(remoteInfo.UserLibrary))
            {
                remoteInfo.UserLibraryName = AssemblyName.GetAssemblyName(remoteInfo.UserLibrary).FullName;
            }
            else
            {
                throw new FileNotFoundException($"The given assembly could not be found: '{remoteInfo.UserLibrary}'", remoteInfo.UserLibrary);
            }

            remoteInfo.ChannelName = injectionPipeName;

            userDataFormatter.Serialize(argumentsStream, remoteInfo);
        }
예제 #2
0
        /// <summary>
        /// Create the config class that is passed to the CLR bootstrap library to be loaded.
        /// The <paramref name="remoteInfo"/> holds information such as what hooking module to load.
        /// </summary>
        /// <param name="remoteInfo">The configuration that is serialized and passed to CoreLoad.</param>
        /// <param name="serializer">Serializes the <paramref name="remoteInfo"/> data.</param>
        /// <param name="library">The managed hooking library to be loaded and executed in the target process.</param>
        /// <param name="argumentsStream">The stream that holds the the serialized <paramref name="remoteInfo"/> class.</param>
        /// <param name="injectionPipeName">The pipe name used for notifying the host process that the hook plugin has been loaded in the target process.</param>
        private static void PrepareInjection(
            ManagedRemoteInfo remoteInfo,
            IUserDataFormatter serializer,
            ref string library,
            MemoryStream argumentsStream,
            string injectionPipeName)
        {
            if (string.IsNullOrWhiteSpace(library))
            {
                throw new ArgumentException("The injection library was not valid");
            }

            if ((library != null) && File.Exists(library))
            {
                library = Path.GetFullPath(library);
            }

            remoteInfo.UserLibrary = library;

            if (File.Exists(remoteInfo.UserLibrary))
            {
                remoteInfo.UserLibraryName = AssemblyName.GetAssemblyName(remoteInfo.UserLibrary).FullName;
            }
            else
            {
                throw new FileNotFoundException($"The given assembly could not be found: '{remoteInfo.UserLibrary}'", remoteInfo.UserLibrary);
            }

            remoteInfo.ChannelName = injectionPipeName;

            serializer.Serialize(argumentsStream, remoteInfo);
        }
예제 #3
0
        void ShouldThrowErrorWhenSerializingNullManagedRemoteInfoClass()
        {
            ManagedRemoteInfo remoteInfo = null;

            Assert.Throws <ArgumentNullException>(
                () => CreateDefaultFormatter().Serialize(new MemoryStream(), remoteInfo));
        }
예제 #4
0
 private HostConnectionData()
 {
     _state           = ConnectionState.Invalid;
     _helperInterface = null;
     _remoteInfo      = null;
     _unmanagedInfo   = null;
 }
예제 #5
0
        void ShouldThrowErrorWhenSerializingNullStreamClass()
        {
            MemoryStream      memoryStream = null;
            ManagedRemoteInfo remoteInfo   = new ManagedRemoteInfo();

            Assert.Throws <ArgumentNullException>(
                () => new BinaryFormatter().Serialize(memoryStream, remoteInfo));
        }
예제 #6
0
        void ShouldSerializeAndDeserializeManagedRemoteInfoObject()
        {
            var memoryStream    = new MemoryStream();
            var remoteInfo      = new ManagedRemoteInfo();
            var binaryFormatter = CreateDefaultFormatter();

            binaryFormatter.Serialize(memoryStream, remoteInfo);

            memoryStream.Position = 0;

            Assert.NotNull(binaryFormatter.Deserialize <ManagedRemoteInfo>(memoryStream));
        }
예제 #7
0
        void ShouldSerializeAndDeserializeManagedRemoteInfoObject()
        {
            var memoryStream    = new MemoryStream();
            var remoteInfo      = new ManagedRemoteInfo();
            var binaryFormatter = new BinaryFormatter();

            binaryFormatter.Serialize(memoryStream, remoteInfo);

            memoryStream.Position = 0;
            object deserializedRemoteInfo = binaryFormatter.Deserialize(memoryStream);

            Assert.NotNull(deserializedRemoteInfo);
        }
예제 #8
0
        void ShouldSerializeAndDeserializeManagedRemoteInfoClass()
        {
            var memoryStream    = new MemoryStream();
            var remoteInfo      = new ManagedRemoteInfo();
            var binaryFormatter = CreateDefaultFormatter();

            binaryFormatter.Serialize(memoryStream, remoteInfo);

            memoryStream.Position = 0;
            var deserializedRemoteInfo = binaryFormatter.Deserialize <ManagedRemoteInfo>(memoryStream);

            Assert.NotNull(deserializedRemoteInfo);
            Assert.IsType(typeof(ManagedRemoteInfo), deserializedRemoteInfo);
        }
예제 #9
0
        void ShouldSerializeAndDeserializeManagedRemoteInfoChannelName()
        {
            const string channelName  = "ChannelName";
            var          memoryStream = new MemoryStream();
            var          remoteInfo   = new ManagedRemoteInfo
            {
                ChannelName = channelName
            };
            var binaryFormatter = CreateDefaultFormatter();

            binaryFormatter.Serialize(memoryStream, remoteInfo);

            memoryStream.Position = 0;
            var deserializedRemoteInfo = binaryFormatter.Deserialize <ManagedRemoteInfo>(memoryStream);

            Assert.NotNull(deserializedRemoteInfo);
            Assert.IsType(typeof(ManagedRemoteInfo), deserializedRemoteInfo);
            Assert.Equal(channelName, deserializedRemoteInfo.ChannelName);
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="processId">The process ID of the local process that is injecting into another remote process.</param>
        /// <param name="formatter">Serializer for the user arguments passed to the plugin.</param>
        /// <param name="passThruArguments">The arguments passed to the plugin during initialization.</param>
        /// <returns></returns>
        private static ManagedRemoteInfo CreateRemoteInfo(int processId, IUserDataFormatter formatter, params object[] passThruArguments)
        {
            var remoteInfo = new ManagedRemoteInfo {
                RemoteProcessId = processId
            };

            var arguments = new List <object>();

            if (passThruArguments != null)
            {
                foreach (var arg in passThruArguments)
                {
                    using (var ms = new MemoryStream())
                    {
                        formatter.Serialize(ms, arg);
                        arguments.Add(ms.ToArray());
                    }
                }
            }
            remoteInfo.UserParams = arguments.ToArray();

            return(remoteInfo);
        }
예제 #11
0
 private HostConnectionData()
 {
     _state = ConnectionState.Invalid;
     _helperInterface = null;
     _remoteInfo = null;
     _unmanagedInfo = null;
 }
예제 #12
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);
                }
            }
        }