全局钩子具体解释

全局钩子具体解释

监控程序的实现 
     我们发现一些木马或其它病毒程序经常会将我们的键盘或鼠标的操作消息记录下来然后再将它发到他们指定的地方以实现监听.这样的功能其它是利用了全局钩子将鼠标或键盘消息进行了截取,从而获得了操作的消息.要得到鼠标和键盘的控制权,我们要用SetWindowsHookEx这个函数: 
HHOOK SetWindowsHookEx( 
   int idHook,        // type of hook to install 
   HOOKPROC lpfn,     // address of hook procedure 
   HINSTANCE hMod,    // handle to application instance 
   DWORD dwThreadId   // identity of thread to install hook for 
); 
当中idHook是要安装的钩子标识即钩子的类型,lpfn是钩子函数的消息处理过程,hMod是应用程序的实例句柄,dwThreadId是要为哪个线程安装钩子.假设它为0则为所有线程都安装钩子,即为全局钩子.这就是获得所有应用程序消息控制权的開始.我们安装的钩子类型有非常多种主要是以下的: 
WH_CALLWNDPROCWH_CALLWNDPROCRETWH_CBTWH_DEBUGWH_FOREGROUNDIDLEWH_GETMESSAGEWH_JOURNALPLAYBACKWH_JOURNALRECORDWH_KEYBOARDWH_KEYBOARD_LLWH_MOUSEWH_MOUSE_LLWH_MSGFILTERWH_SHELLWH_SYSMSGFILTER 
当中WH_MOUSE是鼠标钩子,WH_KEYBOARD是键盘钩子. 
不同的钩子相应不同的钩子过程,钩子过程的写法(以键盘钩子过程为例)是: 
LRESULT CALLBACK MouseProc( 
   int nCode,      // hook code 
   WPARAM wParam,  // message identifier 
   LPARAM lParam   // mouse coordinates 
); 
钩子过程的名字是没关系的. 
要取消钩子的安装能够用UnhookWindowsEx: 
BOOL UnhookWindowsHookEx( 
   HHOOK hhk   // handle to hook procedure to remove 
);

以下要介绍一下怎样让每一个应用程序要安装上钩子函数,要让每一个应用程序都安装上钩子要用到动态链接库的知识,利用动态链接库载入到每一个应用程序中. 
我们首先用VC6.0新建一个WINDOWS动态链接库的空project,新建一个头文件为了动态链接库本身和使用动态链接库的应用程序也能用,我们定义好导入导出宏和自己定义消息以及要导入和导出的函数的定义: 
//HookDll.h 
// 定义函数修饰宏,方便引用本DLLproject的导出函数 
#ifdef KEYHOOKLIB_EXPORTS 
#define KEYHOOKLIB_API __declspec(dllexport)                 //导出宏 
#else 
#define KEYHOOKLIB_API __declspec(dllimport)               //导入宏 
#endif 
// 自己定义与主程序通信的消息 
#define HM_KEY WM_USER + 101                   //自己定义键盘消息 
#define HM_MOUSE WM_USER +102               //自己定义鼠标消息 
// 声明要导出的函数 
BOOL KEYHOOKLIB_API WINAPI SetKeyHook(BOOL bInstall, 
           DWORD dwThreadId = 0, HWND hWndCaller = NULL); 
BOOL KEYHOOKLIB_API WINAPI SetMouseHook(BOOL bInstall, 
           DWORD dwThreadId = 0, HWND hWndCaller = NULL

以下再新建一个C++源文件HookDll.cpp: 
我们先包括<windows.h>头文件 
再定义#define KEYHOOKLIB_EXPORTS让包括"HookDll.h"的时候,我们使用的是导出宏, 
#include "HookDll.h" 
#pragma data_seg("YCIShared") 
HWND g_hWndCaller = NULL; // 保存主窗体句柄 
HHOOK g_hHook = NULL;   // 保存钩子句柄 
HHOOK g_hMouseHook=NULL; 
#pragma data_seg() 
我们上面定义了共享的全局窗体句柄和全局的钩子标识,是为了全部应用程序都共享这三个变量. 
以下是钩子函数的实现代码: 
HMODULE WINAPI ModuleFromAddress(PVOID pv) //获得钩子函数的地址 

MEMORY_BASIC_INFORMATION mbi; 
if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 

   return (HMODULE)mbi.AllocationBase; 

else 

   return NULL; 


LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)// 键盘钩子函数消息过程 

     if(nCode < 0 || nCode == HC_NOREMOVE) 
