Exemple #1
0
 private HostConnectionData()
 {
     _state           = ConnectionState.Invalid;
     _helperInterface = null;
     _remoteInfo      = null;
     _unmanagedInfo   = null;
 }
Exemple #2
0
        private static GCHandle PrepareInjection(
            ManagedRemoteInfo InRemoteInfo,
            ref String InLibraryPath_x86,
            ref String InLibraryPath_x64,
            MemoryStream InPassThruStream)
        {
            // ensure full path information in case of file names...
            if ((InLibraryPath_x86 != null) && File.Exists(InLibraryPath_x86))
            {
                InLibraryPath_x86 = Path.GetFullPath(InLibraryPath_x86);
            }

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

            /*
             *  validate assembly name...
             */
            Assembly UserAsm;

            InRemoteInfo.UserLibrary = InLibraryPath_x86;

            if (NativeAPI.Is64Bit)
            {
                InRemoteInfo.UserLibrary = InLibraryPath_x64;
            }

            if (File.Exists(InRemoteInfo.UserLibrary))
            {
                // translate to assembly name
                InRemoteInfo.UserLibrary = AssemblyName.GetAssemblyName(InRemoteInfo.UserLibrary).FullName;
            }

            if ((UserAsm = Assembly.ReflectionOnlyLoad(InRemoteInfo.UserLibrary)) == null)
            {
                throw new DllNotFoundException("The given assembly could not be found.");
            }

            if ((Int32)(UserAsm.GetName().Flags & AssemblyNameFlags.PublicKey) == 0)
            {
                throw new ArgumentException("The given assembly has no strong name.");
            }

            /*
             *  Convert managed arguments to binary stream...
             */

            BinaryFormatter  Format  = new BinaryFormatter();
            IpcServerChannel Channel = IpcCreateServer <HelperServiceInterface>(
                ref InRemoteInfo.ChannelName,
                WellKnownObjectMode.Singleton);

            Format.Serialize(InPassThruStream, InRemoteInfo);

            return(GCHandle.Alloc(InPassThruStream.GetBuffer(), GCHandleType.Pinned));
        }
Exemple #3
0
        /// <summary>
        /// Creates a new process which is started suspended until you call <see cref="WakeUpProcess"/>
        /// from within your injected library <c>Run()</c> method. This allows you to hook the target
        /// BEFORE any of its usual code is executed. In situations where a target has debugging and
        /// hook preventions, you will get a chance to block those mechanisms for example...
        /// </summary>
        /// <remarks>
        /// <para>
        /// Please note that this method might fail when injecting into managed processes, especially
        /// when the target is using the CLR hosting API and takes advantage of AppDomains. For example,
        /// the Internet Explorer won't be hookable with this method. In such a case your only options
        /// are either to hook the target with the unmanaged API or to hook it after (non-supended) creation
        /// with the usual <see cref="Inject"/> method.
        /// </para>
        /// <para>
        /// See <see cref="Inject"/> for more information. The exceptions listed here are additional
        /// to the ones listed for <see cref="Inject"/>.
        /// </para>
        /// </remarks>
        /// <param name="InEXEPath">
        /// A relative or absolute path to the desired executable.
        /// </param>
        /// <param name="InCommandLine">
        /// Optional command line parameters for process creation.
        /// </param>
        /// <param name="InProcessCreationFlags">
        /// Internally CREATE_SUSPENDED is already passed to CreateProcess(). With this
        /// parameter you can add more flags like DETACHED_PROCESS, CREATE_NEW_CONSOLE or
        /// whatever!
        /// </param>
        /// <param name="InLibraryPath_x86">
        /// A partially qualified assembly name or a relative/absolute file path of the 32-bit version of your library.
        /// For example "MyAssembly, PublicKeyToken=248973975895496" or ".\Assemblies\\MyAssembly.dll".
        /// </param>
        /// <param name="InLibraryPath_x64">
        /// A partially qualified assembly name or a relative/absolute file path of the 64-bit version of your library.
        /// For example "MyAssembly, PublicKeyToken=248973975895496" or ".\Assemblies\\MyAssembly.dll".
        /// </param>
        /// <param name="OutProcessId">
        /// The process ID of the newly created process.
        /// </param>
        /// <param name="InPassThruArgs">
        /// A serializable list of parameters being passed to your library entry points <c>Run()</c> and
        /// <c>Initialize()</c>.
        /// </param>
        /// <exception cref="ArgumentException">
        /// The given EXE path could not be found.
        /// </exception>
        public static void CreateAndInject(
            String InEXEPath,
            String InCommandLine,
            Int32 InProcessCreationFlags,
            String InLibraryPath_x86,
            String InLibraryPath_x64,
            RhAssemblyInfo[] Assemblies,
            out Int32 OutProcessId,
            params Object[] InPassThruArgs)
        {
            Int32             RemotePID;
            Int32             RemoteTID;
            MemoryStream      PassThru   = new MemoryStream();
            ManagedRemoteInfo RemoteInfo = new ManagedRemoteInfo();

            // create suspended process...
            NativeAPI.RtlCreateSuspendedProcess(
                InEXEPath,
                InCommandLine,
                InProcessCreationFlags,
                out RemotePID,
                out RemoteTID);


            try
            {
                InjectEx(
                    NativeAPI.GetCurrentProcessId(),
                    RemotePID,
                    RemoteTID,
                    0x20000000,
                    InLibraryPath_x86,
                    InLibraryPath_x64,
                    Assemblies,
                    true,
                    false,
                    InPassThruArgs);

                OutProcessId = RemotePID;
            }
            catch (Exception e)
            {
                try
                {
                    Process.GetProcessById(RemotePID).Kill();
                }
                catch (Exception) { }

                throw e;
            }
        }
