Click here to Skip to main content
15,891,529 members
Articles / Desktop Programming / Win32

Spying Window Messages from the Inside

Rate me:
Please Sign up or sign in to vote.
4.94/5 (25 votes)
18 Feb 2009GPL36 min read 108.8K   13.9K   136  
An article on Hooking and Monitoring Window messages
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Xml;
using System.Threading;
using System.IO;


namespace DeviareMsgSpy
{
    public partial class Window : Form
    {
        public System.Windows.Forms.OpenFileDialog openFileDialog;
        public String xmlLocation;
        static List<ManualResetEvent> doneEvents = new List<ManualResetEvent>();
        private bool _capturing;
        private Image _finderHome;
        public long msgNumber = 1;
        private Image _finderGone;
        private Cursor _cursorDefault;
        private Cursor _cursorFinder;
        private IntPtr _hPreviousWindow;
        private bool _Pst = false;
        private bool _Dis = true;
        public string _filelocation = "newfinal.xml";
        #region WorkerData
        public struct WorkerData
        {
            public string rtrnval;
            public string name;
            public string hex;
            public string wparam;
            public string lparam;
            public DeviareParams.IParam recvWParam;
            public DeviareParams.IParam recvLParam;
            public uint recvMsgUint;
            public string stRecvWParam;
            public string stRecvLParam;
            public ManualResetEvent doneEvent;
            public string rtrntype;
            public string rtrninfo;
            public string rtrnmisc;
            public string wparamtype;
            public string wparammiscinfo;
            public string lparamtype;
            public string lparammiscinfo;
            public string miscinfo;
            public string posted;
        };
        #endregion
        /// <summary>
        /// Attributes
        /// </summary>
        private Deviare.SpyMgr _mgr = null;
        Deviare.Hook _hook = null;
        Deviare.Hook _hook2 = null;
        Deviare.Hook _hook3 = null;
        Deviare.Hook _hook4 = null;
        Deviare.Hook _hook5 = null;
        Deviare.Hook _hook6 = null;
        Deviare.Hook _hook7 = null;
        Deviare.Hook _hook8 = null;
        Deviare.Hook _hook9 = null;
        Deviare.Hook _hook10 = null;
        Deviare.Hook _hook11 = null;
        Deviare.Hook _hook12 = null;
        DeviareTools.IProcesses procs;
        public static XmlDocument _xmlDoc = new XmlDocument();
        public static XmlNodeList _message;
        XmlAttributeCollection xmlattrc;

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            Application.Exit();
        }  

        DeviareTools.IProcess proc;
   
        /// <summary>
        /// Window class.
        /// </summary>
        public Window()
        {
            _xmlDoc.Load(_filelocation);
            _message = _xmlDoc.GetElementsByTagName("message");
         


            InitializeComponent();
            _cursorDefault = Cursor.Current;
            _cursorFinder = EmbeddedResources.LoadCursor(EmbeddedResources.Finder);
            _finderHome = EmbeddedResources.LoadImage(EmbeddedResources.FinderHome);
            _finderGone = EmbeddedResources.LoadImage(EmbeddedResources.FinderGone);

            _pictureBox.Image = _finderHome;
            _pictureBox.MouseDown += new MouseEventHandler(OnFinderToolMouseDown);
            _mgr = new Deviare.SpyMgr();

           
            this.openFileDialog = new System.Windows.Forms.OpenFileDialog();

        }


