DrawText and lpRect

Aug 22, 2010 at 9:23 PM

I have set up EasyHook to hook DrawText successfully and am having no trouble snooping the text output and sending it to my application.

Ideally, I would like to know the coordinates of where these items are destined to be printed.  Granted, I'm not very good at debugging the injection DLL so I'm looking for suggestions on better debugging techniques and also possibly better ways to look up the coordinates.

I'm not 100% sure how lpRect works.  Does it provide the rectangle for the string being passed in?  Or does it provide the rectangle for the entire box in which the text is to be formatted (say a listView, for example).

I used the ProcMon example as a frame to get my DrawText hook working.... this is my run function:

  public void Run(RemoteHooking.IContext InContext, String InArg1)
        {
            try
            {
            
                DrawTextHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "DrawTextW"), new DDrawText(DrawText_Hooked), this);

                /*
                 * Don't forget that all hooks will start deaktivated...
                 * The following ensures that all threads are intercepted:
                 */
                DrawTextHook.ThreadACL.SetExclusiveACL(new Int32[1]);
            }
            catch (Exception e)
            {
                /*S
                    Now we should notice our host process about this error...
                 */
                Interface.ReportError(RemoteHooking.GetCurrentProcessId(), e);

                return;
            }


            // wait for host process termination...
            try
            {
                while (Interface.Ping(RemoteHooking.GetCurrentProcessId()))
                {
                    Thread.Sleep(2000);

                   

                    // transmit newly monitored file accesses...
                    lock (Queue)
                    {
                  
                            if (Queue.Count > 0)
                            {
                                String[] Package = null;
                           
                                Package = Queue.ToArray();
                      
                                Queue.Clear();
                         
                                Interface.OnDrawText(RemoteHooking.GetCurrentProcessId(), Package);
                                                             
                            }
                                                                              
                    }
                }//while
            }
            catch
            {
                // NET Remoting will raise an exception if host is unreachable
            }
        }

 

 

 

I've even tried declaring a local variable int i = 0, and then replacing  Interface.OnDrawText(RemoteHooking.GetCurrentProcessId(), Package); with

Interface.OnDrawText(RemoteHooking.GetCurrentProcessId(), Package, i); and of course changing the subsequent OnDrawText(Int32 PID, String[] string)  function in my application's code to OnDrawText(Int32 PID, String[] string, int i).  This makes my text hooking cease to work.

Basically I want to see the output of lpRect but do not know how to do this without creating local variables.  I think I get what's going on in the example code, since the String class can dynamically allocate, do I need to make some functions for RECT that can do the same?  But at least, I'd like to start with passing a local variable through the Interface.

 

Thanks in advance!

 

Aug 22, 2010 at 9:33 PM

A few things...

 

I realize that String[] string is not valid since string is a type... my code obviously isn't written like that.

 

Secondly, this was helpful http://easyhook.codeplex.com/Thread/View.aspx?ThreadId=45691

But I still have some questions.  What needs to be Marshaled here?  Take my simple example where I want to declare a local integer variable "i", set it to a value, and pass it back to the application pointed to by the Interface via the OnDrawText function... what would that call look like?  And what if I wanted to make a Queue for the lpRects, would I need to Marshal those as well?

I am extremely green on the idea of marshaling, although I get it's function on a high level, I've never used it in implementation.

 

Thanks!

 

 

Aug 23, 2010 at 12:47 AM

I'm really confused by your explanation/questions/...

Your 'interface class' inherits from http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx, you can find some more information about the marshaling there.