return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);

if(lParam & 0x40000000) // 消息反复就交给下一个hook链 

   return ::CallNextHookEx(g_hHook, nCode, wParam, lParam); 
}

// 通知主窗体。wParam參数为虚拟键码, lParam參数包括了此键的信息 
   ::PostMessage(g_hWndCaller, HM_KEY, wParam, lParam);   //发送自己定义键盘消息 
   return ::CallNextHookEx(g_hHook, nCode, wParam, lParam); 

BOOL WINAPI SetKeyHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)// 安装、卸载钩子的函数 

BOOL bOk; 
g_hWndCaller = hWndCaller;

if(bInstall) 

   g_hHook = ::SetWindowsHookEx(WH_KEYBOARD, KeyHookProc, 
     ModuleFromAddress(KeyHookProc), dwThreadId);               //安装键盘钩子 
   bOk = (g_hHook != NULL); 

else 

   bOk = ::UnhookWindowsHookEx(g_hHook); 
   g_hHook = NULL; 
}

return bOk; 

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)//鼠标钩子处理过程 

   if(nCode < 0 || nCode == HC_NOREMOVE) 
   return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); 
   ::PostMessage(g_hWndCaller, HM_MOUSE, wParam, lParam);//发送自己定义鼠标消息 
   return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); 

BOOL WINAPI SetMouseHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller) 

BOOL bOk; 
g_hWndCaller = hWndCaller; 
if(bInstall) 

   g_hMouseHook = ::SetWindowsHookEx(WH_MOUSE, MouseProc, 
   ModuleFromAddress(MouseProc),dwThreadId);   //安装鼠标钩子 
   bOk = (g_hMouseHook != NULL); 

else 

   bOk = ::UnhookWindowsHookEx(g_hMouseHook); 
   g_hMouseHook = NULL; 

return bOk; 

最后再在project文件夹下建一个HookDll.def模块定义文件.写上下面代码 
LIBRARY HookDll 
EXPORTS         //指明导出函数名称 
   SetKeyHook 
   SetMouseHook 
SECTIONS       //指明共享字段 
   YCIShared   Read Write Shared 
用了模块定义文件时,在使用动态链接库的时间就能够直接用函数名调用函数了,否则将无法找到函数.其有用模块定义文件是为了不让动态链接库发生名字改编.

有了动态链接库后我们还须要用一个应用程序来设置和记录我们的鼠标和键盘记录. 
我们新建一个基于对话框的MFC应用程序projectHookApp.我们首先为我们的自己定义消息加入所需消息响应的实现代码. 
在对话框类的头文件的protected以下的凝视宏中间加入 
afx_msg longonHookKey(WPARAM wParam, LPARAM lParam); 
afx_msg longonHookMouse(WPARAM wParam, LPARAM lParam); 
指明消息处理函数,然后在对话框类的源文件里的 
BEGIN_MESSAGE_MAP(CHookAppDlg, CDialog) 
和END_MESSAGE_MAP之间加入以下的代码 
ON_MESSAGE(HM_KEY,onHookKey) 
ON_MESSAGE(HM_MOUSE,onHookMouse) 
定义好后在源文件里写事实上现函数: 
long CHookAppDlg::OnHookKey(WPARAM wParam, LPARAM lParam) 

// 此时參数wParam为用户按键的虚拟键码, 
// lParam參数包括按键的反复次数、扫描码、前一个按键状态等信息 
char szKey[80]; 
::GetKeyNameText(lParam, szKey, 80);   //获得按键名 
CString strItem; 
strItem.Format("用户按键:%s", szKey); 
CListBox *pListCtrl=((CListBox *)this->GetDlgItem(IDC_LIST1)); 
pListCtrl->InsertString(-1,strItem); 
     CFile MyFile; 
char *content; 
     if(!MyFile.Open(this->MyDocumentDir, 
   CFile::modeRead | CFile::modeWrite)) 

   MyFile.Open(this->MyDocumentDir, 
   CFile::modeCreate); 
   return 0; 

