يوميات مقالات تعليقات تعليقات خارجية
 
السلام عليكم، أهلا بك في صفحتي الشخصية... الساعة الآن 3:09 AM دقيقة بتوقيت الرياض
 
 

يتذكر مبرمجين ويندوز على لغة الفيجوال بيسك و السي++ طريقة كانوا يتجسسون بها على النوافذ الصغيرة مثل TextBox أو ComboBox للتغير في سلوكها و طريقة عملها، و كانت تسمى هذه الطريقة حسب اصطلاح مايكروسفت هوكينق Hooking، هذه الطريقة ما زالت ممكنة حتى في عالم الدوت نيت، فنستطيع التجسس على الأدوات في Windows.Forms مثل TextBox و ListView وغيرها، و الكود التالي عبارة عن فئتين Class تسهل العملية بشكل كبير.

using System;
using System.Collections.Generic;
using System.Text;
namespace MaNa.Helper
{
  using System;
  using System.Drawing;
  using System.Runtime.InteropServices;
  // Contains managed wrappers and implementations of Win32
  // structures, delegates, constants and platform invokes
  // used by the GradientFill and Subclassing samples.
  public sealed class Win32
  {
    public struct TRIVERTEX
    {
      public int x;
      public int y;
      public ushort Red;
      public ushort Green;
      public ushort Blue;
      public ushort Alpha;
      public TRIVERTEX(int x, int y, Color color) : this(x, y, color.R, color.G, color.B, color.A)
      {
      }
      public TRIVERTEX(int x, int y, ushort red, ushort green, ushort blue, ushort alpha)
      {
        this.x = x;
        this.y = y;
        this.Red = (ushort)(red << 8);
        this.Green = (ushort)(green << 8);
        this.Blue = (ushort)(blue << 8);
        this.Alpha = (ushort)(alpha << 8);
      }
    }
    public struct GRADIENT_RECT
    {
      public uint UpperLeft;
      public uint LowerRight;
      public GRADIENT_RECT(uint ul, uint lr)
      {
        this.UpperLeft = ul;
        this.LowerRight = lr;
      }
    }
    public struct GRADIENT_TRIANGLE
    {
      public uint Vertex1;
      public uint Vertex2;
      public uint Vertex3;
      public GRADIENT_TRIANGLE(uint v1, uint v2, uint v3)
      {
        this.Vertex1 = v1;
        this.Vertex2 = v2;
        this.Vertex3 = v3;
      }
    }
    // WM_NOTIFY notification message header.
    [System.Runtime.InteropServices.StructLayout (LayoutKind.Sequential)]
    public class NMHDR
    {
      private IntPtr hwndFrom;
      public uint idFrom;
      public uint code;
    }
    //[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
    public struct TVITEM
    {
      public int mask;
      private IntPtr hItem;
      public int state;
      public int stateMask;
      private IntPtr pszText;
      public int cchTextMax;
      public int iImage;
      public int iSelectedImage;
      public int cChildren;
      private IntPtr lParam;
    }
    // Native representation of a point.
    public struct POINT
    {
      public int X;
      public int Y;
    }
    public struct TVHITTESTINFO
    {
      public POINT pt;
      public uint flags;
      public IntPtr hItem;
    }
    // A callback to a Win32 window procedure (wndproc):
    // Parameters:
    //   hwnd - The handle of the window receiving a message.
    //   msg - The message
    //   wParam - The message's parameters (part 1).
    //   lParam - The message's parameters (part 2).
    //  Returns an integer as described for the given message in MSDN.
    public delegate int WndProc(IntPtr hwnd, uint msg, uint wParam, int lParam);
    [DllImport ("user32.dll", SetLastError = true, EntryPoint = "GradientFill")]
    public static extern bool GradientFill(IntPtr hdc, TRIVERTEX[] pVertex, uint dwNumVertex, GRADIENT_RECT[] pMesh, uint dwNumMesh, uint dwMode);
    public const int GRADIENT_FILL_RECT_H = 0x00000000;
    public const int GRADIENT_FILL_RECT_V = 0x00000001;
    // Not supported on Windows CE:
    public const int GRADIENT_FILL_TRIANGLE = 0x00000002;
    [DllImport ("user32.dll")]
    public static extern IntPtr SetWindowLong(IntPtr hwnd, int nIndex, IntPtr dwNewLong);
    public const int GWL_WNDPROC = -4;
    [DllImport ("user32.dll")]
    public static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, uint msg, uint wParam, int lParam);
    [DllImport ("user32.dll")]
    public static extern int DefWindowProc(IntPtr hwnd, uint msg, uint wParam, int lParam);
    [DllImport ("user32.dll")]
    public static extern int SendMessage(IntPtr hwnd, uint msg, uint wParam, ref TVHITTESTINFO lParam);
    [DllImport ("user32.dll", SetLastError = true)]
    public static extern int SendMessage(IntPtr hwnd, uint msg, uint wParam, ref TVITEM lParam);
    [DllImport ("user32.dll")]
    public static extern uint GetMessagePos();
    [DllImport ("user32.dll")]
    public static extern IntPtr BeginPaint(IntPtr hwnd, ref PAINTSTRUCT ps);
    [DllImport ("user32.dll")]
    public static extern bool EndPaint(IntPtr hwnd, ref PAINTSTRUCT ps);
    public struct PAINTSTRUCT
    {
      private IntPtr hdc;
      public bool fErase;
      public Rectangle rcPaint;
      public bool fRestore;
      public bool fIncUpdate;
      [MarshalAs (UnmanagedType.ByValArray, SizeConst = 32)]
      public byte[] rgbReserved;
    }
    [DllImport ("user32.dll")]
    public static extern IntPtr GetDC(IntPtr hwnd);
    [DllImport ("user32.dll")]
    public static extern bool ReleaseDC(IntPtr hwnd, IntPtr hdc);
    // Helper function to convert a Windows lParam into a Point.
    //   lParam - The parameter to convert.
    // Returns a Point where X is the low 16 bits and Y is the
    // high 16 bits of the value passed in.
    public static Point LParamToPoint(int lParam)
    {
      uint ulParam = (uint)lParam;
      return new Point((int)(ulParam & 0x0000ffff), (int)((ulParam & 0xffff0000) >> 16));
    }
    // Windows messages
    public const uint WM_PAINT = 0x000F;
    public const uint WM_ERASEBKGND = 0x0014;
    public const uint WM_KEYDOWN = 0x0100;
    public const uint WM_KEYUP = 0x0101;
    public const uint WM_MOUSEMOVE = 0x0200;
    public const uint WM_LBUTTONDOWN = 0x0201;
    public const uint WM_LBUTTONUP = 0x0202;
    public const uint WM_NOTIFY = 0x4E;
    public const uint WM_SETFOCUS = 0x0007;
    public const uint WM_ACTIVATE = 0x0006;
    public const uint WM_SETCURSOR = 0x0020;
    public const uint WM_RBUTTONDOWN = 0x0204;
    public const uint WM_RBUTTONUP = 0x0205;
    public const uint WM_NCHITTEST = 0x0084;
    /* WM_NCHITTEST codes*/
    public const int HTERROR = (-2);
    public const int HTTRANSPARENT = (-1);
    public const uint HTNOWHERE = 0;
    public const uint HTCLIENT = 1;
    public const uint HTCAPTION = 2;
    public const uint HTSYSMENU = 3;
    public const uint HTGROWBOX = 4;
    public const uint HTSIZE = HTGROWBOX;
    public const uint HTMENU = 5;
    public const uint HTHSCROLL = 6;
    public const uint HTVSCROLL = 7;
    public const uint HTMINBUTTON = 8;
    public const uint HTMAXBUTTON = 9;
    public const uint HTLEFT = 10;
    public const uint HTRIGHT = 11;
    public const uint HTTOP = 12;
    public const uint HTTOPLEFT = 13;
    public const uint HTTOPRIGHT = 14;
    public const uint HTBOTTOM = 15;
    public const uint HTBOTTOMLEFT = 16;
    public const uint HTBOTTOMRIGHT = 17;
    public const uint HTBORDER = 18;
    public const uint HTREDUCE = HTMINBUTTON;
    public const uint HTZOOM = HTMAXBUTTON;
    public const uint HTSIZEFIRST = HTLEFT;
    public const uint HTSIZELAST = HTBOTTOMRIGHT;
    public const uint HTOBJECT = 19;
    public const uint HTCLOSE = 20;
    public const uint HTHELP = 21;
    // Notifications
    public const uint NM_CLICK = 0xFFFFFFFE;
    public const uint NM_DBLCLK = 0xFFFFFFFD;
    public const uint NM_RCLICK = 0xFFFFFFFB;
    public const uint NM_RDBLCLK = 0xFFFFFFFA;
    // Key
    public const uint VK_SPACE = 0x20;
    public const uint VK_RETURN = 0x0D;
    // Treeview
    public const uint TV_FIRST = 0x1100;
    public const uint TVM_HITTEST = TV_FIRST + 17;
    public const uint TVHT_NOWHERE = 0x0001;
    public const uint TVHT_ONITEMICON = 0x0002;
    public const uint TVHT_ONITEMLABEL = 0x0004;
    public const uint TVHT_ONITEM = (TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMSTATEICON);
    public const uint TVHT_ONITEMINDENT = 0x0008;
    public const uint TVHT_ONITEMBUTTON = 0x0010;
    public const uint TVHT_ONITEMRIGHT = 0x0020;
    public const uint TVHT_ONITEMSTATEICON = 0x0040;
    public const uint TVHT_ABOVE = 0x0100;
    public const uint TVHT_BELOW = 0x0200;
    public const uint TVHT_TORIGHT = 0x0400;
    public const uint TVHT_TOLEFT = 0x0800;
    public const uint TVM_GETITEM = TV_FIRST + 62; //TVM_GETITEMW
    public const uint TVIF_TEXT = 0x0001;
    public const uint TVIF_IMAGE = 0x0002;
    public const uint TVIF_PARAM = 0x0004;
    public const uint TVIF_STATE = 0x0008;
    public const uint TVIF_HANDLE = 0x0010;
    public const uint TVIF_SELECTEDIMAGE = 0x0020;
    public const uint TVIF_CHILDREN = 0x0040;
    public const uint TVIF_DI_SETITEM = 0x1000;
  }
}

