Problem in ExtTextOut hooking with EasyHook

Aug 16, 2011 at 5:57 AM

Hi
 
I wanted to hooking ExtTextOut with easyhook

everything is ok and I don't have any error but
the problem is this:
 
I opened a notepad 
then I ran my project
but
when I clicked on the notepad
it came to close !!! I don't know why!!!!
 
Please help me
 
Filemon program.cs :
 

using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Text;
using System.IO;
using System.Diagnostics;
using EasyHook;
 
namespace FileMon
{
    public class FileMonInterface : MarshalByRefObject
    {
        public void IsInstalled(Int32 InClientPID)
        {
            Console.WriteLine("FileMon has been installed in target
{0}.\r\n", InClientPID);
        }
 
        public void OnCreatFile(Int32 InClientPID, String[] InFileNames)
        {
            for (int i = 0; i < InFileNames.Length; i++)
            {
                Console.WriteLine(InFileNames[i]);
            }
        }
 
        public void ReportException(Exception InInfo)
        {
            Console.WriteLine("The target process has reported an
error:\r\n" + InInfo.ToString());
        }
 
        public void Ping()
        {
        }
    }
 
    class Program
    {
        static String ChannelName = null;
 
        static void Main(string[] args)
        {
            Int32 TargetPID = 0;
 
            if ((args.Length != 1) || !Int32.TryParse(args[0], out
TargetPID))
            {
                Console.WriteLine();
                Console.WriteLine("Usage: FileMon %PID%");
                Console.WriteLine();
 
              // return;
            }
 
            try
            {
                Config.Register(
                    "A FileMon like demo application.",
                    "FileMon.exe",
                    "FileMonInject.dll");
 
                RemoteHooking.IpcCreateServer<FileMonInterface>(ref
ChannelName, WellKnownObjectMode.SingleCall);
 
                Process[] ProcList = Process.GetProcesses();
                String FileName;
                Int32 Id;
                for (int i = 0; i < ProcList.Length; i++)
                {
                    Process Proc = ProcList[i];
                    FileName = Proc.ProcessName;
                    Id = Proc.Id;
                    if (FileName == "notepad")
                        TargetPID = Id;
                }
 
                RemoteHooking.Inject(
                    TargetPID,
                    "FileMonInject.dll",
                    "FileMonInject.dll",
                    ChannelName);
                
                Console.ReadLine();
            }
            catch (Exception ExtInfo)
            {
                Console.WriteLine("There was an error while connecting to
target:\r\n{0}", ExtInfo.ToString());
                Console.ReadLine();
            }
        }
    }
}

 
FileMonInject Main.cs
 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using EasyHook;
 
namespace FileMonInject
{
    public class Main : EasyHook.IEntryPoint
    {
        FileMon.FileMonInterface Interface;
        LocalHook ExtTextOutHook;
        Stack<String> Queue = new Stack<String>();
 
        public Main(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // connect to host...
            Interface =
RemoteHooking.IpcConnectClient<FileMon.FileMonInterface>(InChannelName);
 
            Interface.Ping();
        }
 
        public void Run(
            RemoteHooking.IContext InContext,
            String InChannelName)
        {
            // install hook...
            try
            {
 
                ExtTextOutHook = LocalHook.Create(
                    LocalHook.GetProcAddress("gdi32.dll", "ExtTextOutW"),
                    new DExtTextOut(ExtTextOut_Hooked), this);
 
                ExtTextOutHook.ThreadACL.SetExclusiveACL(new Int32[] { 0
});
            }
            catch (Exception ExtInfo)
            {
                Interface.ReportException(ExtInfo);
 
                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 = null;
 
                        lock (Queue)
                        {
                            Package = Queue.ToArray();
 
                            Queue.Clear();
                        }
 
                      
Interface.OnCreatFile(RemoteHooking.GetCurrentProcessId(), Package);
                    }
                    else
                        Interface.Ping();
                }
            }
            catch
            {
                // Ping() will raise an exception if host is unreachable
            }
        }
 
        [Serializable, StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
 
            public RECT(int left_, int top_, int right_, int bottom_)
            {
                Left = left_;
                Top = top_;
                Right = right_;
                Bottom = bottom_;
            }
 
            public int Height { get { return Bottom - Top; } }
            public int Width { get { return Right - Left; } }
 
        }
      /* [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            private int _Left;
            private int _Top;
            private int _Right;
            private int _Bottom;
        }*/
 

 
        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode,
            SetLastError = true)]
        delegate bool DExtTextOut(
            IntPtr hdc,
            int X,
            int Y,
            uint fuOptions,
            [In] ref RECT lprc,
            [MarshalAs(UnmanagedType.LPWStr)] string lpString,
            uint cbCount,
            [In] IntPtr lpDx); 
            /*IntPtr DCreateFile
            (String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);*/
 
