C#代碼設置系統鉤子

系統鉤子

曾經有一段時間特別迷戀外掛程序,所以有所瞭解,但僅限於皮毛,因爲缺少的知識太多就放棄了,最近有個私活須要用到鉤子,因此重行來研究一番,其實也談不上研究,我是一個C#程序員,原本就沒有多少系統的知識(並非每一個C#程序員都是這樣),使用win32 api對我來講仍是有些困難的,因此不能給出多麼高深的講解,這裏僅限於我是如何使用C#調用win32 api來實現系統鉤子的。

什麼是鉤子程序員

我不以爲本身能說清楚什麼是鉤子,因此我推薦你們看一些 鉤子簡介windows

項目需求:api

實現一個程序來禁用全部鼠標按鍵,禁用任務管理器,禁用註冊表等。

涉及Win32 API函數

  1. SetWindowsHookEx (參考)
  2. UnhookWindowsHookEx (參考)

代碼實現ui

  1. 要使用鉤子首先咱們得有一個鉤子url

    個人鉤子代碼
    ```CSharp
    //定義個委託類型,由於設置鉤子的時候須要這種類型的委託實現
    private delegate int HookProc(int nCode,IntPtr wparam,ref IntPtr lparam);線程

    //實現HookProc委託簽名的方法
    private static int HookProcCallback(int nCode, IntPtr wparam, ref IntPtr lparam)
    {
    //這裏能夠進行消息的過濾,返回0時全部的消息都不會進入下一個鉤子
    return 0;
    }
    ```
  2. 設置鉤子到系統的鉤子鏈中code

    SetWindowsHookEx的定義的參數:
    1. 鉤子的類型,即它處理的消息類型(好比:鍵盤鉤子,鼠標鉤子,Shell鉤子等)
    2. 鉤子回調函數,即接收的消息由誰處理
    3. 須要鉤子攔截的程序句柄,0/null爲當前進程/模塊,
    4. 是否爲全局鉤子,若是爲0則與全部線程關聯,即全局鉤子;不然,這個線程必定屬性上一個參數對應的進程/模塊

    設置鉤子代碼
    CSharp //定義一個鉤子實例 var hookProc = new HookProc(HookProcCallback); //設置鉤子 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, proc, null, 0); if(hkeyboardHook!=IntPtr.Zero){ //設置成功 }進程

完整代碼

public class Hook
{
    // 設置鉤子
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr SetWindowsHookEx(int idHook, HookHandlerDelegate lpfn, IntPtr hmod, uint dwThreadID);

    // 卸載鉤子 
    [DllImport("user32.dll")]
    public static extern bool UnhookWindowsHookEx(IntPtr idHook);

    // 獲取模塊句柄
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetModuleHandle(String modulename);
    public const int WM_KEYDOWN = 0x0100;
    public const int WH_KEYBOARD_LL = 13;
    public const int WM_SYSKEYDOWN = 0x0104;
    public struct KBDLLHOOKSTRUCT
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }
    public delegate int HookHandlerDelegate(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam);
    //鉤子回掉委託實例
    private static HookHandlerDelegate proc;
    //鉤子句柄
    private static IntPtr hKeyboardHook;

    private static int HookCallback(int nCode, IntPtr wparam, ref KBDLLHOOKSTRUCT lparam)
    {
        if (
            nCode >= 0
            &&
            (wparam == (IntPtr)WM_KEYDOWN
            ||
            wparam == (IntPtr)WM_SYSKEYDOWN)
            )
        {
            if (lparam.vkCode == 91 || lparam.vkCode == 164 || lparam.vkCode == 9 || lparam.vkCode == 115)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        return 0;
    }

    public static void HookStart()
    {
        if (hKeyboardHook == IntPtr.Zero)
        {
            // 建立HookProc實例 
            proc = new HookHandlerDelegate(HookCallback);
            using (Process curPro = Process.GetCurrentProcess())
            using (ProcessModule curMod = curPro.MainModule)
            {
                //定義全局鉤子 
                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, proc,GetModuleHandle(curMod.FileName), 0);
            }

            if (hKeyboardHook == IntPtr.Zero)
            {
                HookStop();
                throw new Exception("鉤子設置失敗");
            }
        }

    }

    public static void HookStop()
    {
        bool retKeyboard = true;
        if (hKeyboardHook != IntPtr.Zero)
        {
            retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
            hKeyboardHook = IntPtr.Zero;
        }
        if (!(retKeyboard)) throw new Exception("卸載鉤子失敗");

    }
}
相關文章
相關標籤/搜索