zoukankan      html  css  js  c++  java
  • 关于钩子(HOOK)

    以前做钩子的时候没写记录的习惯。昨天马力叫我重新做一个。这次补上。
    钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
    至于是否需要把钩子写在DLL里面取决于需求,如果只HOOK本进程得消息,可以把消息回调函数和调用钩子的函数写在一起,也就是只需要写个EXE就可以了。如果要HOOK全局消息,需要全局钩子,这样,需要把HOOK代码注入到系统每个进程里面去。而实现这个最好的方法,就是用DLL来实现。系统会自动把该DLL注入到所有的进程空间中。所以,不一定是必须要写DLL来HOOK。

    相关函数:
    创建新的钩子函数加
       HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId)
    钩子类型:比如  WH_KEYBOARD_LL,
    回调函数地址:钩子处理函数 LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    实例句柄:应用程序的实例句柄
    线程ID:要为哪个线程安装钩子.如果它为0则为全部线程都安装钩子,即为全局钩子.这就是获得全部应用程序消息控制权的开始

    卸载钩子函数
    BOOL UnhookWindowsHookEx( HHOOK hhk) 
    hhk为前一个函数的返回值。

    我也不知道如何描述的函数= =
      LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) 。

    这次需求仅仅是屏蔽,那就是不需要记录信息。仅仅是勾取消息后直接丢弃。

    设置键盘底层钩子
    HHOOK key_hHook = SetWindowsHookEx(
       WH_KEYBOARD_LL,
       KeyHookProc,
       base,
       //g_hInst,
       0);
    鼠标底层钩子
    HHOOK mouse_hHook = SetWindowsHookEx(
       WH_MOUSE_LL,
       MouseHookProc,
       base,
       0 );

    之后关于钩子函数,屏蔽即是PC机不作出回应。那么钩出的所有消息不做任何处理,直接给予抛弃处理。即return true;   


    关于DLL,转载下在论坛看的一段。因为自己也不是很懂。
    Win32 DLL的入口和出口函数都是DLLMain这同Win16 DLL是有区别的。只要有进程或线程载入和卸载DLL时,都会调用该函数,其原型是:
    BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;第二个参数指明了当前调用该动态连接库的状态,它有四个可能的值:DLL_PROCESS_ATTACH(进程载入)、DLL_THREAD_ATTACH(线程载入)、DLL_THREAD_DETACH(线程卸载)、DLL_PROCESS_DETACH(进程卸载)。在DLLMain函数中可以通过对传递进来的这个参数的值进行判别,根据不同的参数值对DLL进行必要的初始化或清理工作。由于在Win32环境下,所有进程的空间都是相互独立的,这减少了应用程序间的相互影响,但大大增加了编程的难度。当进程在动态加载DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。当DLL内存被映射到进程空间中,每个进程都有自己的全局内存拷贝,加载DLL的每一个新的进程都重新初始化这一内存区域,也就是说进程不能再共享DLL。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。一种方法便是把这些需要共享的数据单独分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,建立一个内存共享的DLL。 


    之后即是动态链接库的加载。
    静态加载需要动态链接的DLL和LIB以及H头文件。
    之后添加代码
    #include<xxx.h>
    #pragma comment(lib,"XXX.lib").
    之后直接引用函数。

    动态加载:
    typedef BOOL  (_stdcall * AddProc)(需导出的函数参数名)
      HINSTANCE hInst;
      
      hInst=LoadLibrary("动态链接库名.dll");
      AddProc m_Unlock=(AddProc)GetProcAddress(hInst,"函数名");//获取Dll的导出函数
      AddProc m_Lock=(AddProc)GetProcAddress(hInst,"函数名");//获取Dll的导出函数

    不过动态加载的方法在使用的时候我的程序会停止工作。具体原因不明。静态加载没问题。
  • 相关阅读:
    修改ubuntu DNS的步骤/wget url报错: unable to resolve host address的解决方法
    MySQL5.7 Replication主从复制配置教程
    总结一下安装linux系统经验-版本选择-安装ubuntu
    分布式与集群的联系与区别
    spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别
    mysql几种性能测试的工具使用
    mysql max_allowed_packet查询和修改
    mysql主从复制(超简单)
    10 个免费的网络监控工具(转)
    DOS批处理中%cd%和%~dp0的区别
  • 原文地址:https://www.cnblogs.com/zkkkkkky/p/4423007.html
Copyright © 2011-2022 走看看