        // just use a P-Invoke implementation to get native API access
from C# (this step is not necessary for C++.NET)
        [DllImport("gdi32.dll",
            CharSet = CharSet.Unicode,
            SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern bool ExtTextOut(
            IntPtr hdc,                                        
            int X,                                        
            int Y,                                        
            uint fuOptions,                                        
            [In] ref RECT lprc,
            [MarshalAs(UnmanagedType.LPWStr)] string lpString,            
                          
            uint cbCount,                                        
            [In] IntPtr lpDx); 
          /*IntPtr CreateFile String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile);*/
 
        // this is where we are intercepting all file accesses!
        static bool ExtTextOut_Hooked(
            IntPtr hdc,            
            int X,            
            int Y,            
            uint fuOptions,            
            [In] ref RECT lprc,
            [MarshalAs(UnmanagedType.LPWStr)] string lpString,            
 
            uint cbCount,            
            [In] IntPtr lpDx) 
            /*IntPtr CreateFile_Hooked(
            String InFileName,
            UInt32 InDesiredAccess,
            UInt32 InShareMode,
            IntPtr InSecurityAttributes,
            UInt32 InCreationDisposition,
            UInt32 InFlagsAndAttributes,
            IntPtr InTemplateFile)*/
        {
            
            try
            {
                Main This = (Main)HookRuntimeInfo.Callback;
 
                lock (This.Queue)
                {
                  
                //if (lpString == "File")
                //    lpString = "hello";
                  //This.Queue.Push(lpString);
                    This.Queue.Push("[" +
RemoteHooking.GetCurrentProcessId() + ":" +
                      RemoteHooking.GetCurrentThreadId() + "]: \"" +
lpString + "\"");
                  
                }
            }
            catch
            {
                Console.WriteLine("OOoops");
            }
 
            // call original API...
            return ExtTextOut(
                hdc,                  
                X,                  
                Y,                  
                fuOptions,                  
                ref lprc,                  
                lpString,                  
                cbCount,                  
                lpDx); 
                /*InFileName,
                InDesiredAccess,
                InShareMode,
                InSecurityAttributes,
                InCreationDisposition,
                InFlagsAndAttributes,
                InTemplateFile);*/
        }
    }
}

 
I opened a notepad
then I ran my project
I saw this in command window:
 
Usage: FileMon %PID%
FileMon has been installed in target 14896.
 

and when i clicked on notepad , it came closed
 
and I see this in command window:
 
[14896:16960]: ""

Sep 1, 2011 at 8:22 AM
Edited Sep 1, 2011 at 8:23 AM
static extern bool ExtTextOut(
            IntPtr hdc,                                        
            int X,                                        
            int Y,                                        
            uint fuOptions,                                        
            [In] ref RECT lprc,
            [MarshalAs(UnmanagedType.LPWStr)] string lpString,    


needs to be:

static extern bool ExtTextOutW(
            IntPtr hdc,                                        
            int X,                                        
            int Y,                                        
            uint fuOptions,                                        
            [In] ref RECT lprc,
            string lpString,

You forgot the W at the end