Click or drag to resize

LocalHook Class

This class will provide various static members to be used with local hooking and is also the instance class of a hook.
Inheritance Hierarchy

Namespace:  EasyHook
Assembly:  EasyHook (in EasyHook.dll) Version: 2.7.6270.0 (2.7.6270.0)
Syntax
public class LocalHook : CriticalFinalizerObject, IDisposable

The LocalHook type exposes the following members.

Properties
  NameDescription
Public propertyCallback
The callback passed to Create(IntPtr, Delegate, Object).
Public propertyStatic memberGlobalThreadACL
Returns the gloabl thread ACL associated with ALL hooks. Refer to IsThreadIntercepted(Int32) for more information about access negotiation.
Public propertyHookBypassAddress
Returns the trampoline bypass address associated with this hook.
Public propertyThreadACL
Returns the thread ACL associated with this hook. Refer to IsThreadIntercepted(Int32) for more information about access negotiation.
Top
Methods
  NameDescription
Public methodStatic memberCreate
Installs a managed hook. After this you'll have to activate it by setting a proper ThreadACL.
Public methodStatic memberCreateUnmanaged
Installs an unmanaged hook. After this you'll have to activate it by setting a proper ThreadACL. HookRuntimeInfo WON'T be supported! Refer to the native "LhBarrierXxx" APIs to access unmanaged hook runtime information.
Public methodDispose
If you want to immediately uninstall a hook, the only way is to dispose it. A disposed hook is guaranteed to never invoke your handler again but may still consume memory even for process life-time!
Public methodStatic memberEnableRIPRelocation
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...
Public methodEquals
Determines whether the specified Object is equal to the current Object.
(Inherited from Object.)
Protected methodFinalize
Ensures that each instance is always terminated with Dispose.
(Overrides CriticalFinalizerObjectFinalize.)
Public methodGetHashCode
Serves as a hash function for a particular type.
(Inherited from Object.)
Public methodStatic memberGetNameByHandle
Reads the kernel object name for a given windows usermode handle. Executes in approx. 100 micro secounds.
Public methodStatic memberGetProcAddress
Will return the address for a given DLL export symbol. The specified module has to be loaded into the current process space and also export the given method.
Public methodStatic memberGetProcDelegateTDelegate
Will return a delegate for a given DLL export symbol. The specified module has to be loaded into the current process space and also export the given method.
Public methodStatic memberGetProcessIdByHandle
Tries to get the underlying process ID for a given handle.
Public methodStatic memberGetThreadIdByHandle
Tries to get the underlying thread ID for a given handle.
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodIsThreadIntercepted
Checks whether a given thread ID will be intercepted by the underlying hook.
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodStatic memberRelease
Processes any pending hook removals. Warning! This method can be quite slow (1 second) under certain circumstances.
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Top
Remarks
The following demonstrates how to use LocalHook:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using EasyHook;

namespace FileMonInject
{
    public class Main : EasyHook.IEntryPoint
    {
        FileMon.FileMonInterface Interface;
        LocalHook CreateFileHook;
        Stack<String> Queue = new Stack<String> ();

        public Main(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // connect to host...
            Interface = RemoteHooking.IpcConnectClient<FileMon.FileMonInterface>(InChannelName);

            // validate connection...
            Interface.Ping();
        }

        public void Run(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // install hook...
            try
            {
                CreateFileHook = LocalHook.Create(
                    LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"),
                    new DCreateFile(CreateFile_Hooked),
                    this);

                CreateFileHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
            }
            catch (Exception ExtInfo)
            {
                Interface.ReportException(ExtInfo);

                return;
            }

            Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());

            RemoteHooking.WakeUpProcess();

            // wait for host process termination...
            try
            {
                while (true)
                {
                    Thread.Sleep(500);

                    // transmit newly monitored file accesses...
                    if (Queue.Count > 0)
                    {
                        String[] Package = null;

                        lock (Queue)
                        {
                            Package = Queue.ToArray();

                            Queue.Clear();
                        }

                        Interface.OnCreateFile(RemoteHooking.GetCurrentProcessId(), Package);
                    }
                    else
                        Interface.Ping();
                }
            }
            catch
            {
                // Ping() will raise an exception if host is unreachable
            }
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode,
            SetLastError = true)]
        delegate IntPtr DCreateFile(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);

        // just use a P-Invoke implementation to get native API access from C# (this step is not necessary for C++.NET)
        [DllImport("kernel32.dll",
            CharSet = CharSet.Unicode,
            SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern IntPtr CreateFile(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);

        // this is where we are intercepting all file accesses!
        static IntPtr CreateFile_Hooked(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile)
        {

            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;

                lock (This.Queue)
                {
                    This.Queue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" + 
                        RemoteHooking.GetCurrentThreadId() +  "]: \"" + InFileName + "\"");
                }
            }
            catch
            {
            }

            // call original API...
            return CreateFile(
                InFileName,
                InDesiredAccess,
                InShareMode,
                InSecurityAttributes,
                InCreationDisposition,
                InFlagsAndAttributes,
                InTemplateFile);
        }
    }
}
See Also