消息钩子在Windows编程中有着非常广泛的应用,它可以任意拦截Windows系统,这个以消息为驱动的系统中的绝大多数消息类型。一方面这给编程者带来了巨大的灵活性,另一方面也埋下了巨大隐患,大多数窃密软件都使用这种方法。此篇文章给您提供一种钩子的反拦截方法,希望对您有所帮助。文章中使用了API钩子,您之前必须对此技术有一定了解。  
          为求完整,文章分为两部分,第一部分为消息钩子的使用,熟悉此技术的读者可以直接跳过此节。第二部分为消息钩子的反拦截。

一、消息钩子的使用

消息钩子分为本地(local)和远程(remote)两种(两个local   system-wide   hook例外,无关主题,不多说了)。local类型的钩子函数只能拦截本进程的消息。能够拦截本进程以外的消息的钩子,都是remote类型。remote类型的钩子必须放在DLL里面。下面以remote类型为例,通过安装键盘钩子介绍其使用。

1、首先建立DLL,在头文件中添加如下代码。

 #ifdef   KM_EXPORTS  #define   KM_API   __declspec(dllexport)  #else  #define   KM_API   __declspec(dllimport)  #endif  KM_API   BOOL   HookStart();//安装钩子  KM_API   BOOL   HookStop();//卸载钩子   

2、在.cpp文件中添加代码

  #pragma   data_seg("Shared")  HHOOK   g_hhookKey=NULL;  #pragma   data_seg()  #pragma   comment(linker,"/SECTION:Shared,RWS")   

g_hhookKey为键盘钩子的句柄,为确保此数值在所有实例中均保持不变,将其存放于此模块所有实例的共享数据区,若在exe程序中按此格式添加一int   变量   appNum,在程序启动时appNum++,则可以通过访问此变量的数值,确定有多少个exe的实例,当然这种方法也可以替代同步对象用于只启动一个实例。

  HINSTANCE   g_hinstDll=NULL;         //添加全局变量用于记录此DLL模块的句柄  BOOL   APIENTRY   DllMain(   HANDLE   hModule,     DWORD     ul_reason_for_call,     LPVOID   lpReserved   )  {  switch   (ul_reason_for_call)  {  case   DLL_PROCESS_ATTACH:  g_hinstDll=(HINSTANCE)hModule;//在DLL加载时对全局变量赋值  ..................  }  }  LRESULT   KeyHookProc(int   nCode,WPARAM   wParam,LPARAM   lParam)//键盘钩子的过滤函数  {  .....................  return::CallNextHookEx(g_hhookKey,nCode,wParam,lParam);//*****请留意此行代码*****  }  BOOL   HookStart()//安装钩子  {    g_hhookKey=::SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyHookProc,g_hinstDll,  ::GetWindowThreadProcessId(::FindWindow(NULL,"被监视的窗口的标题"),NULL)   );  return   (g_hhookKey!=NULL);  }  BOOL   HookStop()//卸载钩子  {  BOOL   ret;  if(g_hhookKey!=NULL)  ret=::UnhookWindowsHookEx(g_hhookKey);  g_hhookKey=NULL;  return   ret;  }   

只要在exe程序中调用HookStart函数,就可以监视某一窗口的键盘消息,若此窗口为QQ的密码框,你的密码就泄漏了。

二、消息钩子的反拦截

请留意前面带*号注释的代码,其中传入了钩子的句柄g_hhookKey,只要使用API钩子将CallNextHookEx函数替换,并在替换函数中将其卸载,消息钩子就完蛋了。同时,还要保证本进程安装的钩子不被卸载,其中既可能有local类型的还可能有remote类型的。不要以为自己没有在程序中安装钩子,程序中就一定没有安装钩子,在MFC4版本中,MFC会自己装一个local类型的钩子,MFC7版本中好像没了。好了,下面介绍其实现。

1、建立DLL,在头文件中添加如下代码。

  #ifdef   HOOKFORBID_EXPORTS  #define   HOOKFORBID_API   __declspec(dllexport)  #else  #define   HOOKFORBID_API   __declspec(dllimport)  #endif  HOOKFORBID_API   int   fnHookForbid(void);//在exe程序中调用此函数,使DLL加载  HOOKFORBID_API   bool   AddHhook(HHOOK   Hhook);//若exe中安装remote类型消息钩子,将其句柄添加  HOOKFORBID_API   bool   DelHhook(HHOOK   Hhook);//在exe中卸载remote类型消息钩子时,删除其句柄