        private void button1_Click(object sender, EventArgs e)
        {
            if (_hook != null)
            {
                if (_Pst == true) // Remove Post and Send hooks
                {
                    _xmlDoc.Load(_filelocation);

                    _hook.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook.Unhook();
                    _hook = null;
                    _hook2.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                    _hook2.Unhook();
                    _hook2 = null;
                    _hook3.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook3.Unhook();
                    _hook3 = null;
                    _hook4.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                    _hook4.Unhook();
                    _hook4 = null;
                    _hook5.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook5.Unhook();
                    _hook5 = null;
                    _hook6.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook6.Unhook();
                    _hook6 = null;
                    _hook7.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook7.Unhook();
                    _hook7 = null;
                    _hook8.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook8.Unhook();
                    _hook8 = null;
                    _hook9.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook9.Unhook();
                    _hook9 = null;
                    _hook10.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                    _hook10.Unhook();
                    _hook10 = null;
                    _hook11.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                    _hook11.Unhook();
                    _hook11 = null;
                    _hook12.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                    _hook12.Unhook();
                    _hook12 = null;
                    button1.Text = "Install";
                    _txtProc.Enabled = true;
                    _DispatchMsgBtn.Enabled = true;
                    _PstMsgBtn.Enabled = true;
                    _pictureBox.Enabled = true;
                    _textBoxHandle.Enabled = true;
                    _textBoxText.Enabled = true;
                    _textBoxClass.Enabled = true;
                    _textBoxRect.Enabled = true;
                    return;
                }
                if (_Dis == true) // Remove Dispatch hooks
                {
                    _xmlDoc.Load(_filelocation);
                    _hook.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookDisp_OnFunctionCalled);
                    _hook.Unhook();
                    _hook = null;
                    _hook2.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookDisp_OnFunctionCalled);
                    _hook2.Unhook();
                    _hook2 = null;
                    if (_hook3 != null)
                    {
                        _hook3.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook3.Unhook();
                        _hook3 = null;
                    }
                    if (_hook4 != null)
                    {
                        _hook4.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                        _hook4.Unhook();
                        _hook4 = null;
                    }
                    if (_hook5 != null)
                    {
                        _hook5.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook5.Unhook();
                        _hook5 = null;
                    }
                    if (_hook6 != null)
                    {
                        _hook6.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook6.Unhook();
                        _hook6 = null;
                    }
                    if (_hook7 != null)
                    {
                        _hook7.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook7.Unhook();
                        _hook7 = null;
                    }
                    if (_hook8 != null)
                    {
                        _hook8.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook8.Unhook();
                        _hook8 = null;
                    }
                    if (_hook9 != null)
                    {
                        _hook9.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook9.Unhook();
                        _hook9 = null;
                    }
                    if (_hook10 != null)
                    {
                        _hook10.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                        _hook10.Unhook();
                        _hook10 = null;
                    }
                    if (_hook11 != null)
                    {
                        _hook11.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                        _hook11.Unhook();
                        _hook11 = null;
                    }
                    if (_hook12 != null)
                    {
                        _hook12.OnFunctionCalled -= new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                        _hook12.Unhook();
                        _hook12 = null;
                    }
                    button1.Text = "Install";
                    _txtProc.Enabled = true;
                    _DispatchMsgBtn.Enabled = true;
                    _PstMsgBtn.Enabled = true;
                    _pictureBox.Enabled = true;
                    _textBoxHandle.Enabled = true;
                    _textBoxText.Enabled = true;
                    _textBoxClass.Enabled = true;
                    _textBoxRect.Enabled = true;
                    return;
                }
            }

            procs = _mgr.get_Processes(0);
            proc = procs.get_Item(_txtProc.Text); 
            

            
            if (proc == null)
            {
                procs.Refresh();
                proc = procs.get_Item(_txtProc.Text);
                if(proc == null) // If the process is not found refresh the processes.
                {
                    MessageBox.Show("No such process. Refreshing Processes");
                    return;
                }

            }
            DeviareTools.IPEModuleInfo mod = proc.Modules.get_ModuleByName("user32.dll");
            if (mod == null)
            {
                MessageBox.Show("Process is not connected.");
                return;
            }

            DeviareTools.IExportedFunction fnc;
            DeviareTools.IExportedFunction fnc2;
            DeviareTools.IExportedFunction fnc3;
            DeviareTools.IExportedFunction fnc4;
            DeviareTools.IExportedFunction fnc5;
            DeviareTools.IExportedFunction fnc6;
            DeviareTools.IExportedFunction fnc7;
            DeviareTools.IExportedFunction fnc8;
            DeviareTools.IExportedFunction fnc9;
            DeviareTools.IExportedFunction fnc10;
            DeviareTools.IExportedFunction fnc11;
            DeviareTools.IExportedFunction fnc12;
            if (_Pst == true) // Add Post and Send hooks
            {
                _xmlDoc.Load(_filelocation);
                fnc = mod.Functions.get_ItemByName("PostMessageW"); //Post
                fnc2 = mod.Functions.get_ItemByName("SendMessageW");
                fnc3 = mod.Functions.get_ItemByName("PostMessageA"); //Post
                fnc4 = mod.Functions.get_ItemByName("SendMessageA");
                fnc5 = mod.Functions.get_ItemByName("SendMessageCallbackW"); //Post
                fnc6 = mod.Functions.get_ItemByName("SendMessageCallbackA");//Post
                fnc7 = mod.Functions.get_ItemByName("SendNotifyMessageW"); //Post
                fnc8 = mod.Functions.get_ItemByName("SendNotifyMessageA");//Post
                fnc9 = mod.Functions.get_ItemByName("PostThreadMessageW"); //Post
                fnc10 = mod.Functions.get_ItemByName("PostThreadMessageA");//Post
                fnc11 = mod.Functions.get_ItemByName("SendMessageTimeoutW");
                fnc12 = mod.Functions.get_ItemByName("SendMessageTimeoutA");
                _hook = _mgr.CreateHook(fnc);
                _hook.Attach(proc);
                _hook.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook.Hook();
                _hook2 = _mgr.CreateHook(fnc2);
                _hook2.Attach(proc);
                _hook2.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                _hook2.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook2.Hook();
                _hook3 = _mgr.CreateHook(fnc3);
                _hook3.Attach(proc);
                _hook3.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook3.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook3.Hook();
                _hook4 = _mgr.CreateHook(fnc4);
                _hook4.Attach(proc);
                _hook4.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                _hook4.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook4.Hook();
                _hook5 = _mgr.CreateHook(fnc5);
                _hook5.Attach(proc);
                _hook5.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook5.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook5.Hook();
                _hook6 = _mgr.CreateHook(fnc6);
                _hook6.Attach(proc);
                _hook6.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook6.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook6.Hook();
                _hook7 = _mgr.CreateHook(fnc7);
                _hook7.Attach(proc);
                _hook7.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook7.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook7.Hook();
                _hook8 = _mgr.CreateHook(fnc8);
                _hook8.Attach(proc);
                _hook8.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook8.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook8.Hook();
                _hook9 = _mgr.CreateHook(fnc9);
                _hook9.Attach(proc);
                _hook9.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook9.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook9.Hook();
                _hook10 = _mgr.CreateHook(fnc10);
                _hook10.Attach(proc);
                _hook10.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookPst_OnFunctionCalled);
                _hook10.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook10.Hook();
                _hook11 = _mgr.CreateHook(fnc11);
                _hook11.Attach(proc);
                _hook11.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                _hook11.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook11.Hook();
                _hook12 = _mgr.CreateHook(fnc12);
                _hook12.Attach(proc);
                _hook12.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hook_OnFunctionCalled);
                _hook12.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook12.Hook();
            }
            else if (_Dis == true) // Add Dispatch hooks

            {
                _xmlDoc.Load(_filelocation);
                fnc = mod.Functions.get_ItemByName("DispatchMessageW");
                fnc2 = mod.Functions.get_ItemByName("DispatchMessageA");

                _hook = _mgr.CreateHook(fnc);
                _hook.Attach(proc);
                _hook.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookDisp_OnFunctionCalled);
                _hook.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook.Hook();
                _hook2 = _mgr.CreateHook(fnc2);
                _hook2.Attach(proc);
                _hook2.OnFunctionCalled += new Deviare.DHookEvents_OnFunctionCalledEventHandler(_hookDisp_OnFunctionCalled);
                _hook2.Properties = (int)DeviareCommonLib.NktHookFlags._call_before;
                _hook2.Hook(); 
            }

            _txtProc.Enabled = false;
            _DispatchMsgBtn.Enabled = false;
            _PstMsgBtn.Enabled = false;
            _pictureBox.Enabled = false;
            _textBoxHandle.Enabled = false;
            _textBoxText.Enabled = false;
            _textBoxClass.Enabled = false;
            _textBoxRect.Enabled = false;
            button1.Text = "Uninstall";
        }

        public WorkerData lookupMsgs(uint _recvMsg)  // Looks up the recieved message in the Xml and returns info on it
        {

            uint number = uint.Parse(_recvMsg.ToString().ToLower());
            string msgValue = "0x" + number.ToString("x"); // Convert the message to hex
            xmlattrc = _message[0].Attributes;
            WorkerData wd = new WorkerData();
            string[] returnRes = new string[12];
            for (int i = 0; i < _message.Count; i++)
            {
                xmlattrc = _message[i].Attributes;
                if (xmlattrc[0].Value.ToLower() == msgValue)
                {
                    XmlNode node = _message[i];
                    XmlNode name = node.SelectSingleNode("name");
                    XmlNode returnValue = node.SelectSingleNode("return");
                    XmlNode returnInfo = returnValue.SelectSingleNode("returninfo");
                    XmlNode returnMisc = returnValue.SelectSingleNode("returnmisc");
                    XmlNode wparam = node.SelectSingleNode("wparam");
                    XmlNode wname = wparam.SelectSingleNode("wname");
                    XmlNode wmisc = wparam.SelectSingleNode("wmisc");
                    XmlNode lparam = node.SelectSingleNode("lparam");
                    XmlNode lname = lparam.SelectSingleNode("lname");
                    XmlNode lmisc = lparam.SelectSingleNode("lmisc");
                    wd.name = name.InnerText.ToString();
                    wd.hex = msgValue;
                    wd.wparam = wname.InnerText.ToString();
                    wd.lparam = lname.InnerText.ToString();
                    wd.rtrntype = returnValue.Attributes.Item(0).Value.ToString();
                    wd.rtrninfo = returnInfo.InnerText.ToString();
                    wd.rtrnmisc = returnMisc.InnerText.ToString();
                    wd.wparamtype = wparam.Attributes.Item(0).Value.ToString();
                    wd.wparammiscinfo = wmisc.InnerText.ToString();
                    wd.lparamtype = lparam.Attributes.Item(0).Value.ToString();
                    wd.lparammiscinfo = lmisc.InnerText.ToString();   
                    return wd; // Return known 
                }
            }
            wd.name = "Name Not Known";
            wd.wparam = "wParam Not Known";
            wd.lparam = "lParam Not Known";
            wd.hex = msgValue;
            wd.rtrntype = "return type not known";
            wd.rtrninfo = "return info not known";
            wd.rtrnmisc = "return misc not known";
            wd.wparamtype = "wparam type not known";
            wd.wparammiscinfo = "wparam misc info not known";
            wd.lparamtype = "lparam type not known";
            wd.lparammiscinfo = "lparam misc info not known";       
            return wd; // Return not known
        }

        void _hook_OnFunctionCalled(DeviareTools.IProcess proc, DeviareParams.ICallInfo callInfo, Deviare.IRemoteCall rCall) // Hooks send messages
        {
            int returnVal = callInfo.ReturnValue;
            DeviareParams.IParams pms = callInfo.Params;
            DeviareParams.IEnumParams enm = pms.Enumerator;  
            DeviareParams.IParam pm = enm.First;
            DeviareParams.IParam recvMsgHndl = pms.get_Item(0);
            DeviareParams.IParam recvMsgParam = pms.get_Item(1);
            DeviareParams.IParam recvWParam = pms.get_Item(2);
            DeviareParams.IParam recvLParam = pms.get_Item(3);
            uint handle = uint.Parse(_textBoxHandle.Text); // Our selected window handler 
            uint recvWndHndlr = uint.Parse(recvMsgHndl.Value.ToString()); // Hooked window handler 
            uint recvMsgUint = uint.Parse(recvMsgParam.Value.ToString()); // Message value
            String msgOutput = "Window: " + recvMsgHndl.Value.ToString() + "\r\n";              
            if (recvWndHndlr == handle) // Our selected window gets a message
            {
                WorkerData wd = lookupMsgs(recvMsgUint);
                WaitCallback wc = new WaitCallback(workerCallback);                
                wd.posted = "S: ";
                wd.recvWParam = recvWParam;
                wd.recvLParam = recvLParam;
                wd.recvMsgUint = recvMsgUint;
                wd.stRecvWParam = recvWParam.Value.ToString();
                wd.stRecvLParam = recvLParam.Value.ToString();
                wd.rtrnval = returnVal.ToString();
                wd.doneEvent = new ManualResetEvent(false);
                doneEvents.Add(wd.doneEvent);
                ThreadPool.QueueUserWorkItem(wc, wd);
            }
        }

        void _hookPst_OnFunctionCalled(DeviareTools.IProcess proc, DeviareParams.ICallInfo callInfo, Deviare.IRemoteCall rCall) // Hooks Post messages
        {
            int returnVal = callInfo.ReturnValue;
            DeviareParams.IParams pms = callInfo.Params;
            DeviareParams.IEnumParams enm = pms.Enumerator;
            DeviareParams.IParam pm = enm.First;
            DeviareParams.IParam recvMsgHndl = pms.get_Item(0);
            DeviareParams.IParam recvMsgParam = pms.get_Item(1);
            DeviareParams.IParam recvWParam = pms.get_Item(2);
            DeviareParams.IParam recvLParam = pms.get_Item(3);
            uint handle = uint.Parse(_textBoxHandle.Text); // Our selected window handler 
            uint recvWndHndlr = uint.Parse(recvMsgHndl.Value.ToString()); // Hooked window handler 
            uint recvMsgUint = uint.Parse(recvMsgParam.Value.ToString()); // Message value
            String msgOutput = "Window: " + recvMsgHndl.Value.ToString() + "\r\n";            
            if (recvWndHndlr == handle) // Our selected window gets a message
            {
                WorkerData wd = lookupMsgs(recvMsgUint);
                WaitCallback wc = new WaitCallback(workerCallback);                
                wd.posted = "P: ";                
                wd.recvWParam = recvWParam;
                wd.recvLParam = recvLParam;
                wd.recvMsgUint = recvMsgUint;
                wd.stRecvWParam = recvWParam.Value.ToString();
                wd.stRecvLParam = recvLParam.Value.ToString();
                wd.rtrnval = returnVal.ToString();
                wd.doneEvent = new ManualResetEvent(false);                
                doneEvents.Add(wd.doneEvent);
                ThreadPool.QueueUserWorkItem(wc, wd);
            }
        }

        void _hookDisp_OnFunctionCalled(DeviareTools.IProcess proc, DeviareParams.ICallInfo callInfo, Deviare.IRemoteCall rCall) // Hooks Dispatch messages
        {
            DeviareParams.IParams pms = callInfo.Params;
            DeviareParams.IEnumParams enm = pms.Enumerator;
            DeviareParams.IParam pm = enm.First.Evaluated;
            DeviareParams.IParam recvMsgHndl = pm.Fields.get_Item(0);
            DeviareParams.IParam recvMsgParam = pm.Fields.get_Item(1);
            DeviareParams.IParam recvWParam = pm.Fields.get_Item(2);
            DeviareParams.IParam recvLParam = pm.Fields.get_Item(3);
           
            uint handle = uint.Parse(_textBoxHandle.Text); // Our selected window handler 
            uint recvWndHndlr = uint.Parse(recvMsgHndl.Value.ToString()); // Hooked window handler 
            uint recvMsgUint = uint.Parse(recvMsgParam.Value.ToString()); // Message value
            String msgOutput = "Window: " + recvMsgHndl.Value.ToString() + "\r\n";
       
          if (recvWndHndlr == handle) // Our selected window gets a message
           {
                WorkerData wd = lookupMsgs(recvMsgUint);
                WaitCallback wc = new WaitCallback(workerCallback);
                wd.posted = "D: ";
                wd.recvWParam = recvWParam;
                wd.recvLParam = recvLParam;
                wd.recvMsgUint = recvMsgUint;
                wd.stRecvWParam = recvWParam.Value.ToString();
                wd.stRecvLParam = recvLParam.Value.ToString();
                wd.doneEvent = new ManualResetEvent(false);
                doneEvents.Add(wd.doneEvent);
                ThreadPool.QueueUserWorkItem(wc, wd);
            }
        }

        protected void workerCallback(object obj)
        {
            WorkerData wd = (WorkerData)obj;
            {
                try
                {
                    treeView1.Invoke(new AppendHandlerTree(AppendTv), obj);
                }
                catch (Exception e) { Console.WriteLine(e); }
               
                wd.doneEvent.Set();
               }            
        }

        private delegate void AppendHandlerTree(object pp);

        void AppendTv(object pp)
        { 
           WorkerData wd = (WorkerData)pp;
          
           
               treeView1.Nodes.Add(msgNumber + " " +wd.posted + wd.name + " (View XML)");
               msgNumber++;
      
           int lastnode = (treeView1.Nodes.Count - 1);
     
           treeView1.Nodes[lastnode].Nodes.Add("Message ID: " + wd.hex);

            if (wd.wparam != "") // If wparam isn't known place recieved wParam where the name would be
            {
                treeView1.Nodes[lastnode].Nodes.Add(wd.wparam + ": " + wd.stRecvWParam);
                treeView1.Nodes[lastnode].Nodes[1].ToolTipText = wd.wparammiscinfo.ToString();
            }
            else 
            {                
                treeView1.Nodes[lastnode].Nodes.Add("wParam: " + wd.stRecvWParam);
            }
            if (wd.lparam != "") // If lparam isn't known place recieved lParam where the name would be
            {               
                treeView1.Nodes[lastnode].Nodes.Add(wd.lparam + ": " + wd.stRecvLParam);
                treeView1.Nodes[lastnode].Nodes[2].ToolTipText = wd.lparammiscinfo.ToString();
            }
            else
            {                
                treeView1.Nodes[lastnode].Nodes.Add("lParam: " + wd.stRecvLParam);
            }
            if (wd.rtrnval != null) // If there is a return value display it else dont
            {
               
                treeView1.Nodes[lastnode].Nodes.Add("Return Value: " + wd.rtrnval);               
                treeView1.Nodes[lastnode].Nodes[3].ToolTipText = wd.rtrnmisc.ToString();  
            }

            if (wd.name.ToString().IndexOf("not known") != -1) // If the window message isn't in our xml it will return not known
            {
                uint number = uint.Parse(wd.recvMsgUint.ToString());
                string msgValue = "0x" + number.ToString("x");               
                treeView1.Nodes[lastnode].Nodes[0].Nodes.Add(msgValue);              
                treeView1.Nodes[lastnode].Nodes[1].Nodes.Add(wd.stRecvWParam);                
                treeView1.Nodes[lastnode].Nodes[2].Nodes.Add(wd.stRecvLParam);
            }
           

            if (wd.wparamtype.ToString() != "") // If wParam has a type lets parse it
            {
                DeviareParams.IParam lvItemParam = wd.recvWParam.CastTo(wd.wparamtype.ToString());
                if (lvItemParam.IsPointer != 0)
                {
                    lvItemParam = lvItemParam.FullEvaluated;
                }
                DeviareParams.IEnumParams enm2 = lvItemParam.Fields.Enumerator;
                DeviareParams.IParam curParam = enm2.First;
                while (curParam != null)
                {
                    string test = curParam.Type.Name + " " + curParam.Name + " " + curParam.Value.ToString();
                    curParam = enm2.Next;                   
                    treeView1.Nodes[lastnode].Nodes[1].Nodes.Add(test);
                }
            }
            if (wd.lparamtype.ToString() != "") // If lParam has a type lets parse it
            {
                DeviareParams.IParam lvItemParam = wd.recvLParam.CastTo(wd.lparamtype.ToString());
                if (lvItemParam.IsPointer != 0)
                {
                    lvItemParam = lvItemParam.FullEvaluated;
                }
                DeviareParams.IEnumParams enm2 = lvItemParam.Fields.Enumerator;
                DeviareParams.IParam curParam = enm2.First;
                while (curParam != null)
                {
                    string test = curParam.Type.Name + " " + curParam.Name + " " + curParam.Value.ToString();
                    curParam = enm2.Next;                   
                    treeView1.Nodes[lastnode].Nodes[2].Nodes.Add(test);
                }
            }
        }


        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                /*
                 * stop capturing events as soon as the user releases the left mouse button
                 * */
                case (int)Win32.WindowMessages.WM_LBUTTONUP:
                    Show();
                    this.CaptureMouse(false);
                    break;
                case (int)Win32.WindowMessages.WM_RBUTTONDOWN:
                    Show();
                    this.CaptureMouse(false);
                    break;
                /*
                 * handle all the mouse movements
                 * */
                case (int)Win32.WindowMessages.WM_MOUSEMOVE:
                    this.HandleMouseMovements();
                    break;
            };

            base.WndProc(ref m);
        }

        /// <summary>
        /// Processes the mouse down events for the finder tool 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnFinderToolMouseDown(object sender, MouseEventArgs e)
        {
            // Hide the window
            Hide();
            if (e.Button == MouseButtons.Left)
                this.CaptureMouse(true);
           
        }

        /*  public uint GetCaptureWnd()
          {
              return this._wndHandle;
          }
          */
        /// <summary>
        /// Raises the ImageReadyForDisplay event
        /// </summary>
        /// <param name="image"></param>


        /// <summary>
        /// Returns the caption of a window
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        private string GetWindowText(IntPtr hWnd)
        {
            StringBuilder sb = new StringBuilder(256);
            Win32.GetWindowText(hWnd, sb, 256);
            return sb.ToString();
        }

        /// <summary>
        /// Returns the name of a window's class
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        private string GetClassName(IntPtr hWnd)
        {
            StringBuilder sb = new StringBuilder(256);
            Win32.GetClassName(hWnd, sb, 256);
            return sb.ToString();
        }

        /// <summary>
        /// Captures or releases the mouse
        /// </summary>
        /// <param name="captured"></param>
        private void CaptureMouse(bool captured)
        {
            
            // if we're supposed to capture the window
            if (captured)
            {
                // capture the mouse movements and send them to ourself
                Win32.SetCapture(this.Handle);

                // set the mouse cursor to our finder cursor
                Cursor.Current = _cursorFinder;

                // change the image to the finder gone image
                _pictureBox.Image = _finderGone;

                
            }
            // otherwise we're supposed to release the mouse capture
            else
            {
                // so release it
                Win32.ReleaseCapture();

                // put the default cursor back
                Cursor.Current = _cursorDefault;

                // change the image back to the finder at home image
                _pictureBox.Image = _finderHome;

                //show the window
               Show();

                // and finally refresh any window that we were highlighting
                if (_hPreviousWindow != IntPtr.Zero)
                {
                    WindowHighlighter.Refresh(_hPreviousWindow);
                    _hPreviousWindow = IntPtr.Zero;
                }
            }

            // save our capturing state
            _capturing = captured;
        }

        /// <summary>
        /// Handles all mouse move messages sent to the Spy Window
        /// </summary>
        private void HandleMouseMovements()
        {
            // if we're not capturing, then bail out
            if (!_capturing)
                return;

            try
            {
                // capture the window under the cursor's position
                IntPtr hWnd = Win32.WindowFromPoint(Cursor.Position);

                // if the window we're over, is not the same as the one before, and we had one before, refresh it
                if (_hPreviousWindow != IntPtr.Zero && _hPreviousWindow != hWnd)
                    WindowHighlighter.Refresh(_hPreviousWindow);

                // if we didn't find a window.. that's pretty hard to imagine. lol
                if (hWnd == IntPtr.Zero)
                {
                    _txtProc.Text = null;
                    _textBoxHandle.Text = null;
                    _textBoxClass.Text = null;
                    _textBoxText.Text = null;
                    _textBoxRect.Text = null;
                    
                }
                else
                {
                    // save the window we're over
                    _hPreviousWindow = hWnd;

                   

                    // handle
                    _textBoxHandle.Text = string.Format("{0}", hWnd.ToInt32().ToString());


                    // process
                    int _processId = 0;
                   
                    Win32.GetWindowThreadProcessId(hWnd, out _processId);
                    _txtProc.Text = Process.GetProcessById(_processId).MainModule.ModuleName; 

                    // class
                    _textBoxClass.Text = this.GetClassName(hWnd);

                    // caption
                    _textBoxText.Text = this.GetWindowText(hWnd);

                    Win32.Rect rc = new Win32.Rect();
                    Win32.GetWindowRect(hWnd, ref rc);

                    // rect
                    _textBoxRect.Text = string.Format("[{0} x {1}], ({2},{3})-({4},{5})", rc.right - rc.left, rc.bottom - rc.top, rc.left, rc.top, rc.right, rc.bottom);

                    // highlight the window
                    WindowHighlighter.Highlight(hWnd);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
   
        private void _buttonCapture_Click(object sender, EventArgs e)
        {
            {
                try
                {
                    // parse the window handle
                    if (_textBoxHandle.Text.Length != 0)
                    {
                        uint handle = uint.Parse(_textBoxHandle.Text);                     
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            }
        }

        private void _PstMsgBtn_CheckedChanged(object sender, EventArgs e)
        {
            _Pst = true;
            _Dis = false;
        }

        private void _DispatchMsgBtn_CheckedChanged(object sender, EventArgs e)
        {
            _Dis = true;
            _Pst = false;
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            Point pt = Control.MousePosition;
            Point pointInClient = treeView1.PointToClient(pt);
            TreeNode clickedNode = treeView1.GetNodeAt(pointInClient);
           
            
            if (clickedNode != null)
            {
                TreeNode getHexNode = clickedNode.FirstNode;

                if (clickedNode.ToString().IndexOf("Message ID: 0x") != -1) // If Message value node is selected
                {
                    getHexNode = clickedNode;
                }

                if (getHexNode == null) 
                { 
                    // Do nothing
                }
                else if (getHexNode.ToString().IndexOf("Message ID: 0x") != -1) // If the Message Name value is clicked
                    {
                        HexEdit form1 = new HexEdit();
                        int hexcodelength = getHexNode.ToString().Length;                       
                        string hexNodeString = getHexNode.ToString();
                        hexNodeString = hexNodeString.Replace("Message ID: ", "");
                        hexNodeString = hexNodeString.Replace("TreeNode: ", "");                     
                        form1.Show();                   
                        form1.lookupMsgs(hexNodeString);                                            
                }
            }
        }

        private void ClrBtn_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            msgNumber = 1;
        }

    
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
Argentina Argentina
C/C++ developer interested on operating systems, reverse engineering, general system programming, CPU architecture, etc.
Now I'm working creating plugins Outlook Plugin Development.

Comments and Discussions