c#特定程序的钩子

c#特定程序的钩子,第1张

你说的那个啥

wcHandle

压根就是一个窗口句柄

而SetWindowsHookEx

的第三个参数是

模块句柄

也就是说

你回调函数所在的模块的一个句柄

然后

最后一个参数是

进程id

和你需要进程绑定就可以了

局部钩子

没有写过

一般都写全局

HHOOK

SetWindowsHookEx(int

idHook,

//

钩子的类型,即它处理的消息类型HOOKPROC

lpfn,

//

钩子子程的地址指针。如果dwThreadId参数为0//

或是一个由别的进程创建的线程的标识,//

lpfn必须指向DLL中的钩子子程。//

除此以外,lpfn可以指向当前进程的一段钩子子程代码。// 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。HINSTANCE

hMod,

//

应用程序实例的句柄。标识包含lpfn所指的子程的DLL。//

如果dwThreadId

标识当前进程创建的一个线程,//

而且子程代码位于当前进程,hMod必须为NULL。//

可以很简单的设定其为本应用程序的实例句柄。DWORD

dwThreadId

//

与安装的钩子子程相关联的线程的标识符。//

如果为0,钩子子程与所有的线程关联,即为全局钩子。);

百科过来的

函数说明

简单来说钩子就是系统触发一定事件下要进行 *** 作的函数,但是不同的事件会有不同的附加信息,所以根据不同的事件也会在那个三个参数中传递不同的附加内容,就是处理方法的结构必须和系统定义好的结构相同才可以

下面是附加资料可以看一下

------------------------------------------------------------------------------------------------

首先说明一点,你的问题问得不是很恰当,因为钩子函数是回调函数,由系统规定参数,并传递参数,由你写好内容,然后由系统在一定触发条件下调用

例如你建立的是WH_MOUSE钩子, 那么MouseProc的三个参数由 *** 作系统(实际上是WIN32 平台)传递进来,意义分别是nCode怎么处理消息, wParam消息标识, lParam是一个MOUSEHOOKSTRUCT结构指针,而我们要做的就是利用这三个参数来完成自己想实现的功能,这正是回调函数的意义!

一般做钩子用到三个函数, 主要解决的是钩子函数的定义:

钩子有局部和远程两种类型, 与钩子相关的函数有:

1 建立钩子:SetWindowsHookEx, 其四个参数分别为钩子类型, 钩子函数地址, 钩子函数所在DLL的实例句柄,安装钩子后想监控的线程的ID号, 返回参数为钩子句柄

2 UnhookWindowsHookEx, 参数只有一个,为要卸载的钩子句柄

3 钩子函数(名称任意), 三个参数, 具体意义与钩子类型有关

下面再举一个简单例子:

比如你想写一个程序, 当鼠标移到哪里时就在主程序中显示鼠标所在窗口的名称

--------------------

(1)如果鼠标只是局限在窗口内, 那么以上1, 2, 3三个函数均写在运行的主程序中, 比如函数1可以写在按下某个按钮的消息响应函数中,函数 2 写在松开按扭的消息响应函数中,函数 3 只要不写在别的函数中就行, 因为它本生就是一个要定义的独立函数

(2)如果鼠标可以在屏幕任意位置移动, 那么以上函数1, 2位置同(1), 但函数3要写在一个另外写的DLL里, 因为此时安装的是全局钩子, 为了达到获取窗口名称的目的, 在DLL里可能还要做一些其他工作,比如设置共享段, 关于这些这里不细说了

------------------------

如果你想问的是如何填充SetWindowsHookEx的参数 或 钩子函数的三个参数的具体意义, 那么可以参考MSDN, 因为参数与钩子类型, 要挂钩的消息有关

按事件分类

有如下的几种常用类型

(1)键盘钩子和低级键盘钩子可以监视各种键盘消息。

(2) 鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。

(3) 外壳钩子可以监视各种Shell事件消息。比如启动和关闭应用程序。

(4)日志钩子可以记录从系统消息队列中取出的各种事件消息。

(5) 窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。

此外,还有一些特定事件的钩子提供给我们使用,不一一列举。

按使用范围分类

主要有线程钩子和系统钩子

(1) 线程钩子监视指定线程的事件消息。

(2)系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。这是系统钩子和线程钩子很大的不同之处。

几点需要说明的地方:

(1) 如果对于同一事件(如鼠标消息)既安装了线程钩子又安装了系统钩子,那么系统会自动先调用线程钩子,然后调用系统钩子。

(2) 对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。当前钩子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。

