首页
社区
课程
招聘
1
解决WPF使用HVNC的问题-HwndHook
发表于: 2024-12-15 18:43 6735

解决WPF使用HVNC的问题-HwndHook

2024-12-15 18:43
6735

这里就不多介绍HVNC了 因为单纯在之前的文章已经介绍过了
https://bbs.kanxue.com/thread-264956.htm

那么我们都知道 CPP中HVNC有现成的代码(github TinyNuke)可以直接抄
https://github.com/Sts0mrg0/TinyNuke

C#中也有比如
https://github.com/moom825/xeno-rat
核心代码在

他创建了一个控件来解决这个问题
其实WPF中也可以用类似的创建控件的方法来解决
但是我们这里给出第二个方案

什么是HwndHook
HwndHook 是一个委托(Delegate),在 WPF (Windows Presentation Foundation) 中用于处理 Win32 消息。它定义了 HwndSourceHook 方法的签名,该方法可以被用来拦截和处理发送到 WPF 窗口的消息。HwndHook 委托允许开发者在 WPF 应用程序中自定义和扩展对 Win32 消息的处理

在 WPF 中,HwndSource 类代表一个 Win32 窗口句柄(HWND),并且提供了一个方法 AddHook,允许你将一个 HwndSourceHook 委托(即 HwndHook)添加到窗口消息队列中。这个委托会在每个 Win32 消息被分派到相应的 WPF 窗口之前被调用,从而允许开发者在消息到达目标窗口之前对其进行拦截和处理

结构如下

HwndHook有什么用

拦截消息:在消息到达目标控件之前拦截它。
自定义消息处理:根据需要自定义消息的处理逻辑。
修改消息参数:在消息被处理之前修改 wParam 和 lParam 参数。
阻止消息传播:通过设置 handled 参数为 true 来阻止消息继续传播到默认的窗口过程。

为什么使用HwndHook
在C# WPF中,使用HwndHook(通过HwndSource.AddHook方法)来将消息转化为Window消息,是因为WPF框架本身并不直接处理Win32消息,而是通过一个叫做HwndSource的类来与Win32 API进行交互。
HwndSource提供了一个桥梁,使得WPF应用程序能够接收和处理Win32消息
另外他还可以免除自写控件的痛苦等等 总而言之就是节省了时间

如何使用HwndHook
这里只说对单个控件的HwndHook 因为全窗口的HwndHook网上教程还是比较多的
首先定义HwndSource

接下来写HOOK主体

接下来就是在Loaded写加载HwndHook的函数

这里有个小坑需要注意一下
一般来说 有人喜欢在InitializeComponent();后直接就下HwndHook
这是不可行的
因为如果这样PresentationSource.FromVisual找不到对象
所以你要先等他Loaded
也就是

本文仅供技术学习交流

