Exemple #1
0
        private int D3D9ResetDetour(IntPtr instance, ref NativeAPI.PresentParameters presentationParameters)
        {
            if (OnResetDevice != null)
                OnResetDevice(instance);

            return Reset(instance, ref presentationParameters);
        }
Exemple #2
0
 /// <summary>
 /// Loads the given driver into the kernel and immediately marks it for deletion.
 /// The installed driver will be registered with the service control manager under the
 /// <paramref name="InDriverName"/> you specify.
 /// Please note that you should use <see cref="IsX64System"/> to find out which
 /// driver to load. Even if your process is running on 32-Bit this does not mean,
 /// that the OS kernel is running on 32-Bit!
 /// </summary>
 /// <param name="InDriverPath"></param>
 /// <param name="InDriverName"></param>
 public static void InstallDriver(
     String InDriverPath,
     String InDriverName)
 {
     NativeAPI.RhInstallDriver(InDriverPath, InDriverName);
 }
Exemple #3
0
        int D3D9CreateDeviceDetour(IntPtr instance, uint adapter, uint deviceType, IntPtr focusWindow, uint behaviorFlags, ref NativeAPI.PresentParameters presentationParameters, out IntPtr returnedDeviceInterface)
        {
            // Invoke original create device function and retrieve the created device
            var result = Direct3D9CreateDevice(instance, adapter, deviceType, focusWindow, behaviorFlags, ref presentationParameters, out returnedDeviceInterface);
            Direct3DDevice9 = returnedDeviceInterface;
            Hwnd = focusWindow;
            if (hook_end_scene == null) {
                // Hook WndProc
                old_wndproc = NativeAPI.GetWindowLong(focusWindow, NativeAPI.GWL_WNDPROC);
                wnd_proc_delegate = new NativeAPI.WndProcDelegate(WndProcDetour);
                NativeAPI.SetWindowLong(focusWindow, NativeAPI.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(wnd_proc_delegate));

                // Hook EndScene
                var end_scene_pointer = Misc.GetVTableFunction(Direct3DDevice9, NativeAPI.EndSceneOffset);
                EndScene = Misc.GetDelegate<NativeAPI.Direct3D9EndScene>(end_scene_pointer);
                hook_end_scene = LocalHook.Create(end_scene_pointer, new NativeAPI.Direct3D9EndScene(EndSceneCallback), this);
                hook_end_scene.ThreadACL.SetExclusiveACL(new Int32[] { });
            }

            if (hook_reset == null) {
                // Hook Reset
                var reset_pointer = Misc.GetVTableFunction(Direct3DDevice9, NativeAPI.ResetOffset);
                Reset = Misc.GetDelegate<NativeAPI.Direct3D9ResetDelegate>(reset_pointer);
                hook_reset = LocalHook.Create(reset_pointer, new NativeAPI.Direct3D9ResetDelegate(D3D9ResetDetour), this);
                hook_reset.ThreadACL.SetExclusiveACL(new Int32[] { });
            }

            try {
                if (OnCreateDevice != null)
                    OnCreateDevice();
            } catch (Exception e) {
                MessageBox.Show(e.ToString());
            }
            return result;
        }
Exemple #4
0
 /// <summary>
 /// Returns the current native system thread ID.
 /// </summary>
 /// <remarks>
 /// Even if currently each dedicated managed
 /// thread (not a thread from a <see cref="ThreadPool"/>) exactly maps to one native
 /// system thread, this behavior may change in future versions.
 /// If you would like to have unintercepted threads, you should make sure that they are
 /// dedicated ones, e.g. derived from <see cref="Thread"/>.
 /// </remarks>
 /// <returns>The native system thread ID.</returns>
 public static Int32 GetCurrentThreadId()
 {
     return(NativeAPI.GetCurrentThreadId());
 }
Exemple #5
0
 /// <summary>
 /// Installs the EasyHook support driver. After this step you may use
 /// <see cref="InstallDriver"/> to install your kernel mode hooking component.
 /// </summary>
 public static void InstallSupportDriver()
 {
     NativeAPI.RhInstallSupportDriver();
 }
Exemple #6
0
 /// <summary>
 /// Returns the current native system process ID.
 /// </summary>
 /// <returns>The native system process ID.</returns>
 public static Int32 GetCurrentProcessId()
 {
     return(NativeAPI.GetCurrentProcessId());
 }
Exemple #7
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 #8
0
 /// <summary>
 /// If the library was injected with <see cref="CreateAndInject"/>, this will
 /// finally start the current process. You should call this method in the library
 /// <c>Run()</c> method after all hooks have been installed.
 /// </summary>
 public static void WakeUpProcess()
 {
     NativeAPI.RhWakeUpProcess();
 }
Exemple #9
0
 /// <summary>
 ///     RIP relocation is disabled by default. If you want to enable it,
 ///     just call this method which will attach a debugger to the current
 ///     process. There may be circumstances under which this might fail
 ///     and this is why it is not done by default. On 32-Bit system this
 ///     method will always succeed and do nothing...
 /// </summary>
 public static void EnableRIPRelocation()
 {
     NativeAPI.DbgAttachDebugger();
 }