MyFile.SeekToEnd();                 //移动记录指针到末尾 
pListCtrl->GetText(pListCtrl->GetCount()-1,strItem); 
content=strItem.GetBuffer(MAX_PATH); 
MyFile.Write(content,strItem.GetLength()); 
CTime today=CTime::GetCurrentTime(); 
CString str=today.Format("/t/t%Y年%m月%d日 %H:%M:%S/r/n"); 
MyFile.Write(str.GetBuffer(str.GetLength()),str.GetLength()); 
MyFile.Close(); 
return 0; 

long CHookAppDlg::OnHookMouse(WPARAM wParam, LPARAM lParam) 

LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *)lParam; 
CString strItem,strText; 
     CListBox *pListCtrl=((CListBox *)this->GetDlgItem(IDC_LIST1)); 
CPoint point; 
::GetCursorPos(&point); 
ClientToScreen(&point); 
CWnd *pWnd=CWnd::GetForegroundWindow(); 
if(pWnd) 

   char str[80]; 
   pWnd->GetWindowText(str,80); 
   strText.Format("窗体:%s",str); 

CString str; 
/*CString tempstr; 
//   ClientToScreen(&pMouseHook->pt); 
   int x,y; 
   x=pMouseHook->pt.x; 
   y=pMouseHook->pt.y; 
   tempstr.Format("X=%d,Y=%d",x,y); 
   strText+=tempstr;*/ 
     if(wParam==WM_RBUTTONDOWN) 

   str.Format("   右键单击:位置 X=%d,Y=%d",point.x,point.y); 
   strText+=str; 
   pListCtrl->InsertString(-1,strText); 
   this->SaveToFile(strText,pListCtrl); 

if(wParam==WM_LBUTTONDBLCLK) 

   ScreenToClient(&point); 
   str.Format("   左键双击:位置 X=%d,Y=%d",point.x,point.y); 
   strText+=str; 
   pListCtrl->InsertString(-1,strText); 
   this->SaveToFile(strText,pListCtrl); 

if(wParam==WM_LBUTTONDOWN) 

   str.Format("   左键单击:位置 X=%d,Y=%d",point.x,point.y); 
   //MessageBox(strText); 
   strText+=str; 
   pListCtrl->InsertString(-1,strText); 
   this->SaveToFile(strText,pListCtrl); 

return 0; 

void CHookAppDlg::SaveToFile(CString strText,CListBox *pListCtrl) 

char *content; 
     CFile MyFile; 
if(!MyFile.Open(this->MyDocumentDir, 
   CFile::modeRead | CFile::modeWrite)) 

   MyFile.Open(this->MyDocumentDir, 
   CFile::modeCreate); 
   pListCtrl->InsertString(-1,"失败"); 
   return; 

MyFile.SeekToEnd(); 
content=strText.GetBuffer(strText.GetLength()); 
MyFile.Write(content,strText.GetLength()); 
CTime today=CTime::GetCurrentTime(); 
CString strTime=today.Format("/t/t%Y年%m月%d日 %H:%M:%S/r/n"); 
MyFile.Write(strTime.GetBuffer(strTime.GetLength()),strTime.GetLength()); 
MyFile.Close(); 

上面的代码就是实现将鼠标消息和键盘消息的操作消息加入到一个列表框中和记录到一个文件上的代码.当中this->MyDocumentDir是你要将操作消息记录到的文件路径.

在对话框初始化的时候
if(!SetKeyHook(TRUE,0, m_hWnd))
   MessageBox("安装钩子失败!");
if(!SetMouseHook(TRUE,0, m_hWnd))
   MessageBox("安装钩子失败!");

最后在
void CHookAppDlg::OnDestroy() 
{
::SetKeyHook(FASLE);//取消安装钩子
::SetMouseHook(FALSE);//取消安装钩子
}

这是鼠标和键盘消息的监听代码,你也能够为应用程序安装其它类型的钩子.

全局钩子具体解释,布布扣,bubuko.com

时间: 2024-08-28 18:30:15

全局钩子具体解释的相关文章

全局钩子详细解释