2、在.cpp文件中添加代码

  CArray<HHOOK,HHOOK>   array;//用于记录本进程安装的钩子的句柄  //  int   fnHookForbid(void)  {  return   1;  }  bool   AddHhook(HHOOK   Hhook)  {  array.Add(Hhook);  return   true;  }  bool   DelHhook(HHOOK   Hhook)  {  bool   ret=false;  for(int   i=0;i<array.GetSize();i++)  {  if(array.GetAt(i)==Hhook)  {  array.RemoveAt(i);  ret=true;  break;  }  }  return   ret;  }  //   

下面的代码用于API替换,其中用到了CAPIHook   类,《Windows   核心编程》(Jeffrey   Richter著)一书中有源代码。使用其它开发包也可以实现此功能。

  //  typedef   HHOOK   (WINAPI   *PFNSETWINDOWSHOOKEX)(  int   idHook,  HOOKPROC   lpfn,  HINSTANCE   hMod,  DWORD   dwThreadId  );  typedef   LRESULT     (WINAPI   *PFNCALLNEXTHOOKEX)(  HHOOK   hhk,  int   nCode,  WPARAM   wParam,  LPARAM   lParam  );  //  extern   CAPIHook   g_SetWindowsHookExA;  extern   CAPIHook   g_SetWindowsHookExW;  extern   CAPIHook   g_CallNextHookEx;  //  //此函数用于替换SetWindowsHookEx函数的ASCII版本SetWindowsHookExA  HHOOK   WINAPI   Hook_SetWindowsHookExA(   int   idHook,     HOOKPROC   lpfn,     HINSTANCE   hMod,     DWORD   dwThreadId   )    {  HHOOK   nResult   =0;  nResult   =   ((PFNSETWINDOWSHOOKEX)(PROC)   g_SetWindowsHookExA)(   idHook,   lpfn,     hMod,   dwThreadId     );  //若在本进程中安装了local类型钩子,记录其句柄  if(hMod==NULL)                    array.Add(nResult);  return(nResult);  }  //此函数用于替换SetWindowsHookEx函数的UNICODE版本SetWindowsHookExW  HHOOK   WINAPI   Hook_SetWindowsHookExW(   int   idHook,   HOOKPROC   lpfn,     HINSTANCE   hMod,   DWORD   dwThreadId     )    {  HHOOK   nResult   =0;  nResult   =   ((PFNSETWINDOWSHOOKEX)(PROC)   g_SetWindowsHookExW)(   idHook,   lpfn,     hMod,     dwThreadId     );  //若在本进程中安装了local类型钩子,记录其句柄  if(hMod==NULL)                    array.Add(nResult);  return(nResult);  }  //此函数用于替换CallNextHookEx函数,此函数只有一个版本  LRESULT     WINAPI   Hook_CallNextHookEx(   HHOOK   hhk,   int   nCode,     WPARAM   wParam,   LPARAM   lParam)    {  LRESULT     nResult   =0;  nResult   =   ((PFNCALLNEXTHOOKEX)(PROC)   g_CallNextHookEx)(   hhk,   nCode,   wParam,     lParam   );  //在数组中查找句柄,若找不到,将其卸载  bool   bfind=false;                      for(int   i=0;i<array.GetSize();i++)  {  if(array.GetAt(i)==hhk)  {  bfind=true;  break;  }  }  if(!bfind)  {  UnhookWindowsHookEx(     hhk     );  }  return   (nResult);  }  //  //使用CAPIHook   类对函数进行替换  CAPIHook   g_SetWindowsHookExA("User32.dll",   "SetWindowsHookExA",    (PROC)   Hook_SetWindowsHookExA,   true);  CAPIHook   g_SetWindowsHookExW("User32.dll",   "SetWindowsHookExW",    (PROC)   Hook_SetWindowsHookExW,   true);  CAPIHook   g_CallNextHookEx("User32.dll",   "CallNextHookEx",    (PROC)   Hook_CallNextHookEx,   true);   

到了这里,所有工作都完成了,只要在exe程序中调用fnHookForbid函数,并在安装remote类型钩子时调用AddHhook函数记录其句柄,卸载时调用DelHhook函数删除句柄就万事ok了。  
       一点不足:这种方法可以有效屏蔽消息钩子对信息安全的威胁。可以使Spy++失效。然而,由于是在CallNextHookEx函数中卸载钩子,因此,钩子函数总是会被调用一次。还有一件非常费解的事,金山词霸总能够正常取词,不知道词霸是怎么做到的。  
      本人并非专业程序员,   若此方法存在任何错误或隐患,敬请批评指出,请不要在帖子上损我。

呵呵!假如我的钩子是这么用的:

  FUN_SETWINDOWSHOOKA   *pFn   =   (FUN_SETWINDOWSHOOKA   *)  ::GetProcAddress(::GetModuleHandle("kernel32.dll"),   "SetWindowsHookA");  pFn(...);   