Exemple #10
0
        /// <summary>
        ///     REQUIRES ADMIN PRIVILEGES. Installs EasyHook and all given user NET assemblies into the GAC and
        ///     ensures that all references are cleaned up if the installing application
        ///     is shutdown. Cleanup does not depend on the calling application...
        /// </summary>
        /// <remarks>
        ///     <para>
        ///         ATTENTION: There are some problems when debugging processes whose libraries
        ///         are added to the GAC. Visual Studio won't start the debug session! There is
        ///         only one chance for you to workaround this issue if you want to install
        ///         libraries AND debug them simultanously. This is simply to debug only one process
        ///         which is the default setting of Visual Studio. Because the libraries are added
        ///         to the GAC AFTER Visual Studio has initialized the debug session, there won't be
        ///         any conflicts; at least so far...
        ///     </para>
        ///     <para>
        ///         In debug versions of EasyHook, you may also check the "Application" event log, which holds additional
        ///         information
        ///         about the GAC registration, after calling this method. In general this method works
        ///         transactionally. This means if something goes wrong, the GAC state of all related libraries
        ///         won't be violated!
        ///     </para>
        ///     <para>
        ///         The problem with NET assemblies is that the CLR only searches the GAC and
        ///         directories starting with the application base directory for assemblies.
        ///         To get injected assemblies working either all of them have to be located
        ///         under the target base directory (which is not suitable in most cases) or
        ///         reside in the GAC.
        ///     </para>
        ///     <para>
        ///         EasyHook provides a way to automatically register all of its own assemblies
        ///         and custom ones temporarily in the GAC. It also ensures
        ///         that all of these assemblies are removed if the installing process exists.
        ///         So you don't need to care about and may write applications according to
        ///         the XCOPY standard. If your application ships with an installer, you may
        ///         statically install all of your assemblies and the ones of EasyHook into the
        ///         GAC. In this case just don't call <see cref="Register" />.
        ///     </para>
        ///     <para>
        ///         Of course EasyHook does also take care of multiple processes using the same
        ///         injection libraries. So if two processes are sharing some of those DLLs,
        ///         a stable reference counter ensures that the libraries are kept in the GAC
        ///         if one process is terminated while the other continues running and so continues
        ///         holding a proper GAC reference.
        ///     </para>
        ///     <para>
        ///         Please note that in order to add your library to the GAC, it has to be a valid
        ///         NET assembly and expose a so called "Strong Name". Assemblies without a strong
        ///         name will be rejected by this method!
        ///     </para>
        /// </remarks>
        /// <param name="InDescription">
        ///     A description under which the installed files should be referenced.
        /// </param>
        /// <param name="InUserAssemblies">
        ///     A list of user assemblies as relative or absolute paths.
        /// </param>
        /// <exception cref="System.IO.FileNotFoundException">
        ///     At least one of the files specified could not be found!
        /// </exception>
        /// <exception cref="BadImageFormatException">
        ///     Unable to load at least one of the given files for reflection.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     At least one of the given files does not have a strong name.
        /// </exception>
        public static void Register(
            String InDescription,
            params String[] InUserAssemblies)
        {
            var AsmList     = new List <Assembly>();
            var RemovalList = "";
            var InstallList = new List <String>();

            /*
             * Read and validate config file...
             */
            var Files = new List <string>();

            Files.Add(typeof(Config).Assembly.Location);

            Files.AddRange(InUserAssemblies);

            for (var i = 0; i < Files.Count; i++)
            {
                Assembly Entry;
                var      AsmPath = Path.GetFullPath(Files[i]);

                if (!File.Exists(AsmPath))
                {
                    throw new FileNotFoundException("The given assembly \"" + Files[i] + "\" (\"" + AsmPath + "\") does not exist.");
                }

                // just validate that this is a NET assembly with valid metadata...
                try
                {
                    Entry = Assembly.ReflectionOnlyLoadFrom(AsmPath);
                }
                catch (Exception ExtInfo)
                {
                    throw new BadImageFormatException("Unable to load given assembly \"" + Files[i] + "\" (\"" + AsmPath +
                                                      "\") for reflection. Is this a valid NET assembly?", ExtInfo);
                }

                // is strongly named? (required for GAC)
                var Name = AssemblyName.GetAssemblyName(AsmPath);

                if ((Name.Flags & AssemblyNameFlags.PublicKey) == 0)
                {
                    throw new ArgumentException("The given user library \"" + Files[i] + "\" is not strongly named!");
                }

                AsmList.Add(Entry);
                InstallList.Add(AsmPath);

                RemovalList += " \"" + Name.Name + "\"";
            }

            /*
             * Install assemblies into GAC ...
             */

            // create unique installation identifier
            var IdentData = new Byte[30];

            new RNGCryptoServiceProvider().GetBytes(IdentData);

            // run cleanup service
            InDescription = InDescription.Replace('"', '\'');

            RunCommand(
                "GACRemover", false, false, GetDependantSvcExecutableName(), Process.GetCurrentProcess().Id.ToString() + " \"" +
                Convert.ToBase64String(IdentData) + "\" \"" + InDescription + "\"" + RemovalList);

            // install assemblies
            NativeAPI.GacInstallAssemblies(
                InstallList.ToArray(),
                InDescription,
                Convert.ToBase64String(IdentData));
        }