Global Hook (WH_SHELL,WH_CBT)

Apr 30, 2010 at 5:28 PM

Hi,

I'm trying to create a easyhook project that uses SetWindowsHookEx to monitor WH_SHELL or WH_CBT events on all processes and pass them bacl to my UI Interface. It should work for both 32-bit and 64-bit processes. However iv'e been stuck for 2 days . I have created the 2 projects the UI simple console and the inject dll but I'm not sure how to register the delegate HOOKPROC and the Inject method expects a PID but I'm trying to do a global hook.

Does anyone have any examples or pointers for this please? Is it even possible?

Thanks

AF

Here's the code so far

WindowEasyHook.EXE

using System;
using System.Runtime.Remoting;
using System.Windows.Forms;
using EasyHook;
using WindowEasyHook.Interfaces;

namespace WindowEasyHook
{


    public class WindowEasyHookInterface : MarshalByRefObject
    {
        public void IsInstalled(Int32 inClientPid)
        {
            Console.WriteLine("EasyHook has been installed in target {0}.\r\n", inClientPid);
        }

        public void OnCreateFile(Int32 inClientPid, String[] inFileNames)
        {
            foreach (var t in inFileNames)
            {
                Console.WriteLine(t);
            }
        }

        public void ReportException(Exception inInfo)
        {
            Console.WriteLine("The target process has reported an error:\r\n" + inInfo);
        }

        public void Ping()
        {
        }

    }

    static class Program
    {
        static String _channelName;

        static void Main(string[] args)
        {
            int targetPid;

            if ((args.Length != 1) || !Int32.TryParse(args[0], out targetPid))
            {
                Console.WriteLine();
                Console.WriteLine("Usage: EasyHook %PID%");
                Console.WriteLine();

                return;
            }

            try
            {
                try
                {

                    Console.ReadLine();

                    Config.Register(
                        "A EasyHook like demo application.",
                        "WindowEasyHook.exe",
                        "WindowEasyHookInject.dll");
                }
                catch (ApplicationException ax)
                {
                    MessageBox.Show("This is an administrative task!", "Permission denied...", MessageBoxButtons.OK);
                    MessageBox.Show(ax.InnerException.Message, "Permission denied...", MessageBoxButtons.OK);
                   
                    System.Diagnostics.Process.GetCurrentProcess().Kill();
                }

                RemoteHooking.IpcCreateServer<WindowEasyHookInterface>(ref _channelName, WellKnownObjectMode.SingleCall);

                RemoteHooking.Inject(0,
                                     "WindowEasyHookInject.dll",
                                     "WindowEasyHookInject.dll",
                                     _channelName);



                Console.ReadLine();
            }
            catch (Exception extInfo)
            {
                Console.WriteLine("There was an error while connecting to target:\r\n{0}", extInfo);
            }
        }
    }
}

WindowEasyHookInject.DLL
 
using System;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.InteropServices;
using EasyHook;
using WindowEasyHook.Interfaces;

namespace WindowEasyHookInject
{
    public class Main : IEntryPoint
    {

        public enum HookTypes
        {

            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }

        public enum ShellHookMessages
        {

            HSHELL_WINDOWCREATED = 1,
            HSHELL_WINDOWDESTROYED = 2,
            HSHELL_ACTIVATESHELLWINDOW = 3,
            HSHELL_WINDOWACTIVATED = 4,
            HSHELL_GETMINRECT = 5,
            HSHELL_REDRAW = 6,
            HSHELL_TASKMAN = 7,
            HSHELL_LANGUAGE = 8,
            HSHELL_SYSMENU = 9,
            HSHELL_ENDTASK = 10,
            HSHELL_ACCESSIBILITYSTATE = 11,
            HSHELL_APPCOMMAND = 12,
            HSHELL_WINDOWREPLACED = 13,
            HSHELL_WINDOWREPLACING = 14


        }

        readonly WindowEasyHookInterface _interface;
        readonly Stack<String> _queue = new Stack<String>();

