用C#钩子写一个改键外挂

我的微信群——软件开发测试工程师交流群,欢迎扫码:

改键是一种习惯,比如在玩儿lol或者dota的时候。理论上玩儿什么游戏都可以改键。

做一个窗体(点击Install——应用改键,点击Uninstall——撤销应用):

窗体定义代码如下:

using System.Windows.Forms;

namespace KeysExchange
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.intall_button = new System.Windows.Forms.Button();
            this.uninstall_button = new System.Windows.Forms.Button();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.comboBox2 = new System.Windows.Forms.ComboBox();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // intall_button
            // 
            this.intall_button.Location = new System.Drawing.Point(179, 162);
            this.intall_button.Name = "intall_button";
            this.intall_button.Size = new System.Drawing.Size(75, 23);
            this.intall_button.TabIndex = 4;
            this.intall_button.Text = "Install";
            this.intall_button.UseVisualStyleBackColor = true;
            this.intall_button.Click += new System.EventHandler(this.intall_button_Click);
            // 
            // uninstall_button
            // 
            this.uninstall_button.Location = new System.Drawing.Point(179, 207);
            this.uninstall_button.Name = "uninstall_button";
            this.uninstall_button.Size = new System.Drawing.Size(75, 23);
            this.uninstall_button.TabIndex = 5;
            this.uninstall_button.Text = "Uninstall";
            this.uninstall_button.UseVisualStyleBackColor = true;
            this.uninstall_button.Click += new System.EventHandler(this.uninstall_button_Click);
            // 
            // comboBox1
            // 
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Location = new System.Drawing.Point(54, 41);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(57, 21);
            this.comboBox1.TabIndex = 6;
            this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            // 
            // comboBox2
            // 
            this.comboBox2.FormattingEnabled = true;
            this.comboBox2.Location = new System.Drawing.Point(175, 41);
            this.comboBox2.Name = "comboBox2";
            this.comboBox2.Size = new System.Drawing.Size(57, 21);
            this.comboBox2.TabIndex = 7;
            this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(126, 44);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(43, 13);
            this.label1.TabIndex = 8;
            this.label1.Text = "改为:";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(301, 273);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.comboBox2);
            this.Controls.Add(this.comboBox1);
            this.Controls.Add(this.uninstall_button);
            this.Controls.Add(this.intall_button);
            this.Name = "Form1";
            this.Text = "KeysExchange";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion
        private System.Windows.Forms.Button intall_button;
        private System.Windows.Forms.Button uninstall_button;
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.ComboBox comboBox2;
        private System.Windows.Forms.Label label1;
    }

    struct ComboItem
    {
        private string text;
        private string value;

        public ComboItem(string text, string value)
        {
            this.text = text;
            this.value = value;
        }

        public override string ToString()
        {
            return this.text;
        }

        public string ToValue()
        {
            return this.value;
        }
    }
}

钩子代码如下:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace KeysExchange
{
    public class KeyboardHookLib
    {
        private const int WH_KEYBOARD_LL = 13;      
        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);
        private static int _hHookValue = 0;
        private HookHandle _KeyBoardHookProcedure;
        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);
        private IntPtr _hookWindowPtr = IntPtr.Zero;
        public KeyboardHookLib() { }
        private static ProcessKeyHandle _clientMethod = null;
        [DllImport("user32")]
        public static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
        private const int WM_KEYDOWN = 0x100;//KEYDOWN
        private const int WM_KEYUP = 0x101;//KEYUP
        private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
        private const int WM_SYSKEYUP = 0x105;//SYSKEYUP

        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = new HookHandle(OnHookProc);
                _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
                _hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL, _KeyBoardHookProcedure, _hookWindowPtr, 0);
                if (_hHookValue == 0) UninstallHook();
            }
        }

        public void UninstallHook()
        {
            if (_hHookValue != 0)
            {
                if (UnhookWindowsHookEx(_hHookValue))
                {
                    _hHookValue = 0;
                }
            }
        }

        private static int OnHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));
                if (_clientMethod != null)
                {
                    bool handle = false;
                    ///Tylan: Judge if the event is KeyDown or not.
                    if (lParam.ToInt32() > 0 && wParam == 0x100)
                    {
                        _clientMethod(hookStruct, out handle);
                    }
                    if (handle) return 1; 
                }
            }
            return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
        }
    }
}

逻辑部分代码如下:

using System;
using System.Windows.Forms;

namespace KeysExchange
{
    public partial class Form1 : Form
    {
        private KeyboardHookLib _keyboardHook = null;

        public Form1()
        {
            InitializeComponent();
            for (int alp = 65; alp <= 90; alp++)
            {
                ComboItem item = new ComboItem(((Keys)alp).ToString(), alp.ToString());
                comboBox1.Items.Add(item);
                comboBox2.Items.Add(item);
            }
        }

        private void intall_button_Click(object sender, EventArgs e)
        {
            //Install the hook.
            _keyboardHook = new KeyboardHookLib();
            _keyboardHook.InstallHook(this.OnKeyPress);
        }

        private void uninstall_button_Click(object sender, EventArgs e)
        {
            //Cancel the hook.
            if (_keyboardHook != null) _keyboardHook.UninstallHook();
        }

        public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
        {
            handle = false;
            if (((Keys)hookStruct.vkCode).ToString() == comboBox1.SelectedItem.ToString()) 
            {
                handle = true;
                //Exchange the keys.
                hookStruct.vkCode = int.Parse(((ComboItem)comboBox2.SelectedItem).ToValue());
                Keys key = (Keys)hookStruct.vkCode;
                //MessageBox.Show((key == Keys.None ? "" : key.ToString()));
                System.Windows.Forms.SendKeys.Send(key.ToString().ToLower());
            }
        }
    }
}

F5运行,找个游戏试一下,改键成功啦(按p成功打开背包)~

原文地址:https://www.cnblogs.com/LanTianYou/p/5053682.html