(3) 钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装钩子,在使用完毕后要及时卸载。

C#是面向对象的编程语言,所以钩子是写在类中的。

/// <summary>

/// 设置的钩子类型

/// </summary>

public enum HookType : int

{

     

    /// <summary>

    /// WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以把守菜单,迁移转变 

    ///条,消息框,对话框消息并且发明用户应用ALT+TAB or ALT+ESC 组合键切换窗口。 

    ///WH_MSGFILTER Hook只能把守传递到菜单,迁移转变条,消息框的消息,以及传递到通 

    ///过安装了Hook子过程的应用法度建树的对话框的消息。WH_SYSMSGFILTER Hook 

    ///把守所有应用法度消息。 

    ///WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式轮回时代 

    ///过滤消息,这等价于在主消息轮回中过滤消息。     

       

    ///经由过程调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。经由过程应用这 

    ///个函数,应用法度可以或许在模式轮回时代应用雷同的代码去过滤消息,如同在主消息循 

    ///环里一样

    /// </summary>

    WH_MSGFILTER = -1,

    /// <summary>

    /// WH_JOURNALRECORD Hook用来把守和记录输入事务。典范的,可以应用这 

    ///个Hook记录连气儿的鼠标和键盘事务,然后经由过程应用WH_JOURNALPLAYBACK Hook 

    ///往返放。WH_JOURNALRECORD Hook是全局Hook,它不克不及象线程特定Hook一样 

    ///应用。WH_JOURNALRECORD是system-wide local hooks,它们不会被打针到任何行 

    ///程地址空间

    /// </summary>

    WH_JOURNALRECORD = 0,

    /// <summary>

    /// WH_JOURNALPLAYBACK Hook使应用法度可以插入消息到体系消息队列。可 

    ///以应用这个Hook回放经由过程应用WH_JOURNALRECORD Hook记录下来的连气儿的鼠 

    ///标和键盘事务。只要WH_JOURNALPLAYBACK Hook已经安装,正常的鼠标和键盘 

    ///事务就是无效的。WH_JOURNALPLAYBACK Hook是全局Hook,它不克不及象线程特定 

    ///Hook一样应用。WH_JOURNALPLAYBACK Hook返回超时价,这个值告诉体系在处 

    ///理来自回放Hook当前消息之前须要守候多长时候(毫秒)。这就使Hook可以把握实 

    ///时事务的回放。WH_JOURNALPLAYBACK是system-wide local hooks,它们不会被 

    ///打针到任何行程地址空间

    /// </summary>

    WH_JOURNALPLAYBACK = 1,

    /// <summary>

       

    /// 在应用法度中,WH_KEYBOARD Hook用来把守WM_KEYDOWN and  

    ///WM_KEYUP消息,这些消息经由过程GetMessage or PeekMessage function返回。可以使 

    ///用这个Hook来把守输入到消息队列中的键盘消息

    /// </summary>

    WH_KEYBOARD = 2,

    /// <summary>

    /// 应用法度应用WH_GETMESSAGE Hook来把守从GetMessage or PeekMessage函 

    ///数返回的消息。你可以应用WH_GETMESSAGE Hook去把守鼠标和键盘输入,以及 

    ///其它发送到消息队列中的消息

    /// </summary>

    WH_GETMESSAGE = 3,

    /// <summary>

    /// 把守发送到窗口过程的消息,体系在消息发送到接管窗口过程之前调用

    /// </summary>

    WH_CALLWNDPROC = 4,

    /// <summary>

    /// 在以下事务之前,体系都邑调用WH_CBT Hook子过程,这些事务包含: 

    ///1 激活,建树,烧毁,最小化,最大化,移动,改变尺寸等窗口事务; 

    ///2 完成体系指令; 

    ///3 来自体系消息队列中的移动鼠标,键盘事务; 

    ///4 设置输入核苦衷务; 

    ///5 同步体系消息队列事务。

    ///Hook子过程的返回值断定体系是否容许或者防止这些 *** 纵中的一个

    /// </summary>

    WH_CBT = 5,

    /// <summary>

    /// WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以把守菜单,迁移转变 

    ///条,消息框,对话框消息并且发明用户应用ALT+TAB or ALT+ESC 组合键切换窗口。 

    ///WH_MSGFILTER Hook只能把守传递到菜单,迁移转变条,消息框的消息,以及传递到通 

    ///过安装了Hook子过程的应用法度建树的对话框的消息。WH_SYSMSGFILTER Hook 

    ///把守所有应用法度消息。 

