0

My ultimate goal with hooking is to read news headlines being received by an external application, and process those headlines in my application.

To get started, I've been trying to access text written to a simple console app that I wrote, which outputs "We're on number xxx" repeatedly every five seconds, with xxx incrementing.

Taken from this example, I used the following code, and the associated pointer telling me something has changed. However, I'm interested in the actual text written, and when I try to access it using Marshal.ReadIntPtr(hwnd), I get a System.AccessViolationException: Attempted to read or write protected memory...

Here's the code, explanations or help would be next to godliness right now:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace testsAndSamples_hookingWinEvents
{
    class Program
    {
        delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
            IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

        [DllImport("user32.dll")]
        static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
           hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
           uint idThread, uint dwFlags);

        [DllImport("user32.dll")]
        static extern bool UnhookWinEvent(IntPtr hWinEventHook);

        const uint EVENT_OBJECT_NAMECHANGE = 0x800C;
        const uint WINEVENT_OUTOFCONTEXT = 0;

        // Need to ensure delegate is not collected while we're using it,
        // storing it in a class field is simplest way to do this.
        static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);

        public static void Main()
        {
            // Listen for name change changes across all processes/threads on current desktop...
            IntPtr hhook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, IntPtr.Zero,
                    procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);

            // MessageBox provides the necessary mesage loop that SetWinEventHook requires.
            // In real-world code, use a regular message loop (GetMessage/TranslateMessage/
            // DispatchMessage etc or equivalent.)
            MessageBox.Show("hooked");

            UnhookWinEvent(hhook);
        }

        static void WinEventProc(IntPtr hWinEventHook, uint eventType,
            IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
        {
            // filter out non-HWND namechanges... (eg. items within a listbox)
            if (idObject != 0 || idChild != 0)
            {
                return;
            }
            // this doesn't work:
            var hey = Marshal.ReadIntPtr(hwnd);

            Console.WriteLine("Text of hwnd changed {0:x8}", hwnd.ToInt32());
        }
    }

}
  • The HWND is an opaque pointer, i.e. you do not read the memory location directly, but using the appropriate Win32 API methods. If you comment out Marshal.ReadIntPtr(hwnd) do you see a non-zero value output to the Console for "Text of hwnd changed..."? – Justin Stenning Jul 12 '17 at 03:19
  • Yes I do. I believe it's hexadecimal, denoted (number)x(more numbers) – Nick Fisher Jul 12 '17 at 23:35
  • 1
    ok so the exception is because you are trying to read the pointer location. You will instead need to look at other win API methods that may tell you what you want to know about that window handle. – Justin Stenning Jul 12 '17 at 23:37
  • Any suggestions on where to look? – Nick Fisher Jul 12 '17 at 23:48
  • perhaps look at winspy or API monitor to investigate what contains the text etc. don't know enough about the app you are investigating. You might need to explore other options such as API hooking (e.g. Intercept a draw text command or similar - API monitor should help narrow down the options). – Justin Stenning Jul 12 '17 at 23:51
  • I've been banging my head against the wall trying exactly what you're talking about lol. I'm inexperienced at c++, and all the attempts I've made at API hooking for this application have been futile. Thanks for the pointers – Nick Fisher Jul 13 '17 at 21:37

0 Answers0