c# - 如何让 EasyHook 工作?

标签 c# easyhook

我正在尝试了解 easyhook 如何为即将到来的项目工作。为此,我决定尝试劫持 firefox.exe 进程中的 GetMonitorInfoW 和 GetDeviceCaps 以获取 window.screen.width 和 height 以返回疯狂的值。

这是我做的:

injectorHelperLib.dll:

public class GetDisplayParamsInterface : MarshalByRefObject
{
    // Methods
    public void IsInstalled(int InClientPID)
    {
        Console.WriteLine("Display params injector has been installed in target {0}.\r\n", InClientPID);
    }

    public void Ping()
    {
    }        
}

注入(inject)器库.dll:

/// <summary>
/// based on interception of calls in nsScreenWin.cpp
/// </summary>
public class InjectorClass : IEntryPoint
{
    #region relevant functions
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left, Top, Right, Bottom;

        public RECT(int left, int top, int right, int bottom)
        {
            Left = left;
            Top = top;
            Right = right;
            Bottom = bottom;
        }

        public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }

        public int X
        {
            get { return Left; }
            set { Right -= (Left - value); Left = value; }
        }

        public int Y
        {
            get { return Top; }
            set { Bottom -= (Top - value); Top = value; }
        }

        public int Height
        {
            get { return Bottom - Top; }
            set { Bottom = value + Top; }
        }

        public int Width
        {
            get { return Right - Left; }
            set { Right = value + Left; }
        }

        public System.Drawing.Point Location
        {
            get { return new System.Drawing.Point(Left, Top); }
            set { X = value.X; Y = value.Y; }
        }

        public System.Drawing.Size Size
        {
            get { return new System.Drawing.Size(Width, Height); }
            set { Width = value.Width; Height = value.Height; }
        }

        public static implicit operator System.Drawing.Rectangle(RECT r)
        {
            return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
        }

        public static implicit operator RECT(System.Drawing.Rectangle r)
        {
            return new RECT(r);
        }

        public static bool operator ==(RECT r1, RECT r2)
        {
            return r1.Equals(r2);
        }

        public static bool operator !=(RECT r1, RECT r2)
        {
            return !r1.Equals(r2);
        }

        public bool Equals(RECT r)
        {
            return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
        }

        public override bool Equals(object obj)
        {
            if (obj is RECT)
                return Equals((RECT)obj);
            else if (obj is System.Drawing.Rectangle)
                return Equals(new RECT((System.Drawing.Rectangle)obj));
            return false;
        }

        public override int GetHashCode()
        {
            return ((System.Drawing.Rectangle)this).GetHashCode();
        }

        public override string ToString()
        {
            return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class MONITORINFO
    {
        public int cbSize;
        public RECT rcMonitor;
        public RECT rcWork;
        public uint dwFlags;
    }

    [DllImport("user32.dll")]
    static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);

    [UnmanagedFunctionPointer(CallingConvention.StdCall,
        CharSet = CharSet.Unicode,
        SetLastError = true)]
    private delegate bool DGetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);

    bool GetMonitorInfo_Hook(IntPtr hMonitor, ref MONITORINFO lpmi)
    {
        var r=GetMonitorInfo(hMonitor, ref lpmi);

        //doctor the data
        lpmi.rcMonitor.Right = lpmi.rcMonitor.Left + displaySize.Width;
        lpmi.rcMonitor.Bottom = lpmi.rcMonitor.Top + displaySize.Height;

        lpmi.rcWork.Right = lpmi.rcWork.Left + workAreaSize.Width;
        lpmi.rcWork.Bottom = lpmi.rcWork.Top + workAreaSize.Height;

        //let's consider the call successfull
        return true;
    }



    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

    [UnmanagedFunctionPointer(CallingConvention.StdCall,
        CharSet = CharSet.Unicode,
        SetLastError = true)]
    delegate int DGetDeviceCaps(IntPtr hdc, int nIndex);

    int GetDeviceCaps_Hook(IntPtr hdc, int nIndex)
    {
        if (nIndex==(int)DeviceCap.BITSPIXEL)
        {
            return PixelDepth;
        }
        if (nIndex==(int)DeviceCap.HORZRES)
        {
            return displaySize.Width;
        }
        if(nIndex==(int)DeviceCap.VERTRES)
        {
            return displaySize.Height;
        }

        return GetDeviceCaps(hdc, nIndex);
    }

    enum DeviceCap
    {
        /// <summary>
        /// Device driver version
        /// </summary>
        DRIVERVERSION = 0,
        /// <summary>
        /// Device classification
        /// </summary>
        TECHNOLOGY = 2,
        /// <summary>
        /// Horizontal size in millimeters
        /// </summary>
        HORZSIZE = 4,
        /// <summary>
        /// Vertical size in millimeters
        /// </summary>
        VERTSIZE = 6,
        /// <summary>
        /// Horizontal width in pixels
        /// </summary>
        HORZRES = 8,
        /// <summary>
        /// Vertical height in pixels
        /// </summary>
        VERTRES = 10,
        /// <summary>
        /// Number of bits per pixel
        /// </summary>
        BITSPIXEL = 12,
        /// <summary>
        /// Number of planes
        /// </summary>
        PLANES = 14,
        /// <summary>
        /// Number of brushes the device has
        /// </summary>
        NUMBRUSHES = 16,
        /// <summary>
        /// Number of pens the device has
        /// </summary>
        NUMPENS = 18,
        /// <summary>
        /// Number of markers the device has
        /// </summary>
        NUMMARKERS = 20,
        /// <summary>
        /// Number of fonts the device has
        /// </summary>
        NUMFONTS = 22,
        /// <summary>
        /// Number of colors the device supports
        /// </summary>
        NUMCOLORS = 24,
        /// <summary>
        /// Size required for device descriptor
        /// </summary>
        PDEVICESIZE = 26,
        /// <summary>
        /// Curve capabilities
        /// </summary>
        CURVECAPS = 28,
        /// <summary>
        /// Line capabilities
        /// </summary>
        LINECAPS = 30,
        /// <summary>
        /// Polygonal capabilities
        /// </summary>
        POLYGONALCAPS = 32,
        /// <summary>
        /// Text capabilities
        /// </summary>
        TEXTCAPS = 34,
        /// <summary>
        /// Clipping capabilities
        /// </summary>
        CLIPCAPS = 36,
        /// <summary>
        /// Bitblt capabilities
        /// </summary>
        RASTERCAPS = 38,
        /// <summary>
        /// Length of the X leg
        /// </summary>
        ASPECTX = 40,
        /// <summary>
        /// Length of the Y leg
        /// </summary>
        ASPECTY = 42,
        /// <summary>
        /// Length of the hypotenuse
        /// </summary>
        ASPECTXY = 44,
        /// <summary>
        /// Shading and Blending caps
        /// </summary>
        SHADEBLENDCAPS = 45,

        /// <summary>
        /// Logical pixels inch in X
        /// </summary>
        LOGPIXELSX = 88,
        /// <summary>
        /// Logical pixels inch in Y
        /// </summary>
        LOGPIXELSY = 90,

        /// <summary>
        /// Number of entries in physical palette
        /// </summary>
        SIZEPALETTE = 104,
        /// <summary>
        /// Number of reserved entries in palette
        /// </summary>
        NUMRESERVED = 106,
        /// <summary>
        /// Actual color resolution
        /// </summary>
        COLORRES = 108,

        // Printing related DeviceCaps. These replace the appropriate Escapes
        /// <summary>
        /// Physical Width in device units
        /// </summary>
        PHYSICALWIDTH = 110,
        /// <summary>
        /// Physical Height in device units
        /// </summary>
        PHYSICALHEIGHT = 111,
        /// <summary>
        /// Physical Printable Area x margin
        /// </summary>
        PHYSICALOFFSETX = 112,
        /// <summary>
        /// Physical Printable Area y margin
        /// </summary>
        PHYSICALOFFSETY = 113,
        /// <summary>
        /// Scaling factor x
        /// </summary>
        SCALINGFACTORX = 114,
        /// <summary>
        /// Scaling factor y
        /// </summary>
        SCALINGFACTORY = 115,

        /// <summary>
        /// Current vertical refresh rate of the display device (for displays only) in Hz
        /// </summary>
        VREFRESH = 116,
        /// <summary>
        /// Horizontal width of entire desktop in pixels
        /// </summary>
        DESKTOPVERTRES = 117,
        /// <summary>
        /// Vertical height of entire desktop in pixels
        /// </summary>
        DESKTOPHORZRES = 118,
        /// <summary>
        /// Preferred blt alignment
        /// </summary>
        BLTALIGNMENT = 119
    }

    private static Size displaySize = new Size(666, 766);
    private static Size workAreaSize = new Size(777, 877);
    private int pixelDepth = 666;

    public static Size DisplaySize
    {
        get { return displaySize; }
        set { displaySize = value; }
    }

    public static Size WorkAreaSize
    {
        get { return workAreaSize; }
        set { workAreaSize = value; }
    }

    public int PixelDepth
    {
        get { return pixelDepth; }
        set { pixelDepth = value; }
    }

    #endregion

    GetDisplayParamsInterface Interface;
    private LocalHook getMonitorInfoHook,getDeviceCapsHook;

        // Methods
    public InjectorClass(RemoteHooking.IContext InContext, string InChannelName)
    {
        this.Interface = RemoteHooking.IpcConnectClient<GetDisplayParamsInterface>(InChannelName);
        this.Interface.Ping();
    }

    public void Run(RemoteHooking.IContext InContext, string InChannelName)
    {
        try
        {
            this.getMonitorInfoHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "GetMonitorInfoW"), new DGetMonitorInfo(GetMonitorInfo_Hook), this);
            this.getDeviceCapsHook = LocalHook.Create(LocalHook.GetProcAddress("gdi32.dll", "GetDeviceCaps"), new DGetDeviceCaps(GetDeviceCaps_Hook), this);
            this.getMonitorInfoHook.ThreadACL.SetExclusiveACL(new int[1]);
        }
        catch (Exception exception)
        {
            this.Interface.ReportException(exception);
            return;
        }
        this.Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());
        RemoteHooking.WakeUpProcess();
        try
        {
            while (true)
            {
                Thread.Sleep(500);

                this.Interface.Ping();
            }
        }
        catch
        {
        }
    }
}

