`
mmdev
  • 浏览: 12914935 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Windows 反消息钩子(1)

 
阅读更多

消息钩子在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类进行更改,可以实时对地址进行替换,就象消息钩子被调用次序的不确定性一样,到时候没法确定那个替换函数被调用了。
分享到:
评论

相关推荐

    ff.rar_钩子_钩子 消息

    消息钩子在Windows编程中有着非常广泛的应用,它可以任意拦截Windows系统,这个以消息为驱动的系统中的绝大多数消息类型。一方面这给编程者带来了巨大的灵活性,另一方面也埋下了巨大隐患,大多数窃密软件都使用这种...

    键盘钩子-windows消息机制-抓取用户按下的每一个按键

    用于抓取用户输入的键盘消息,已封装好类。无反钩子功能

    Secure-Desktop, 反键盘记录器/抗干扰技术在 Windows 中的应用.zip

    Secure-Desktop, 反键盘记录器/抗干扰技术在 Windows 中的应用 安全桌面安全桌面是 Windows 在安全区域打开程序的工具,它的中的控制台和远程管理工具无法访问。通过设置一个 /Windows 钩子来工作,它告诉 Windows ...

    ColdHide是适用于Windows的迷你,简单的开源用户模式反反调试库x86 / x64-C/C++开发

    ColdHide是适用于Windows的小型,简单的开源用户模式反反调试库x86 / x64。 要注入此库,请尝试使用ColdMDLoader。 ColdHide ColdHide是适用于Windows的小型,简单的开源用户模式反反调试库x86 / x64。 要注入此库,...

    Windows应用程序捆绑核心编程光盘代码

    9.5.2 替换Windows消息处理函数实现挂钩的实例 210 9.6 钩子DLL文件的装载 214 9.7 本章小结 216 参考文献 216 第10章 数据的编码和解码实例 217 10.1 引言 217 10.2 游程编码 218 10.2.1 CX游程压缩方法 218...

    Windows编程循序渐进.part2

    第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1...

    Windows编程循序渐进.part3

    第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1...

    windows编程资料大全

    当用户移动鼠标或按下键盘键时,Windows调用其中的一个钩子并且钩子函数开始记录时间: LRESULT CALLBACK MyMouseHook(int code,WPARAM wp,LPARAM lp) { if (code==HC_ACTION) { // note the tick count g_...

    bank_mitigations:反键盘记录器,反屏幕记录器...通过钩子进行保护或通过间谍软件检测来改善沙盒的策略...-演示

    bank_mitigations 防键盘记录器,防屏幕记录器...使用钩子进行保护的策略。 您可以将沙盒与恶意软件一起使用,请在以下位置阅读演示文稿: 视频PoC第1部分-阻止键盘记录程序: 视频PoC第2部分-阻止屏幕记录器:

    VfpDecoder反编译软件

    V1.5使用的钩子与V1.1不同, 提高了切入VFP程序的成功率,但缺点是无法判断出VFP程序的主文件,所以FileList.TXT中没有MainFile一项,另外对系统资源(主要是CPU)的占用率也有所增大。 3.V1.5比V1.1增加了一个...

    反键盘记录软件SpyShelter Premium9.7中文注册版.rar

    SpyShelter Premium是一款专业的反键盘记录软件,可以保护你的输入安全。可以加密所有进程或指定进程的击键,让任意进程都无法获取键盘的键入。受限程序,受限程序功能允许您自定义一份运行于低权限级别的应用程序...

    精通MFC (光盘) 源代码

    7.11.3 安装和解除消息钩子 7.11.4 使用线程范围和钩子实例 7.11.5 使用全局钩子实例 7.12 小结 第8章 对话框 8.1 对话框的生存期 8.1.1 对话框的创建 8.1.2 对话框的初始化 8.1.3 对话框的消息处理 8.1.4...

    xuetr0.36——狙剑的手动杀毒利器

    13.ObjectType Hook检测和恢复,提供了禁止创建进程,禁止创建线程,禁止创建文件,禁止创建注册表,禁止加载模块,禁止消息钩子注入,禁止关机重启等。对付强劲病毒可以起到大作用。 XueTr的主程序:蓝色的小图标,...

    软件破解入门教程.txt

    第二十四课 WINDOWS钩子函数 第二十五课:位图初步 第二十七课 工具提示控件 第二十八课 Win32调试API 第一部分 第二十六课 启动画面 第二十九课 Win32调试API 第二部分 第三十课 Win32调试API 第三部分 第三...

    Bytecode Viewer:逆向工程套件(反编译器、编辑器、调试器等)-开源

    通过 EZ-Injection 安全地启动 Java 应用程序并插入钩子。 使用 Malicious Code Scanner 插件扫描恶意代码。 导出为 DEX、Jar、Class、Zip 或 Java 源文件。 打开 Android APK、Android DEX、Java 类文件和 Java 罐...

    python灰帽子包含高清扫描和可复制两个版本.zip

     5.4 破除恶意软件中的反调试例程  5.4 1 lsDebuugerPresent  5.4.2 破除进程枚举例程  第6章 钩子的艺术  6.1 使用PyDbg部署软钩子  6.2 使用Immunity Debugger部署硬钩子  第7章 DLL注入与代码注入技术  ...

    冰刃 IceSword

    消息钩子:枚举系统中所注册的消息钩子(通过SetWindowsHookEx等),若钩子函数在exe模块中则是实际的地址,若在dll模块中则是相对于dll基址的偏移,具体请自行判断吧(一般地址值小于0x400000的就是全局钩子)。...

    RVDbg:RVDbg是Windows进程的debuggerexception处理程序,具有规避反调试技术的功能。 (正在以下文件中工作的更清洁,有记录的代码库:核心分支)

    这意味着议程还将​​不包括注册矢量化异常处理程序和结构化异常处理程序,而是从KiUserExceptionDispatcher中的钩子手动制作我们自己的异常处理程序,该异常处理程序可以优雅地丢弃与调试器无关的异常,并将它们...

    手工杀毒利器 系统维护 PC Hunter v1.5.4

    它是功能最强大的Windows系统信息分析查看及维护工具,同时也是强大的手工杀毒利刃,用它可以查看各类系统信息,例如:进程管理、驱动模块、内核钩子、网络管理,注册表、文件管理、启动项等,通过这些系统信息揪出...

Global site tag (gtag.js) - Google Analytics