Example #1
0
        private static void Release(Type InEntryPoint)
        {
            if (InEntryPoint == null)
            {
                return;
            }

            LocalHook.Release();
        }
Example #2
0
        /// <summary>
        /// Installs an unmanaged hook. After this you'll have to activate it by setting a proper <see cref="ThreadACL"/>.
        /// <see cref="HookRuntimeInfo"/> WON'T be supported! Refer to the native "LhBarrierXxx" APIs to
        /// access unmanaged hook runtime information.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Note that not all entry points are hookable! In general methods like <c>CreateFileW</c>
        /// won't cause any trouble. But there may be methods that are not hookable because their
        /// entry point machine code is not eligable to be hooked. You should test all hooks on
        /// common environments like "Windows XP x86/x64 SP1/SP2/SP3" and "Windows Vista x86/x64 (SP1)".
        /// This is the only way to ensure that your application will work well on most machines.
        /// </para><para>
        /// Unmanaged hooks will require a native DLL which handles the requests. This way
        /// you will get a high-performance interface, because
        /// a switch from unmanaged to managed code seems to be rather time consuming without doing anything
        /// useful (at least nothing visible); so a hook omitting this switch will be handled one or two
        /// orders of magnitudes faster until finally your handler gains execution. But as a managed hook is still executed
        /// within at last 1000 nano-seconds, even the "slow" managed implementation will be fast enough in most
        /// cases. With C++.NET you would be able to provide such native high-speed hooks for frequently
        /// called API methods, while still using managed ones for usual API methods, within a single assembly!
        /// A pure unmanaged, empty hook executes in approx. 70 nano-seconds, which is incredible fast
        /// considering the thread deadlock barrier and thread ACL negotiation that are already included in this benchmark!
        /// </para>
        /// </remarks>
        /// <param name="InTargetProc">A target entry point that should be hooked.</param>
        /// <param name="InNewProc">A handler with the same signature as the original entry point
        /// that will be invoked for every call that has passed the Thread Deadlock Barrier and various integrity checks.</param>
        /// <param name="InCallback">An uninterpreted callback that will later be available through <c>LhBarrierGetCallback()</c>.</param>
        /// <returns>
        /// A handle to the newly created hook.
        /// </returns>
        /// <exception cref="OutOfMemoryException">
        /// Not enough memory available to complete the operation. On 64-Bit this may also indicate
        /// that no memory can be allocated within a 31-Bit boundary around the given entry point.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The given function pointer does not map to executable memory (valid machine code) or
        /// you passed <c>null</c> as delegate.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The given entry point contains machine code that can not be hooked.
        /// </exception>
        /// <exception cref="InsufficientMemoryException">
        /// The maximum amount of hooks has been installed. This is currently set to MAX_HOOK_COUNT (1024).
        /// </exception>
        public static LocalHook CreateUnmanaged(
            IntPtr InTargetProc,
            IntPtr InNewProc,
            IntPtr InCallback)
        {
            LocalHook Result = new LocalHook();

            Result.m_Callback   = InCallback;
            Result.m_Handle     = Marshal.AllocCoTaskMem(IntPtr.Size);
            Result.m_SelfHandle = GCHandle.Alloc(Result, GCHandleType.Weak);

            // workitem/13695 & workitem/25580
            Marshal.WriteIntPtr(Result.m_Handle, IntPtr.Zero);

            try
            {
                NativeAPI.LhInstallHook(
                    InTargetProc,
                    InNewProc,
                    InCallback,
                    Result.m_Handle);
            }
            catch (Exception e)
            {
                Marshal.FreeCoTaskMem(Result.m_Handle);
                Result.m_Handle = IntPtr.Zero;

                Result.m_SelfHandle.Free();

                throw e;
            }

            Result.m_ThreadACL = new HookAccessControl(Result.m_Handle);

            return(Result);
        }
Example #3
0
        /// <summary>
        /// Installs a managed hook. After this you'll have to activate it by setting a proper <see cref="ThreadACL"/>.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Note that not all entry points are hookable! In general methods like <c>CreateFileW</c>
        /// won't cause any trouble. But there might be methods that are not hookable because their
        /// entry point machine code is not eligable to be hooked. You should test all hooks on
        /// common environments like "Windows XP x86/x64 SP2/SP3" and "Windows Vista x86/x64 (SP1)".
        /// This is the only way to ensure that your application will work well on most machines.
        /// </para><para>
        /// Your handler delegate has to use the <see cref="UnmanagedFunctionPointerAttribute"/> and
        /// shall map to the same native method signature, otherwise the application will crash! The best
        /// way is to use predefined delegates used in related P-Invoke implementations usually found with Google.
        /// If you know how to write such native delegates you won't need internet resources of course.
        /// I recommend using C++.NET which allows you to just copy the related windows API to your managed
        /// class and thread it as delegate without any changes. This will also speed up the whole thing
        /// because no unnecessary marshalling is required! C++.NET is also better in most cases because you
        /// may access the whole native windows API from managed code without any effort what significantly eases
        /// writing of hook handlers.
        /// </para>
        /// <para>
        /// The given delegate is automatically prevented from being garbage collected until the hook itself
        /// is collected...
        /// </para>
        /// </remarks>
        /// <param name="InTargetProc">A target entry point that should be hooked.</param>
        /// <param name="InNewProc">A handler with the same signature as the original entry point
        /// that will be invoked for every call that has passed the Fiber Deadlock Barrier and various integrity checks.</param>
        /// <param name="InCallback">An uninterpreted callback that will later be available through <see cref="HookRuntimeInfo.Callback"/>.</param>
        /// <returns>
        /// A handle to the newly created hook.
        /// </returns>
        /// <exception cref="OutOfMemoryException">
        /// Not enough memory available to complete the operation. On 64-Bit this may also indicate
        /// that no memory can be allocated within a 31-Bit boundary around the given entry point.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The given function pointer does not map to executable memory (valid machine code) or
        /// you passed <c>null</c> as delegate.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The given entry point contains machine code that can not be hooked.
        /// </exception>
        /// <exception cref="InsufficientMemoryException">
        /// The maximum amount of hooks has been installed. This is currently set to MAX_HOOK_COUNT (1024).
        /// </exception>
        public static LocalHook Create(
            IntPtr InTargetProc,
            Delegate InNewProc,
            Object InCallback)
        {
            LocalHook Result = new LocalHook();

            Result.m_Callback   = InCallback;
            Result.m_HookProc   = InNewProc;
            Result.m_Handle     = Marshal.AllocCoTaskMem(IntPtr.Size);
            Result.m_SelfHandle = GCHandle.Alloc(Result, GCHandleType.Weak);

            Marshal.WriteIntPtr(Result.m_Handle, IntPtr.Zero);

            try
            {
                NativeAPI.LhInstallHook(
                    InTargetProc,
                    Marshal.GetFunctionPointerForDelegate(Result.m_HookProc),
                    GCHandle.ToIntPtr(Result.m_SelfHandle),
                    Result.m_Handle);
            }
            catch (Exception e)
            {
                Marshal.FreeCoTaskMem(Result.m_Handle);
                Result.m_Handle = IntPtr.Zero;

                Result.m_SelfHandle.Free();

                throw e;
            }

            Result.m_ThreadACL = new HookAccessControl(Result.m_Handle);

            return(Result);
        }