Exemple #4
0
        internal static void InjectEx(
            Int32 InHostPID,
            Int32 InTargetPID,
            Int32 InWakeUpTID,
            Int32 InNativeOptions,
            String InLibraryPath_x86,
            String InLibraryPath_x64,
            Boolean InCanBypassWOW64,
            Boolean InCanCreateService,
            params Object[] InPassThruArgs)
        {
            MemoryStream      PassThru   = new MemoryStream();
            ManagedRemoteInfo RemoteInfo = new ManagedRemoteInfo();
            BinaryFormatter   Format     = new BinaryFormatter();
            Int32             NtStatus;

            HelperServiceInterface.BeginInjection(InTargetPID);

            try
            {
                RemoteInfo            = new ManagedRemoteInfo();
                RemoteInfo.HostPID    = InHostPID;
                RemoteInfo.UserParams = InPassThruArgs;

                GCHandle hPassThru = PrepareInjection(
                    RemoteInfo,
                    ref InLibraryPath_x86,
                    ref InLibraryPath_x64,
                    PassThru);

                /*
                 *  Inject library...
                 */
                try
                {
                    switch (NtStatus = NativeAPI.RhInjectLibraryEx(
                                InTargetPID,
                                InWakeUpTID,
                                NativeAPI.EASYHOOK_INJECT_MANAGED | InNativeOptions,
                                typeof(Config).Assembly.Location,
                                typeof(Config).Assembly.Location,
                                hPassThru.AddrOfPinnedObject(),
                                (int)PassThru.Length))
                    {
                    case NativeAPI.STATUS_WOW_ASSERTION:
                    {
                        // Use helper application to bypass WOW64...
                        if (InCanBypassWOW64)
                        {
                            WOW64Bypass.Inject(
                                InHostPID,
                                InTargetPID,
                                InWakeUpTID,
                                InNativeOptions,
                                InLibraryPath_x86,
                                InLibraryPath_x64,
                                InPassThruArgs);
                        }
                        else
                        {
                            throw new AccessViolationException("Unable to inject library into target process.");
                        }
                    } break;

                    case NativeAPI.STATUS_ACCESS_DENIED:
                    {
                        // Use service and try again...
                        if (InCanCreateService)
                        {
                            ServiceMgmt.Inject(
                                InHostPID,
                                InTargetPID,
                                InWakeUpTID,
                                InNativeOptions,
                                InLibraryPath_x86,
                                InLibraryPath_x64,
                                InPassThruArgs);
                        }
                        else
                        {
                            NativeAPI.Force(NtStatus);
                        }
                    } break;

                    case NativeAPI.STATUS_SUCCESS:
                    {
                        // wait for injection completion
                        HelperServiceInterface.WaitForInjection(InTargetPID);
                    } break;

                    default:
                    {
                        NativeAPI.Force(NtStatus);
                    } break;
                    }
                }
                finally
                {
                    hPassThru.Free();
                }
            }
            finally
            {
                HelperServiceInterface.EndInjection(InTargetPID);
            }
        }
