Hook is invoked only in Visual Studio

Oct 1, 2013 at 8:42 PM
Hi

I have a hook monitor with following code:
var monitor = new ActiveWindowMonitor();
            string channelName = null;
            IpcServerChannel ipcServer = null;
            var hookServer = new WindowMessageHook();
            var isHooked = false;
            monitor.ActiveWindowChanged += (sender, e) =>
                {
                    if (e.ActiveWindowTitle == "Form1" && !isHooked)
                    {
                        isHooked = true;
                        uint currentPid = 0;
                        GetWindowThreadProcessId(e.ActiveWindowHandle, out currentPid);                        
                        ipcServer = 
                            RemoteHooking.IpcCreateServer<WindowMessageHook>(ref channelName, 
                                WellKnownObjectMode.Singleton, 
                                hookServer, 
                                new WellKnownSidType[0]);

                       InjectToProcess((int)currentPid, channelName);
                    }
                };
          
            Application.Run();
        }

        private static void InjectToProcess(int pid, string channelName)
        {
            try
            {
                var fullPathToInjector = 
                    Path.Combine(Path.GetDirectoryName(typeof(WindowMessageHook).Assembly.Location), injector);

                RemoteHooking.Inject(pid, 
                    InjectionOptions.Default, 
                    fullPathToInjector, 
                    fullPathToInjector, 
                    new object[] { channelName });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Injection exception: {0}", ex.ToString());
            }
        }

        [DllImport("user32.dll", SetLastError = true)]
        static extern void GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
The code for WindowMessageHook:
public class WindowMessageHook : MarshalByRefObject
    {        

        public void OnGetWindowMessage(int pid, MSG msg)
        {
            Console.WriteLine("PID:{0}, Handle:{1}, Message:{2}", pid, msg.hwnd, msg.message); 
        }       
}
The code for dll injection:
public class WindowMessageInjection : IEntryPoint
    {
        private LocalHook _getWindowMessageHook;        
        private readonly WindowMessageHook _hookClient;
        private readonly GetMessageDelegate _getMessageDelegate;

        public WindowMessageInjection(EasyHook.RemoteHooking.IContext context, string channelName)
        {
            _hookClient = RemoteHooking.IpcConnectClient<WindowMessageHook>(channelName);
            _getMessageDelegate = GetMessageHooked;
        }

        public void Run(EasyHook.RemoteHooking.IContext context, string args)
        {
            try
            {
                var procAddress = LocalHook.GetProcAddress("user32.dll", "GetMessageW");
                _getWindowMessageHook = LocalHook.Create(procAddress, _getMessageDelegate, this);          
                     
                _getWindowMessageHook.ThreadACL.SetExclusiveACL(new int[1]);
            }
            catch (Exception ex)
            {
                _hookClient.ReportError(RemoteHooking.GetCurrentProcessId(), ex);
            }

        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);

        private static sbyte GetMessageHooked(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax)
        {            
            var injection = (WindowMessageInjection)HookRuntimeInfo.Callback;
         
            var result = GetMessage(out lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
            var pid = RemoteHooking.GetCurrentProcessId();                       
            injection._hookClient.OnGetWindowMessage(pid,  lpMsg);
            return result;
        }

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate sbyte GetMessageDelegate(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);

        [StructLayout(LayoutKind.Sequential)]
        public struct MSG
        {
            public IntPtr hwnd;
            public UInt32 message;
            public IntPtr wParam;
            public IntPtr lParam;
            public UInt32 time;
            public POINT pt;

            public static implicit operator System.Windows.Interop.MSG(MSG msg)
            {
                return new System.Windows.Interop.MSG
                {
                    hwnd = msg.hwnd,
                    lParam = msg.lParam,
                    message = (int)msg.message,
                    pt_x = msg.pt.X,
                    pt_y = msg.pt.Y,
                    time = (int)msg.time,
                    wParam = msg.wParam
                };
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }                     
        }       
    }
The hook is not invoked, when I run my monitor application and application (Form1) for injection. But when I run my monitor application and run application for injection from VS 2012, then all right, hook is invoked.

What is the problem?

Best regards
Oct 1, 2013 at 9:30 PM
You need to keep your hook in memory. Add these lines at the end of the Run method of WindowMessageInjection:
           // wait for host process termination...
            try
            {
                while (true)
                {
                    Thread.Sleep(500);
                    _interface.Ping(); // Ping is a simple method in your class which is derived from MarshalByRefObject
                }
            }
            catch
            {
                _interface = null;
                // .NET Remoting will raise an exception if host is unreachable
            }