public class CustomPictureBox : PictureBox
   {
       Node client;
       public CustomPictureBox(Node _client)
       {
           client = _client;
       }
 
       [DllImport("user32.dll")]
       public static extern short GetKeyState(int nVirtKey);
 
       // Constants for clipboard data formats
       public const uint CF_TEXT = 1;          // Text format
       public const uint CF_BITMAP = 2;        // Bitmap format
       public const uint CF_UNICODETEXT = 13;   // Unicode text format
       public const uint CF_HDROP = 15;         // File format
 
       // Import the necessary WinAPI functions
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool IsClipboardFormatAvailable(uint format);
 
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool OpenClipboard(IntPtr hWndNewOwner);
 
       [DllImport("user32.dll")]
       public static extern IntPtr GetClipboardData(uint uFormat);
 
 
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool CloseClipboard();
 
       [DllImport("user32.dll")]
       static extern short VkKeyScan(char c);
 
       [DllImport("user32.dll")]
       public static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out uint lpChar, uint uFlags);
       public Point TranslateCoordinates(Point originalCoords, Size originalScreenSize, PictureBox targetControl)
       {
           // Calculate the scaling factors
           float scaleX = (float)targetControl.Image.Width / originalScreenSize.Width;
           float scaleY = (float)targetControl.Image.Height / originalScreenSize.Height;
 
           // Apply the scaling factors
           int scaledX = (int)(originalCoords.X * scaleX);
           int scaledY = (int)(originalCoords.Y * scaleY);
 
           // Get the unzoomed and offset-adjusted coordinates
           Point translatedCoords = UnzoomedAndAdjusted(targetControl, new Point(scaledX, scaledY));
 
           return translatedCoords;
       }
       public static void GetClipboardFormat()
       {
           if (!OpenClipboard(IntPtr.Zero))
               return;
 
 
           if (IsClipboardFormatAvailable(CF_TEXT))
           {
               IntPtr hGlobal = GetClipboardData(CF_TEXT);
               string clipboardText = Marshal.PtrToStringUni(hGlobal);
               Marshal.FreeHGlobal(hGlobal);
           }
           else if (IsClipboardFormatAvailable(CF_BITMAP))
           {
               IntPtr hBitmap = GetClipboardData(CF_BITMAP);
               System.Drawing.Bitmap clipboardBitmap = System.Drawing.Bitmap.FromHbitmap(hBitmap);
               Marshal.FreeHGlobal(hBitmap);
           }
           else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
           {
               IntPtr hGlobal = GetClipboardData(CF_UNICODETEXT);
               string clipboardText = Marshal.PtrToStringUni(hGlobal);
               Marshal.FreeHGlobal(hGlobal);
           }
 
           CloseClipboard();
       }
       private Point UnzoomedAndAdjusted(PictureBox pictureBox, Point scaledPoint)
       {
           // Calculate the zoom factor
           float zoomFactor = Math.Min(
               (float)pictureBox.ClientSize.Width / pictureBox.Image.Width,
               (float)pictureBox.ClientSize.Height / pictureBox.Image.Height);
 
           // Get the displayed rectangle of the image
           Rectangle displayedRect = GetImageDisplayRectangle(pictureBox);
 
           // Offset and unzoom the coordinates
           int translatedX = (int)((scaledPoint.X - displayedRect.X) / zoomFactor);
           int translatedY = (int)((scaledPoint.Y - displayedRect.Y) / zoomFactor);
 
           return new Point(translatedX, translatedY);
       }
 
       private Rectangle GetImageDisplayRectangle(PictureBox pictureBox)
       {
           if (pictureBox.SizeMode == PictureBoxSizeMode.Normal)
           {
               return new Rectangle(0, 0, pictureBox.Image.Width, pictureBox.Image.Height);
           }
           else if (pictureBox.SizeMode == PictureBoxSizeMode.StretchImage)
           {
               return pictureBox.ClientRectangle;
           }
           else
           {
               float zoomFactor = Math.Min(
                   (float)pictureBox.ClientSize.Width / pictureBox.Image.Width,
                   (float)pictureBox.ClientSize.Height / pictureBox.Image.Height);
 
               int imageWidth = (int)(pictureBox.Image.Width * zoomFactor);
               int imageHeight = (int)(pictureBox.Image.Height * zoomFactor);
 
               int imageX = (pictureBox.ClientSize.Width - imageWidth) / 2;
               int imageY = (pictureBox.ClientSize.Height - imageHeight) / 2;
 
               return new Rectangle(imageX, imageY, imageWidth, imageHeight);
           }
       }
       public static char GetModifiedKey(char c)
       {
           short vkKeyScanResult = VkKeyScan(c);
 
           // a result of -1 indicates no key translates to input character
           if (vkKeyScanResult == -1)
               return c;
 
           // vkKeyScanResult & 0xff is the base key, without any modifiers
           uint code = (uint)vkKeyScanResult & 0xff;
           // set shift key pressed
           byte[] b = new byte[256];
           b[0x10] = 0x80;
 
           uint r;
           // return value of 1 expected (1 character copied to r)
           if (1 != ToAscii(code, code, b, out r, 0))
               return c;
 
           return (char)r;
       }
 
       public static bool IsAlphaNumeric(char c)
       {
           return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '1' && c <= '9');
       }
       public void TriggerWndProc(ref Message m)
       {
           WndProc(ref m);
       }
 
       protected override void WndProc(ref Message m)
       {
           if (this.Image == null)
           {
               base.WndProc(ref m);
               return;
           }
           byte[] payload;
           switch (m.Msg)
           {
               case 0x0201: // WM_LBUTTONDOWN
               case 0x0202: // WM_LBUTTONUP
               case 0x0204: // WM_RBUTTONDOWN
               case 0x0205: // WM_RBUTTONUP
               case 0x0207: // WM_MBUTTONDOWN
               case 0x0208: // WM_MBUTTONUP
               case 0x0203: // WM_LBUTTONDBLCLK
               case 0x0206: // WM_RBUTTONDBLCLK
               case 0x0209: // WM_MBUTTONDBLCLK
               case 0x0200: // WM_MOUSEMOVE
               case 0x020A: // WM_MOUSEWHEEL
                   int x = (int)(m.LParam.ToInt32() & 0xFFFF);
                   int y = (int)((m.LParam.ToInt32() >> 16) & 0xFFFF);
                   Point newpoint = TranslateCoordinates(new Point(x, y), this.Image.Size, this);
                   x = newpoint.X;
                   y = newpoint.Y;
 
                   m.LParam = (IntPtr)((y << 16) | (x & 0xFFFF));
 
                   uint msg = (uint)m.Msg;
                   IntPtr wParam = m.WParam;
                   IntPtr lParam = m.LParam;
                   int Imsg = (int)msg;
                   int IwParam = (int)wParam;
                   int IlParam = (int)lParam;
                   Task.Run(async () =>
                   {
                       payload = client.sock.Concat(new byte[] { 3 }, client.sock.IntToBytes(Imsg));
                       payload = client.sock.Concat(payload, client.sock.IntToBytes(IwParam));
                       payload = client.sock.Concat(payload, client.sock.IntToBytes(IlParam));
                       await client.SendAsync(payload);
                   }).Wait();
                   break;
 
               case 0x0302: //WM_PASTE
                   break;
 
               case 0x0100: //WM_KEYDOWN
               case 0x0101: // WM_KEYUP
                   msg = (uint)m.Msg;
                   wParam = m.WParam;
                   lParam = m.LParam;
 
                   // Check if the Shift or Caps Lock key is pressed
                   bool isShiftPressed = (GetKeyState((int)Keys.ShiftKey) & 0x8000) != 0;
                   bool isCapsLockOn = Control.IsKeyLocked(Keys.CapsLock);
                   if (isShiftPressed || isCapsLockOn)
                   {
                       // Modify the wParam to include the SHIFT or CAPSLOCK flag
                       const int VK_SHIFT = 0x10;
                       const int VK_CAPITAL = 0x14;
 
                       if (wParam.ToInt32() == VK_SHIFT || wParam.ToInt32() == VK_CAPITAL)
                       {
                           // Skip processing SHIFT or CAPSLOCK key release
                           break;
                       }
 
                       if (isShiftPressed)
                       {
                           msg = 0x0102;
                           uint scanCode = (uint)((lParam.ToInt32() >> 16) & 0xFF);
                           byte[] keyboardState = new byte[256];
                           ToAscii((uint)wParam.ToInt32(), scanCode, keyboardState, out uint charCode, 0);
                           wParam = (IntPtr)Convert.ToInt32(GetModifiedKey((char)charCode));
                       }
 
                       if (isCapsLockOn)
                       {
                           uint scanCode = (uint)((lParam.ToInt32() >> 16) & 0xFF);
                           byte[] keyboardState = new byte[256];
                           ToAscii((uint)wParam.ToInt32(), scanCode, keyboardState, out uint charCode, 0);
                           if (IsAlphaNumeric((char)charCode))
                           {
                               msg = 0x0102;
                           }
                       }
                   }
                   Imsg = (int)msg;
                   IwParam = (int)wParam;
                   IlParam = (int)lParam;
                   Task.Run(async () =>
                   {
                       payload = client.sock.Concat(new byte[] { 3 }, client.sock.IntToBytes(Imsg));
                       payload = client.sock.Concat(payload, client.sock.IntToBytes(IwParam));
                       payload = client.sock.Concat(payload, client.sock.IntToBytes(IlParam));
                       await client.SendAsync(payload);
                   }).Wait();
                   break;
           }
           base.WndProc(ref m);
       }
 
   }