و هذه الفئة الثانية:

using System;

using System.Windows.Forms;

using System.Text;

using System.Collections.Generic;

using System.Runtime.InteropServices;

namespace Manahil.Helper

{

public class WndProcHooker

{

// The WndProcCallback method is used when a hooked

// window's message map contains the hooked message.

// Parameters:

// hwnd - The handle to the window for which the message

// was received.

// wParam - The message's parameters (part 1).

// lParam - The message's parameters (part 2).

// handled - The invoked function sets this to true if it

// handled the message. If the value is false when the callback

// returns, the next window procedure in the wndproc chain is

// called.

//

// Returns a value specified for the given message.

public delegate int WndProcCallback(

IntPtr hwnd, uint msg, uint wParam, int lParam, ref bool handled);

// This is the global list of all the window procedures we have

// hooked. The key is an hwnd. The value is a HookedProcInformation

// object which contains a pointer to the old wndproc and a map of

// message's callbacks for the window specified. Controls whose handles

// have been created go into this dictionary.

private static Dictionary<IntPtr, HookedProcInformation> hwndDict =

new Dictionary<IntPtr, HookedProcInformation>();

// The key for this dictionary is a control and the value is a

// HookedProcInformation. Controls whose handles have not been created

// go into this dictionary. When the HandleCreated event for the

// control is fired the control is moved into hwndDict.

private static Dictionary<Control, HookedProcInformation> ctlDict =

new Dictionary<Control, HookedProcInformation>();

// Makes a connection between a message on a specified window handle

// and the callback to be called when that message is received. If the

// window was not previously hooked it is added to the global list of

// all the window procedures hooked.

// Parameters:

// ctl - The control whose wndproc we are hooking.

// callback - The method to call when the specified.

// message is received for the specified window.

// msg - The message being hooked.

public static void HookWndProc(

Control ctl, WndProcCallback callback, uint msg)

{

HookedProcInformation hpi = null;

if (ctlDict.ContainsKey(ctl))

hpi = ctlDict[ctl];

else if (hwndDict.ContainsKey(ctl.Handle))

hpi = hwndDict[ctl.Handle];

if (hpi == null)

{

// If new control, create a new

// HookedProcInformation for it.

hpi = new HookedProcInformation(ctl,

new Win32.WndProc(WndProcHooker.WindowProc));

ctl.HandleCreated += new EventHandler(ctl_HandleCreated);

ctl.HandleDestroyed += new EventHandler(ctl_HandleDestroyed);

ctl.Disposed += new EventHandler(ctl_Disposed);

// If the handle has already been created set the hook. If it

// hasn't been created yet, the hook will get set in the

// ctl_HandleCreated event handler.

if (ctl.Handle != IntPtr.Zero)

hpi.SetHook();

}

// Stick hpi into the correct dictionary.

if (ctl.Handle == IntPtr.Zero)

ctlDict[ctl] = hpi;

else

hwndDict[ctl.Handle] = hpi;

// Add the message/callback into the message map.

hpi.messageMap[msg] = callback;

}

// The event handler called when a control is disposed.

static void ctl_Disposed(object sender, EventArgs e)

{

Control ctl = sender as Control;

if (ctlDict.ContainsKey(ctl))

ctlDict.Remove(ctl);

else

System.Diagnostics.Debug.Assert(false);

}

// The event handler called when a control's handle is destroyed.

// We remove the HookedProcInformation from hwndDict and

// put it back into ctlDict in case the control get re-

// created and we still want to hook its messages.

static void ctl_HandleDestroyed(object sender, EventArgs e)

{

// When the handle for a control is destroyed, we want to

// unhook its wndproc and update our lists

Control ctl = sender as Control;

if (hwndDict.ContainsKey(ctl.Handle))

{

HookedProcInformation hpi = hwndDict[ctl.Handle];

UnhookWndProc(ctl, false);

}

else

System.Diagnostics.Debug.Assert(false);

}

// The event handler called when a control's handle is created. We

// call SetHook() on the associated HookedProcInformation object and

// move it from ctlDict to hwndDict.

static void ctl_HandleCreated(object sender, EventArgs e)

{

Control ctl = sender as Control;

if (ctlDict.ContainsKey(ctl))

{

HookedProcInformation hpi = ctlDict[ctl];

hwndDict[ctl.Handle] = hpi;

ctlDict.Remove(ctl);

hpi.SetHook();

}

else

System.Diagnostics.Debug.Assert(false);

}

// This is a generic wndproc. It is the callback for all hooked

// windows. If we get into this function, we look up the hwnd in the

// global list of all hooked windows to get its message map. If the

// message received is present in the message map, its callback is

// invoked with the parameters listed here.

// Parameters:

// hwnd - The handle to the window that received the

// message

// msg - The message

// wParam - The message's parameters (part 1)

// lParam - The messages's parameters (part 2)

// Returns the callback handled the message, the callback's return

// value is returned form this function. If the callback didn't handle

// the message, the message is forwarded on to the previous wndproc.

private static int WindowProc(

IntPtr hwnd, uint msg, uint wParam, int lParam)

{

if (hwndDict.ContainsKey(hwnd))

{

HookedProcInformation hpi = hwndDict[hwnd];

if (hpi.messageMap.ContainsKey(msg))

{

WndProcCallback callback = hpi.messageMap[msg];

bool handled = false;

int retval = callback(hwnd, msg, wParam, lParam, ref handled);

if (handled)

return retval;

}

// If the callback didn't set the handled property to true,

// call the original window procedure.

return hpi.CallOldWindowProc(hwnd, msg, wParam, lParam);

}

System.Diagnostics.Debug.Assert(

false, "WindowProc called for hwnd we don't know about");

return Win32.DefWindowProc(hwnd, msg, wParam, lParam);

}

// This method removes the specified message from the message map for

// the specified hwnd.

public static void UnhookWndProc(Control ctl, uint msg)

{

// Look for the HookedProcInformation in the

// ctrDict and hwndDict dictionaries.

HookedProcInformation hpi = null;

if (ctlDict.ContainsKey(ctl))

hpi = ctlDict[ctl];

else if (hwndDict.ContainsKey(ctl.Handle))

hpi = hwndDict[ctl.Handle];

// if we couldn't find a HookedProcInformation, throw

if (hpi == null)

throw new ArgumentException("No hook exists for this control");

// look for the message we are removing in the messageMap

if (hpi.messageMap.ContainsKey(msg))

hpi.messageMap.Remove(msg);

else

// if we couldn't find the message, throw

throw new ArgumentException(

string.Format(

"No hook exists for message ({0}) on this control",

msg));

}

// Restores the previous wndproc for the specified window.

// Parameters:

// ctl - The control whose wndproc we no longer want to hook.

// disposing - True if HookedProcInformation is not

// read back into ctlDict.

public static void UnhookWndProc(Control ctl, bool disposing)

{

HookedProcInformation hpi = null;

if (ctlDict.ContainsKey(ctl))

hpi = ctlDict[ctl];

else if (hwndDict.ContainsKey(ctl.Handle))

hpi = hwndDict[ctl.Handle];

if (hpi == null)

throw new ArgumentException("No hook exists for this control");

// If we found our HookedProcInformation in ctlDict and we are

// disposing remove it from ctlDict.

if (ctlDict.ContainsKey(ctl) && disposing)

ctlDict.Remove(ctl);

// If we found our HookedProcInformation in hwndDict, remove it

// and if we are not disposing stick it in ctlDict.

if (hwndDict.ContainsKey(ctl.Handle))

{

hpi.Unhook();

hwndDict.Remove(ctl.Handle);

if (!disposing)

ctlDict[ctl] = hpi;

}

}

// This class remembers the old window procedure for the specified

// window handle and also provides the message map for the messages

// hooked on that window.

class HookedProcInformation

{

// The message map for the window.

public Dictionary<uint, WndProcCallback> messageMap;

// The old window procedure for the window.

private IntPtr oldWndProc;

// The delegate that gets called in place of this window's

// wndproc.

private Win32.WndProc newWndProc;

// Control whose wndproc is being hooked.

private Control control;

// Constructs a new HookedProcInformation object

// Parameters:

// ctl - The handle to the window being hooked

// wndproc - The window procedure to replace the

// original one for the control.

public HookedProcInformation(Control ctl, Win32.WndProc wndproc)

{

control = ctl;

newWndProc = wndproc;

messageMap = new Dictionary<uint, WndProcCallback>();

}

// Replaces the windows procedure for control with the

// one specified in the constructor.

public void SetHook()

{

IntPtr hwnd = control.Handle;

if (hwnd == IntPtr.Zero)

throw new InvalidOperationException(

"Handle for control has not been created");

oldWndProc = Win32.SetWindowLong(hwnd, Win32.GWL_WNDPROC,

Marshal.GetFunctionPointerForDelegate(newWndProc));

}

// Restores the original window procedure for the control.

public void Unhook()

{

IntPtr hwnd = control.Handle;

if (hwnd == IntPtr.Zero)

throw new InvalidOperationException(

"Handle for control has not been created");

Win32.SetWindowLong(hwnd, Win32.GWL_WNDPROC, oldWndProc);

}

// Calls the original window procedure of the control with the

// arguments provided.

// Parameters:

// hwnd - The handle of the window that received the

// message

// msg - The message

// wParam - The message's arguments (part 1)

// lParam - The message's arguments (part 2)

// Returns the value returned by the control's original wndproc.

public int CallOldWindowProc(

IntPtr hwnd, uint msg, uint wParam, int lParam)

{

return Win32.CallWindowProc(

oldWndProc, hwnd, msg, wParam, lParam);

}

}

}

}

نشر بتاريخ Saturday, October 07, 2006 7:43 PM

التعليقات

# re: التجسس على النوافذ Hooking في الدوت نيت Mohannad 10/14/2006 12:21 PM

هل جربت رؤية هذه الصفحة على الفايرفوكس؟؟ أتمنى أن تجرب

لا أستطيع رؤية نصف الكود!!!


# re: التجسس على النوافذ Hooking في الدوت نيت حُس حُس 10/16/2006 6:21 AM

بصراحة لم أجرب،
و يبدو ان الفايرفوكسيين يعانون كثيرا من الموقع،،
راح أثبته و أجربه،،

و بالمناسبه،، ترى الموضوع كان في المسوده، و نشرته بالغلط..

تحياتي،،


# tafrawt_11@hotmail.com soumaya 4/9/2008 3:25 PM

cava


العنوان  
الإسم  
الموقع
التعليق   
نص الصورة:
 • التصفح
 » RSS
 

 • المقالات

 » ASP.NET










 • الأرشيف





















 • اليوميات












 • الصور



جميع الحقوق محفوظة،
حسام المقحم 2006م