你的方法还是屏蔽不了哦!不信试验一下!记得给分哦!(该法为:“反反API钩子大法 ”)  
   
  当然!同理也可以绕过API钩子!有同样兴趣的人记得发消息给我哦!  
   
  首先声明一下:我拦截的是消息钩子,如果安装钩子时考虑到了反卸载则不在讨论之内。  
  其次:上述方法不可靠,对CAPIHook类进行更改,可以实时对地址进行替换,就象消息钩子被调用次序的不确定性一样,到时候没法确定那个替换函数被调用了。

Windows 反消息钩子(1)相关推荐

  1. windows全局消息钩子的一个BUG

    Windows操作系统全局消息钩子Bug 场景: Process A与Process B是同一个程序的两个实例, 1. 两个进程都设置了WH_CBT消息钩子,钩子的消息处理都在TSVulFw.dat模 ...

  2. C++ Windows Hook 消息钩子 详解

    本文完整测试工程的源码免积分下载地址:http://download.csdn.net/detail/zy_dreamer/5336484 我们先来简单的了解一下基本概念: Hook是WINDOWS提 ...

  3. 利用钩子机制取得Windows的消息监控权

    利用钩子机制取得Windows的消息监控权 我们知道,Windows系统是建立在消息传递机制基础上的,几乎所有的程序活动都由消息来驱动.Windows的钩子机制可以看作是一个消息中转站,控制系统发出消 ...

  4. 关于Windows消息钩子的理解与测试项目

    前奏 近来一直在自学Windows Hook相关的知识,已经尝试多种注入方式.尤其对消息钩子方式很感兴趣,因为看到Spy++能够截获系统中绝大多数应用的消息流,就很想知道它的工作原理,打算制作属于自己 ...

  5. windows中使用钩子拦截消息

    一.前 言 众所周知,Windows程式的运行是依靠发生的事件来驱动.换句话说,程式不断等待一个消息的发生,然后对这个消息的类型进行判断,再做适当的处理.处理完此次消息后又回到等待状态.从上面对Win ...

  6. windows消息处理过程及消息钩子

    应用层发消息: 发送消息过程 SendMessage(user32.dll)->SendMessageWorker,先检查有没有hook消息钩子,有的话调用CsSendMessage,进入消息钩 ...

  7. Windows的消息定义大全

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了. 例如:单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.           消息本身是作为 ...

  8. Windows窗口消息大全,全不全自己看

    1 Windows窗口消息大全,全不全自己看 2 3 // 4 #include "AFXPRIV.H"//消息值的定义来源 5 #include "Dde.h" ...

  9. Windows窗口消息介绍

    Windows窗口消息介绍 // #include "AFXPRIV.H"//消息值的定义来源 #include "Dde.h"//DDE消息值的定义来源 #i ...

最新文章

  1. at24c16如何划分出多个读写区_51单片机向at24c16EPROM写入一个数据每问题,写入多个数据,读出的数据都一样...
  2. Permission denied: user=root, access=WRITE, inode=/:hadoopuser:supergroup:drwxr-xr-x
  3. Java编程时部分快捷键
  4. Java的反射机制 工厂模式综合讲解【转载自51CTO】
  5. aria-required属性学习笔记
  6. java锁原理_Java锁原理学习
  7. 【github系列】github上传空目录
  8. Scrapy开发指南
  9. 小红的真真假假签到题题(构造+思维)
  10. java几何画板_geogebra几何画板下载
  11. IT负载率与数据中心规模——孙长青
  12. 工作占用了太多私人时间_当公司老板过多占用你的个人时间,虽然不是什么大事但很想辞职怎么办?...
  13. 各平均数介绍(算数平均数、几何平均数、加权算术平均数)
  14. Python爬虫(四)——小说下载器
  15. C语言练习-还原算术表达式
  16. Real-time Rendering (3rd edition)学习笔记第4章
  17. Win10 没有激活,如何改变任务栏位置
  18. 开放开源开先河(上)
  19. 级联(cascade)
  20. AlexNet模型及代码详解

热门文章

  1. GitHub的使用(入门)
  2. 旅游新纪元篇章,雾灵山紫山期待大家品鉴
  3. 【思维导图】大数据发展历程2005~2017
  4. 输入一行字符,分别统计出其中的英文字母大写小写、空格、数字和其它字符的个数。
  5. md5sum命令的灵活运用
  6. 疫苗行业薪酬增长率在生物医药领域最为突出;华为发布全场景智能光储解决方案;开利完成对广东积微集团的收购 | 美通社头条...
  7. FORD-FULKERSON算法
  8. ruid+oracle,Timmy Trumpet《Oracle》[高品质音乐下载]
  9. Excel中计算个人所得税的公式
  10. Jsp的四大作用域与九大对象