public class CustomPictureBox : PictureBox
   {
       Node client;
       public CustomPictureBox(Node _client)
       {
           client = _client;
       }
 
       [DllImport("user32.dll")]
       public static extern short GetKeyState(int nVirtKey);
 
       // Constants for clipboard data formats
       public const uint CF_TEXT = 1;          // Text format
       public const uint CF_BITMAP = 2;        // Bitmap format
       public const uint CF_UNICODETEXT = 13;   // Unicode text format
       public const uint CF_HDROP = 15;         // File format
 
       // Import the necessary WinAPI functions
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool IsClipboardFormatAvailable(uint format);
 
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool OpenClipboard(IntPtr hWndNewOwner);
 
       [DllImport("user32.dll")]
       public static extern IntPtr GetClipboardData(uint uFormat);
 
 
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool CloseClipboard();
 
       [DllImport("user32.dll")]
       static extern short VkKeyScan(char c);
 
       [DllImport("user32.dll")]
       public static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out uint lpChar, uint uFlags);
       public Point TranslateCoordinates(Point originalCoords, Size originalScreenSize, PictureBox targetControl)
       {
           // Calculate the scaling factors
           float scaleX = (float)targetControl.Image.Width / originalScreenSize.Width;
           float scaleY = (float)targetControl.Image.Height / originalScreenSize.Height;
 
           // Apply the scaling factors
           int scaledX = (int)(originalCoords.X * scaleX);
           int scaledY = (int)(originalCoords.Y * scaleY);
 
           // Get the unzoomed and offset-adjusted coordinates
           Point translatedCoords = UnzoomedAndAdjusted(targetControl, new Point(scaledX, scaledY));
 
           return translatedCoords;
       }
       public static void GetClipboardFormat()
       {
           if (!OpenClipboard(IntPtr.Zero))
               return;
 
 
           if (IsClipboardFormatAvailable(CF_TEXT))
           {
               IntPtr hGlobal = GetClipboardData(CF_TEXT);
               string clipboardText = Marshal.PtrToStringUni(hGlobal);
               Marshal.FreeHGlobal(hGlobal);
           }
           else if (IsClipboardFormatAvailable(CF_BITMAP))
           {
               IntPtr hBitmap = GetClipboardData(CF_BITMAP);
               System.Drawing.Bitmap clipboardBitmap = System.Drawing.Bitmap.FromHbitmap(hBitmap);
               Marshal.FreeHGlobal(hBitmap);
           }
           else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
           {
               IntPtr hGlobal = GetClipboardData(CF_UNICODETEXT);
               string clipboardText = Marshal.PtrToStringUni(hGlobal);
               Marshal.FreeHGlobal(hGlobal);
           }
 
           CloseClipboard();
       }
       private Point UnzoomedAndAdjusted(PictureBox pictureBox, Point scaledPoint)
       {
           // Calculate the zoom factor
           float zoomFactor = Math.Min(
               (float)pictureBox.ClientSize.Width / pictureBox.Image.Width,
               (float)pictureBox.ClientSize.Height / pictureBox.Image.Height);
 
           // Get the displayed rectangle of the image
           Rectangle displayedRect = GetImageDisplayRectangle(pictureBox);
 
           // Offset and unzoom the coordinates
           int translatedX = (int)((scaledPoint.X - displayedRect.X) / zoomFactor);
           int translatedY = (int)((scaledPoint.Y - displayedRect.Y) / zoomFactor);
 
           return new Point(translatedX, translatedY);
       }
 
       private Rectangle GetImageDisplayRectangle(PictureBox pictureBox)
       {
           if (pictureBox.SizeMode == PictureBoxSizeMode.Normal)
           {
               return new Rectangle(0, 0, pictureBox.Image.Width, pictureBox.Image.Height);
           }
           else if (pictureBox.SizeMode == PictureBoxSizeMode.StretchImage)
           {
               return pictureBox.ClientRectangle;
           }
           else
           {
               float zoomFactor = Math.Min(
                   (float)pictureBox.ClientSize.Width / pictureBox.Image.Width,
                   (float)pictureBox.ClientSize.Height / pictureBox.Image.Height);
 
               int imageWidth = (int)(pictureBox.Image.Width * zoomFactor);
               int imageHeight = (int)(pictureBox.Image.Height * zoomFactor);
 
               int imageX = (pictureBox.ClientSize.Width - imageWidth) / 2;
               int imageY = (pictureBox.ClientSize.Height - imageHeight) / 2;
 
               return new Rectangle(imageX, imageY, imageWidth, imageHeight);
           }
       }
       public static char GetModifiedKey(char c)
       {
           short vkKeyScanResult = VkKeyScan(c);
 
           // a result of -1 indicates no key translates to input character
           if (vkKeyScanResult == -1)
               return c;
 
           // vkKeyScanResult & 0xff is the base key, without any modifiers
           uint code = (uint)vkKeyScanResult & 0xff;
           // set shift key pressed
           byte[] b = new byte[256];
           b[0x10] = 0x80;
 
           uint r;
           // return value of 1 expected (1 character copied to r)
           if (1 != ToAscii(code, code, b, out r, 0))
               return c;
 
           return (char)r;
       }
 
       public static bool IsAlphaNumeric(char c)
       {
           return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '1' && c <= '9');
       }
       public void TriggerWndProc(ref Message m)
       {
           WndProc(ref m);
       }
 
       protected override void WndProc(ref Message m)
       {
           if (this.Image == null)
           {
               base.WndProc(ref m);
               return;
           }
           byte[] payload;
           switch (m.Msg)
           {
               case 0x0201: // WM_LBUTTONDOWN
               case 0x0202: // WM_LBUTTONUP
               case 0x0204: // WM_RBUTTONDOWN
               case 0x0205: // WM_RBUTTONUP
               case 0x0207: // WM_MBUTTONDOWN
               case 0x0208: // WM_MBUTTONUP
               case 0x0203: // WM_LBUTTONDBLCLK
               case 0x0206: // WM_RBUTTONDBLCLK
               case 0x0209: // WM_MBUTTONDBLCLK
               case 0x0200: // WM_MOUSEMOVE
               case 0x020A: // WM_MOUSEWHEEL
                   int x = (int)(m.LParam.ToInt32() & 0xFFFF);
                   int y = (int)((m.LParam.ToInt32() >> 16) & 0xFFFF);
                   Point newpoint = TranslateCoordinates(new Point(x, y), this.Image.Size, this);
                   x = newpoint.X;
                   y = newpoint.Y;
 
                   m.LParam = (IntPtr)((y << 16) | (x & 0xFFFF));
 
                   uint msg = (uint)m.Msg;
                   IntPtr wParam = m.WParam;
                   IntPtr lParam = m.LParam;
                   int Imsg = (int)msg;
                   int IwParam = (int)wParam;
                   int IlParam = (int)lParam;
                   Task.Run(async () =>

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
咖啡_741298
为你点赞!
3天前
最新回复 (1)
雪    币: 9780
活跃值: (7005)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
.net yyds
2024-12-15 19:40
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册