    ///WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式轮回时代 

    ///过滤消息,这等价于在主消息轮回中过滤消息。 

    ///经由过程调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。经由过程应用这 

    ///个函数,应用法度可以或许在模式轮回时代应用雷同的代码去过滤消息,如同在主消息循 

    ///环里一样

    /// </summary>

    WH_SYSMSGFILTER = 6,

    /// <summary>

    /// WH_MOUSE Hook把守从GetMessage 或者 PeekMessage 函数返回的鼠标消息。 

    ///应用这个Hook把守输入到消息队列中的鼠标消息

    /// </summary>

    WH_MOUSE = 7,

    /// <summary>

    /// 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时

    /// </summary>

    WH_HARDWARE = 8,

    /// <summary>

    /// 在体系调用体系中与其它Hook接洽关系的Hook子过程之前,体系会调用 

    ///WH_DEBUG Hook子过程。你可以应用这个Hook来决意是否容许体系调用与其它 

    ///Hook接洽关系的Hook子过程

    /// </summary>

    WH_DEBUG = 9,

    /// <summary>

    /// 外壳应用法度可以应用WH_SHELL Hook去接管首要的通知。当外壳应用法度是 

    ///激活的并且当顶层窗口建树或者烧毁时,体系调用WH_SHELL Hook子过程。 

    ///WH_SHELL 共有5钟景象: 

    ///1 只要有个top-level、unowned 窗口被产生、起感化、或是被摧毁; 

    ///2 当Taskbar须要重画某个按钮; 

    ///3 当体系须要显示关于Taskbar的一个法度的最小化情势; 

    ///4 当今朝的键盘布局状况改变; 

    ///5 当应用者按Ctrl+Esc去履行Task Manager(或雷同级此外法度)。 

    ///遵守常规,外壳应用法度都不接管WH_SHELL消息。所以,在应用法度可以或许接 

    ///收WH_SHELL消息之前,应用法度必须调用SystemParametersInfo function注册它自 

    ///己

    /// </summary>

    WH_SHELL = 10,

    /// <summary>

    /// 当应用法度的前台线程处于余暇状况时,可以应用WH_FOREGROUNDIDLE  

    ///Hook履行低优先级的任务。当应用法度的前台线程可能要变成余暇状况时,体系就 

    ///会调用WH_FOREGROUNDIDLE Hook子过程

    /// </summary>

    WH_FOREGROUNDIDLE = 11,

    /// <summary>

    /// 把守发送到窗口过程的消息,体系在消息发送到接管窗口过程之后调用

    /// </summary>

    WH_CALLWNDPROCRET = 12,

    /// <summary>

    /// 把守输入到线程消息队列中的键盘消息

    /// </summary>

    WH_KEYBOARD_LL = 13,

    /// <summary>

    /// 把守输入到线程消息队列中的鼠标消息

    /// </summary>

    WH_MOUSE_LL = 14

}

public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        [DllImport("USER32DLL")]

private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);//导入钩子函数消息传递的方法

[DllImport("USER32DLL")]

private static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);//导入设置钩子的方法

[DllImport("user32dll", CharSet = CharSetAuto, CallingConvention = CallingConventionStdCall)]

private static extern bool UnhookWindowsHookEx(int idHook);    

//导入卸载钩子的方法

private delegate int HookProc(int nCode, int wParam, IntPtr lParam);  //声明回调函数

///<summary>

///自定义回调函数

///</summary>

private int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)

{

    MessageBoxShow(nCodeToString());

    //键盘按下时

    if (nCode >= 0 && wParam == (IntPtr)0)

    {

         int vkCode = MarshalReadInt32(lParam);

         Keys key = (Keys)vkCode;

         MessageBoxShow(keyToString());

    }

    return CallNextHookEx(handle, nCode, wParam, lParam);

}

        private void Form1_Load(object sender, EventArgs e)

        {

            //创建钩子(这个函数的参数你可以百度找找,C#钩子研究过但没成功)

            SetWindowsHookEx(params);

        }

    }

很多人都以为未排泄是大问题,其实不是,一个触发没有排泄是不会导致死机的,他只会在运行几千次以后造成游戏卡顿。而直接死机的原因大部分是因为触发没写好不断循环造成。

你这个触发本身没有问题,看看是不是钩子导致了其他触发不停循环,基本可以肯定问题出在其他触发,而不是这里。

以上就是关于c#特定程序的钩子全部的内容,包括:c#特定程序的钩子、易语言钩子、钩子程序的分类等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10125404.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存