EasyHook DrawTextW user32.dll 注入,应用程序崩溃

EasyHook DrawTextW user32.dll Injection, Application crashing

我正在使用 EasyHook 也挂钩对 DrawTextW 的调用,在使用记事本进行测试时,如果我打开帮助 -> 关于,它会按预期捕获屏幕上显示的所有文本。但是,如果我打开文件 -> 打开,记事本就会崩溃。我不希望它捕获任何文本,但我不明白为什么记事本会崩溃。任何帮助将不胜感激。

using EasyHook;
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using UI;

namespace MyClassLibrary
{
    public class Main : IEntryPoint
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct HDC__
        {
            public int unused;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct tagRECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [DllImport("user32.dll", EntryPoint = "DrawTextW")]
        public static extern int DrawTextW([In()] IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format);


        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        public delegate int TDrawTextW(
          [In()] IntPtr hdc,
          [MarshalAs(UnmanagedType.LPWStr)]
          StringBuilder lpchText,
          int cchText,
          ref tagRECT lprc,
          uint format);


        static string ChannelName;
        RemoteMon Interface;

        LocalHook DrawTextWHook;
        public Main(RemoteHooking.IContext InContext, String InChannelName)
        {
            try
            {
                Interface = RemoteHooking.IpcConnectClient<RemoteMon>(InChannelName);
                ChannelName = InChannelName;
                Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());
            }
            catch (Exception ex)
            {
                Interface.ErrorHandler(ex);
            }
        }

        static int hkDrawTextW(
                  [In()] IntPtr hdc,
                  [MarshalAs(UnmanagedType.LPWStr)]
                  StringBuilder lpchText,
                  int cchText,
                  ref tagRECT lprc,
                  uint format)
        {
            try
            {
                ((Main)HookRuntimeInfo.Callback).Interface.GotDrawTextW(lpchText);
                return DrawTextW(hdc, lpchText, cchText, ref lprc, format);
            }
            catch (Exception ex)
            {
                ((Main)HookRuntimeInfo.Callback).Interface.ErrorHandler(ex);
                return 0;
            }
        }

        public void Run(RemoteHooking.IContext InContext, String InChannelName)
        {
            try
            {
                DrawTextWHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "DrawTextW"),
                                                new TDrawTextW(hkDrawTextW), this);
                DrawTextWHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
            }
            catch (Exception ex)
            {
                Interface.ErrorHandler(ex);
            }
            try
            {
                RemoteHooking.WakeUpProcess();
            }
            catch (Exception ex)
            {
                Interface.ErrorHandler(ex);
            }
            while (true)
            {
                Thread.Sleep(10000);
            }
        }
    }
}

当“打开”对话框显示时,将文本编组到 StringBuilder 时出现问题。我不是 100% 确定原因,但也许是 COM 初始化字符串和使用 malloc 初始化的字符串之间的区别?我过去曾遇到过字符串编组问题,具体取决于它们的底层内存是如何初始化的。

解决方案是对文本参数使用 String 而不是 StringBuilder。用字符串参数替换extern和delegate等合适的地方:

    [DllImport("user32.dll", EntryPoint = "DrawTextW")]
    public static extern int DrawTextW([In()] IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] String lpchText, int cchText, ref tagRECT lprc, uint format);

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
    public delegate int TDrawTextW(
      [In()] IntPtr hdc,
      [MarshalAs(UnmanagedType.LPWStr)]
      String lpchText,
      int cchText,
      ref tagRECT lprc,
      uint format);

    static int hkDrawTextW(
              [In()] IntPtr hdc,
              [MarshalAs(UnmanagedType.LPWStr)]
              String lpchText,
              int cchText,
              ref tagRECT lprc,
              uint format)
    {
      ...
    }