文本.exe:

    static void Main(string[] args)
    {
        int pid = 15332;
        try
        {                
            RemoteHooking.IpcCreateServer<GetDisplayParamsInterface>(ref ChannelName, WellKnownObjectMode.SingleCall, new WellKnownSidType[0]);
            RemoteHooking.Inject(pid, "injectorLib.dll", "injectorLib.dll", new object[] { ChannelName });
            Console.ReadLine();
        }
        catch (Exception exception)
        {
            Console.WriteLine("There was an error while connecting to target:\r\n{0}", exception.ToString());
        }
}

应用程序似乎启动并报告附加到进程,但对 window.screen.width 或我想影响的任何其他变量没有影响。

我做错了什么?

最佳答案

您只将线程 ACL 应用于您的一个 Hook 。我不确定这是否是您遇到问题的原因,但使用该代码,您的 getDeviceCapsHook 将不会执行。

this.getDeviceCapsHook.ThreadACL.SetExclusiveACL(new int[1]);

关于c# - 如何让 EasyHook 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17026432/

相关文章:

c# - EasyHook 给定的 32 位库不存在,用户库没有导出正确的运行

c# - 如何使用 C# 拦截 Win32 API 调用?

c# - 使 ListView 在垂直方向上可滚动

c# - 遍历目录直到我在 C# 中找到某个文件

c# - 无法使用 Entity Framework Web API VS 2013 Express for Web 添加 Controller

c# - 如何找到未关闭的DataReader?

c# EasyHook,窗口标题改变

c# - Easyhook 在 vs2010 上引发 "Unable to install assembly in the GAC"错误

c# - 无法为链接服务器 "Microsoft.Jet.OLEDB.4.0"初始化 OLE DB 提供程序 "(null)"的数据源对象