        LocalHook _createWindowHook;
        HookProc _myCallbackDelegate;

        public delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(HookTypes hookType, HookProc hookProc, IntPtr hInstance, uint nThreadId);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr CallNextHookEx(IntPtr hookHandle, int nCode, IntPtr wParam, IntPtr lParam);

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate IntPtr DSetWindowsHookEx(HookTypes hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        public static IntPtr MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code >= 0)
            {
                var msg = "";

                switch (code)
                {
                    case (int)ShellHookMessages.HSHELL_ACTIVATESHELLWINDOW:
                        msg = "_HOOK32_HSHELL_ACTIVATESHELLWINDOW";
                        break;
                    case (int)ShellHookMessages.HSHELL_GETMINRECT:
                        msg = "_HOOK32_HSHELL_GETMINRECT";
                        break;
                    case (int)ShellHookMessages.HSHELL_LANGUAGE:
                        msg = "_HOOK32_HSHELL_LANGUAGE";
                        break;
                    case (int)ShellHookMessages.HSHELL_REDRAW:
                        msg = "_HOOK32_HSHELL_REDRAW";
                        break;
                    case (int)ShellHookMessages.HSHELL_TASKMAN:
                        msg = "_HOOK32_HSHELL_TASKMAN";
                        break;
                    case (int)ShellHookMessages.HSHELL_WINDOWACTIVATED:
                        msg = "_HOOK32_HSHELL_WINDOWACTIVATED";
                        break;
                    case (int)ShellHookMessages.HSHELL_WINDOWCREATED:
                        msg = "_HOOK32_HSHELL_WINDOWCREATED";
                        break;
                    case (int)ShellHookMessages.HSHELL_WINDOWDESTROYED:
                        msg = "_HOOK32_HSHELL_WINDOWDESTROYED";
                        break;
                }

                if (msg != "")
                {
                }
                var thisProcess = (Main)HookRuntimeInfo.Callback;

                thisProcess._interface.OnCreateFile(2, new[] { "Callback Function" });

                lock (thisProcess._queue)
                {
                    thisProcess._queue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" +
                                            RemoteHooking.GetCurrentThreadId() + "]: \"" + msg + "\"");
                }
            }


            return CallNextHookEx(LocalHook.GetProcAddress("user32.dll", "CallNextHookExW"), code, wParam, lParam);

        }

        public Main(RemoteHooking.IContext InContext, String InChannelName)
        {
            // connect to host...
            //
            _interface = RemoteHooking.IpcConnectClient<WindowEasyHookInterface>(InChannelName);
            _interface.Ping();

        }

        public void Run(RemoteHooking.IContext InContext, String InChannelName)
        {
            // install hook...
            //
            try
            {

                _myCallbackDelegate = new HookProc(MyCallbackFunction);

                _createWindowHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "SetWindowsHookExW"), new DSetWindowsHookEx(SetWindowsHookEx_Hooked), _myCallbackDelegate);

                _createWindowHook.ThreadACL.SetExclusiveACL(new[] { 0 });


            }
            catch (Exception ex)
            {
                _interface.ReportException(ex);

                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;

                        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
            }
        }

        public static IntPtr SetWindowsHookEx_Hooked(HookTypes hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId)
        {
            try
            {
                var thisProcess = (Main)HookRuntimeInfo.Callback;

                thisProcess._interface.OnCreateFile(1, new[] { "SetWindowsHookEx_Hooked" });

                lock (thisProcess._queue)
                {
                    thisProcess._queue.Push("[" + RemoteHooking.GetCurrentProcessId() + ":" + RemoteHooking.GetCurrentThreadId() + "]: \"" + hookType + "\"");
                }

            }

            catch
            {
            }

            // call original API...
            //
            return SetWindowsHookEx(HookTypes.WH_SHELL, lpfn, hMod, dwThreadId);

        }

    }

}

 

May 12, 2010 at 10:00 AM

Hi,

Can anyone help me on this please.

Regards

AF