Beispiel #1
0
        /// <summary>
        /// Loads the user library,
        /// creates an instance for the <see cref="IEntryPoint"/> specified in the library
        /// and invokes the Run() method specified in that instance.
        /// </summary>
        /// <param name="userLibrary">The assembly provided by the user, located in the application directory or in the global assembly cache.</param>
        /// <param name="paramArray">Array of parameters to use with the constructor and with the Run() method.</param>
        /// <param name="helperServiceInterface"><see cref="HelperServiceInterface"/> to use for reporting to the host side.</param>
        /// <returns>The exit code to be returned by the main() method.</returns>
        private static int LoadUserLibrary(string userLibrary, object[] paramArray, HelperServiceInterface helperServiceInterface)
        {
            Type       entryPoint = null;
            MethodInfo runMethod;
            object     instance;

            try
            {
                entryPoint = FindEntryPoint(userLibrary);
                /// Determine if a Run() method is defined, before initializing an instance for the type.
                runMethod = FindMatchingMethod(entryPoint, "Run", paramArray);
                if (runMethod == null)
                {
                    throw new MissingMethodException(ConstructMissingMethodExceptionMessage("Run", paramArray));
                }
                /// Initialize an object for the entrypoint.
                instance = InitializeInstance(entryPoint, paramArray);
                if (instance == null)
                {
                    throw new MissingMethodException(ConstructMissingMethodExceptionMessage(entryPoint.Name, paramArray));
                }
                /// Notify the host about successful injection.
                helperServiceInterface.InjectionCompleted(RemoteHooking.GetCurrentProcessId());
            }
            catch (Exception e)
            {
                /// Provide error information on host side.
                try
                {
                    helperServiceInterface.InjectionException(RemoteHooking.GetCurrentProcessId(), e);
                }
                finally
                {
                    Release(entryPoint);
                }
                return(-1);
            }

            try
            {
                /// After this it is safe to enter the Run() method, which will block until assembly unloading...
                /// From now on the user library has to take care about error reporting!
                runMethod.Invoke(instance, BindingFlags.Public | BindingFlags.Instance | BindingFlags.ExactBinding |
                                 BindingFlags.InvokeMethod, null, paramArray, null);
            }
            finally
            {
                Release(entryPoint);
            }
            return(0);
        }
Beispiel #2
0
        /// <summary>
        ///     Loads the user library (trying the strong name first, then the file name),
        ///     creates an instance for the <see cref="IEntryPoint" /> specified in the library
        ///     and invokes the Run() method specified in that instance.
        /// </summary>
        /// <param name="userLibraryStrongName">
        ///     The assembly strong name provided by the user, located in the global assembly
        ///     cache.
        /// </param>
        /// <param name="userLibraryFileName">The assembly file name provided by the user to be loaded.</param>
        /// <param name="paramArray">
        ///     Array of parameters to use with the constructor and with the Run() method. Note that all but
        ///     the first parameter should be binary encoded.
        /// </param>
        /// <param name="helperServiceInterface"><see cref="HelperServiceInterface" /> to use for reporting to the host side.</param>
        /// <returns>The exit code to be returned by the main() method.</returns>
        private static int LoadUserLibrary(string userLibraryStrongName, string userLibraryFileName, object[] paramArray, HelperServiceInterface helperServiceInterface)
        {
            Type       entryPoint = null;
            MethodInfo runMethod;
            object     instance;

            // 1. Load the assembly and find the EasyHook.IEntryPoint and matching Run() method
            try
            {
                // Load the given assembly and find the first EasyHook.IEntryPoint
                entryPoint = FindEntryPoint(userLibraryStrongName, userLibraryFileName);

                // Only attempt to deserialise parameters after we have loaded the userAssembly
                // this allows types from the userAssembly to be passed as parameters
                var format = new BinaryFormatter();
                format.Binder = new AllowAllAssemblyVersionsDeserializationBinder(entryPoint.Assembly);
                for (var i = 1; i < paramArray.Length; i++)
                {
                    using (var ms = new MemoryStream((byte[])paramArray[i]))
                    {
                        paramArray[i] = format.Deserialize(ms);
                    }
                }

                // Determine if a Run() method is defined with matching parameters, before initializing an instance for the type.
                runMethod = FindMatchingMethod(entryPoint, "Run", paramArray);
                if (runMethod == null)
                {
                    throw new MissingMethodException(ConstructMissingMethodExceptionMessage("Run", paramArray));
                }
                // Initialize an object for the entrypoint.
                instance = InitializeInstance(entryPoint, paramArray);
                if (instance == null)
                {
                    throw new MissingMethodException(ConstructMissingMethodExceptionMessage(entryPoint.Name, paramArray));
                }
                // Notify the host about successful injection.
                helperServiceInterface.InjectionCompleted(RemoteHooking.GetCurrentProcessId());
            }
            catch (Exception e)
            {
                // Provide error information on host side.
                try
                {
                    helperServiceInterface.InjectionException(RemoteHooking.GetCurrentProcessId(), e);
                }
                finally
                {
                    Release(entryPoint);
                }
                return(-1);
            }

            // 2. Invoke the Run() method
            try
            {
                // After this it is safe to enter the Run() method, which will block until assembly unloading...
                // From now on the user library has to take care about error reporting!
                runMethod.Invoke(instance, BindingFlags.Public | BindingFlags.Instance | BindingFlags.ExactBinding |
                                 BindingFlags.InvokeMethod, null, paramArray, null);
            }
            finally
            {
                Release(entryPoint);
            }
            return(0);
        }