Exemple #5
0
        internal static void InjectEx(
            Int32 InHostPID,
            Int32 InTargetPID,
            Int32 InWakeUpTID,
            Int32 InNativeOptions,
            String InLibraryPath_x86,
            String InLibraryPath_x64,
            Boolean InCanBypassWOW64,
            Boolean InCanCreateService,
            Boolean InRequireStrongName,
            params Object[] InPassThruArgs)
        {
            var PassThru = new MemoryStream();

            HelperServiceInterface.BeginInjection(InTargetPID);
            try
            {
                var RemoteInfo = new ManagedRemoteInfo();
                RemoteInfo.HostPID = InHostPID;
                // We first serialise parameters so that they can be deserialised AFTER the UserLibrary is loaded
                var format = new BinaryFormatter();
                var args   = new List <object>();
                if (InPassThruArgs != null)
                {
                    foreach (var arg in InPassThruArgs)
                    {
                        using (var ms = new MemoryStream())
                        {
                            format.Serialize(ms, arg);
                            args.Add(ms.ToArray());
                        }
                    }
                }
                RemoteInfo.UserParams = args.ToArray();

                RemoteInfo.RequireStrongName = InRequireStrongName;

                var hPassThru = PrepareInjection(
                    RemoteInfo,
                    ref InLibraryPath_x86,
                    ref InLibraryPath_x64,
                    PassThru);

                /*
                 *  Inject library...
                 */
                try
                {
                    Int32 NtStatus;
                    switch (NtStatus = NativeAPI.RhInjectLibraryEx(
                                InTargetPID,
                                InWakeUpTID,
                                NativeAPI.EASYHOOK_INJECT_MANAGED | InNativeOptions,
                                typeof(Config).Assembly.Location,
                                typeof(Config).Assembly.Location,
                                hPassThru.AddrOfPinnedObject(),
                                (int)PassThru.Length))
                    {
                    case NativeAPI.STATUS_WOW_ASSERTION:
                    {
                        // Use helper application to bypass WOW64...
                        if (InCanBypassWOW64)
                        {
                            WOW64Bypass.Inject(
                                InHostPID,
                                InTargetPID,
                                InWakeUpTID,
                                InNativeOptions,
                                InLibraryPath_x86,
                                InLibraryPath_x64,
                                InRequireStrongName,
                                InPassThruArgs);
                        }
                        else
                        {
                            throw new AccessViolationException("Unable to inject library into target process.");
                        }
                    }
                    break;

                    case NativeAPI.STATUS_ACCESS_DENIED:
                    {
                        // Use service and try again...
                        if (InCanCreateService)
                        {
                            ServiceMgmt.Inject(
                                InHostPID,
                                InTargetPID,
                                InWakeUpTID,
                                InNativeOptions,
                                InLibraryPath_x86,
                                InLibraryPath_x64,
                                InRequireStrongName,
                                InPassThruArgs);
                        }
                        else
                        {
                            NativeAPI.Force(NtStatus);
                        }
                    }
                    break;

                    case NativeAPI.STATUS_SUCCESS:
                    {
                        // wait for injection completion
                        HelperServiceInterface.WaitForInjection(InTargetPID);
                    }
                    break;

                    default:
                    {
                        NativeAPI.Force(NtStatus);
                    }
                    break;
                    }
                }
                finally
                {
                    hPassThru.Free();
                }
            }
            finally
            {
                HelperServiceInterface.EndInjection(InTargetPID);
            }
        }
Exemple #6
0
        private static GCHandle PrepareInjection(
            ManagedRemoteInfo InRemoteInfo,
            ref String InLibraryPath_x86,
            ref String InLibraryPath_x64,
            MemoryStream InPassThruStream)
        {
            if (String.IsNullOrEmpty(InLibraryPath_x86) && String.IsNullOrEmpty(InLibraryPath_x64))
            {
                throw new ArgumentException("At least one library for x86 or x64 must be provided");
            }

            // ensure full path information in case of file names...
            if ((InLibraryPath_x86 != null) && File.Exists(InLibraryPath_x86))
            {
                InLibraryPath_x86 = Path.GetFullPath(InLibraryPath_x86);
            }

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

            /*
             *  validate assembly name...
             */
            Assembly UserAsm;

            InRemoteInfo.UserLibrary = InLibraryPath_x86;

            if (NativeAPI.Is64Bit)
            {
                InRemoteInfo.UserLibrary = InLibraryPath_x64;
            }

            if (File.Exists(InRemoteInfo.UserLibrary))
            {
                // translate to assembly name
                InRemoteInfo.UserLibraryName = AssemblyName.GetAssemblyName(InRemoteInfo.UserLibrary).FullName;
            }

            // Attempt to load the library by its FullName and if that fails, by its original library filename
            if ((UserAsm = Assembly.ReflectionOnlyLoad(InRemoteInfo.UserLibraryName)) == null && (UserAsm = Assembly.ReflectionOnlyLoadFrom(InRemoteInfo.UserLibrary)) == null)
            {
                throw new DllNotFoundException("The given assembly could not be found.");
            }

            // Check for a strong name if necessary
            if (InRemoteInfo.RequireStrongName && (Int32)(UserAsm.GetName().Flags & AssemblyNameFlags.PublicKey) == 0)
            {
                throw new ArgumentException("The given assembly has no strong name.");
            }

            /*
             *  Convert managed arguments to binary stream...
             */

            var Format  = new BinaryFormatter();
            var Channel = IpcCreateServer <HelperServiceInterface>(
                ref InRemoteInfo.ChannelName,
                WellKnownObjectMode.Singleton);

            Format.Serialize(InPassThruStream, InRemoteInfo);

            return(GCHandle.Alloc(InPassThruStream.GetBuffer(), GCHandleType.Pinned));
        }