全局钩子具体解释 监控程序的实现      我们发现一些木马或其它病毒程序经常会将我们的键盘或鼠标的操作消息记录下来然后再将它发到他们指定的地方以实现监听.这样的功能其它是利用了全局钩子将鼠标或键盘消息进行了截取,从而获得了操作的消息.要得到鼠标和键盘的控制权,我们要用SetWindowsHookEx这个函数: HHOOK SetWindowsHookEx(    int idHook,        // type of hook to install    HOOKPROC lpfn,   

C# 鼠标全局钩子

/// <summary> /// 鼠标全局钩子 /// </summary> public class MouseHook { private const int WM_MOUSEMOVE = 0x200; private const int WM_LBUTTONDOWN = 0x201; private const int WM_RBUTTONDOWN = 0x204; private const int WM_MBUTTONDOWN = 0x207; private cons

VC++开发Windows系统全局钩子

本文的大部分内容属于对一篇网文的实践与练习,同时参考的还有一本书,在此向网文与书的作者表示敬意. 这个程序是一个windows系统键盘监控程序,随着开机自动启动,可以监控系统中各用户的键盘,并将按键记录写在指定的log文件里. 程序分为两个部分:全局钩子DLL和一个隐藏的单文档应用程序. 全局钩子DLL 创建基于“MFC AppWizard(dll)”的“扩展MFC DLL(Extension MFC DLL)”类型工程KeyBoardHook 在自动生成的源文件KeyBoardHook.cpp

钩子编程(HOOK) 安装系统全局钩子

MySQL使用的是插件式存储引擎. 主要包括存储引擎有:MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive,Merge,Federated. 其中最为广泛的是MyISAM 和Innodb两种存储引擎,所以接下来对它们做简单介绍. MyISAM 存储引擎简介 MyISAM 存储引擎的表存储在数据库中,每一个表都被存放为三个以表名命名的物理文件. 1.(.frm文件)任何存储引擎都不可缺少的存放表结构定义信息的文件 2.(.MYD文件)存放表数

常见注入手法第四讲,SetWindowsHookEx全局钩子注入.以及注入QQ32位实战.

常见注入手法第四讲,SetWindowsHookEx全局钩子注入.以及注入QQ32位实战. PS:上面是操作.最后是原理 一丶需要了解的API 使用全局钩子注入.我们需要了解几个WindowsAPI. 不需要太多. 1. 设置钩子API HHOOK WINAPI SetWindowsHookEx( _In_ int idHook, 设置钩子的类型.意思就是我要设置的钩子是什么钩子. 可以是监视窗口过程.可以是监视消息队列. _In_ HOOKPROC lpfn, 根据钩子类型.设置不同的回调函数

Django框架(十六)—— forms组件、局部钩子、全局钩子

forms组件.局部钩子.全局钩子 一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语法 from django.shortcuts import render, HttpResponse from django import forms # 1.先写一个类,继承Form class MyForm(forms.Form): # 定义一个属性,可以用

[C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入

1.扫描枪获取数据原理基本相当于键盘数据,获取扫描枪扫描出来的数据,一般分为两种实现方式. a)文本框输入获取焦点,扫描后自动显示在文本框内. b)使用键盘钩子,勾取扫描枪虚拟按键,根据按键频率进行手动输入和扫描枪扫描判断. 2.要实现系统钩子其实很简单,调用三个Win32的API即可. SetWindowsHookEx 用于设置钩子.(设立一道卡子,盘查需要的信息) CallNextHookEx 用于传递钩子(消息是重要的,所以从哪里来,就应该回到哪里去,除非你决定要封锁消息) UnhookW

C#全局钩子和局部钩子记录

源自:https://blog.csdn.net/programvae/article/details/80292076 最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋.也供后面的人学习.    因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是.    大部分网上参考文章都只是展示了全局钩子的写法,而线程钩子的写法和介绍相对少一些,特别是关键

利用debug钩子拦截全局钩子,经典反黑客技术

// 键盘钩子消息处理过程LRESULT CALLBACK DebugProc ( int nCode, WPARAM wParam, LPARAM lParam ){ if ( nCode == HC_ACTION ) {  PDEBUGHOOKINFO pDebugHookInfo = (PDEBUGHOOKINFO)lParam ;  switch ( wParam )  {  case WH_KEYBOARD:  case WH_MOUSE:   {    // 如果钩子不是由当前DEB