钩子函数简单示例

关于钩子函数的概念,百科有更详细的注释。

我个人的理解是,任何消息,系统都会有对应的机制或者说函数来处理,钩子函数的意义在于,可以在系统处理之前,先拿到这个具体的消息,然后做出自己的处理,接下来可以选择将消息传给其它钩子函数,或者系统,或者截断消息的传递。    

不得不说,由于平台和环境的差异,很多例子根本跑不通,我这个基于VS/C++,基本的鼠标和键盘钩子,就当给自己做个记录吧

1.封装钩子函数的dll

   头文件名  MouseKeyboardHook.h

#ifdef MOUSEKEYBOARDHOOK_EXPORTS
#define MOUSEKEYBOARDHOOK_API __declspec(dllexport)
#else
#define MOUSEKEYBOARDHOOK_API __declspec(dllimport)
#endif
 
extern "C" MOUSEKEYBOARDHOOK_API int SetHook( DWORD dwThreadId  );
extern "C" MOUSEKEYBOARDHOOK_API int UnSetHook(void);

 执行函数文件名 MouseKeyboardHook.cpp

// MouseKeyboardHook.cpp : 定义 DLL 应用程序的导出函数。
//MouseKeyboardHook.cpp文件
 
#include "stdafx.h"
#include "MouseKeyboardHook.h"
#include "stdio.h"
#include <atlstr.h>
 
 
//共享内存变量
#pragma data_seg("MouseKeyboardHook")
HHOOK g_hMouseHook = NULL;
HHOOK g_hKeyboardHook = NULL;
#pragma data_seg()
// 这是导出变量的一个示例
MOUSEKEYBOARDHOOK_API int nMouseKeyboardHook=0;
 
// 这是导出函数的一个示例。
int UnSetHook(void);
int fnMouseKeyboardHook(void);
int SetHook( DWORD dwThreadId  );
//注意:钩子函数的格式必须是 LRESULT CALLBACK 函数名( int 钩子类型, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK MouseHookProc( int nCode, WPARAM wParam, LPARAM lParam );//处理鼠标的钩子函数
LRESULT CALLBACK KeyboardHookProc( int nCode, WPARAM wParam, LPARAM lParam );//处理键盘的钩子函数
HMODULE WINAPI ModuleFromAddress(PVOID pv) ;//这个是获取DLL的内存地址,可以重复使用,当做模版
 
 
LRESULT CALLBACK KeyboardHookProc( int nCode, WPARAM wParam, LPARAM lParam )
{
	if( wParam=='Q' && lParam>0 )//当只有按下Q键的时候才会退出钩子函数。其他其他的话都屏蔽
	{
		MessageBox( NULL, "卸载钩子中...", "卸载钩子", MB_OK );
		UnSetHook();
	}
	else return TRUE;
	return ::CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);//传递消息给其它钩子
}
 
LRESULT CALLBACK MouseHookProc( int nCode, WPARAM wParam, LPARAM lParam )//我这里屏蔽所有鼠标消息
{
if ( g_hMouseHook != NULL && nCode == HC_ACTION) {
  MessageBox( NULL, "安装钩子成功!", "", MB_OK );
  //UnSetHook();
  return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
  //return TRUE;//这里可以写自己的逻辑(回调函数),告诉windows,不用上班了
 }
 return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

MOUSEKEYBOARDHOOK_API int SetHook( DWORD dwThreadId  )//安装钩子函数
{
	g_hMouseHook = ::SetWindowsHookEx( WH_MOUSE, MouseHookProc, ModuleFromAddress(MouseHookProc), 0 );
	g_hKeyboardHook = ::SetWindowsHookEx( WH_KEYBOARD, KeyboardHookProc, ModuleFromAddress(KeyboardHookProc), 0 );
	return 0;
}
 
MOUSEKEYBOARDHOOK_API int UnSetHook(void)//卸载钩子函数
{
    MessageBox( NULL, "卸载钩子kaishi!", "", MB_OK );
	if (g_hMouseHook != NULL) {
		MessageBox( NULL, "卸载钩子lushang", "", MB_OK );
  ::UnhookWindowsHookEx(g_hMouseHook);
  MessageBox( NULL, "卸载钩子成功!", "", MB_OK );
  g_hMouseHook = NULL;
 }
	//	if (g_hKeyboardHook != NULL) {
 // ::UnhookWindowsHookEx(g_hKeyboardHook);
 // MessageBox( NULL, "卸载钩子成功!", "", MB_OK );
 // g_hKeyboardHook = NULL;
 //}
 return TRUE;

	//BOOL b1 = ::UnhookWindowsHookEx( g_hMouseHook );
	//BOOL b2 = ::UnhookWindowsHookEx( g_hKeyboardHook );
	//if( b1==FALSE || b2==FALSE )
	//	MessageBox( NULL, "卸载钩子失败!", "", MB_OK );
	//int a = GetLastError();
	//CString str ;
	//str.Format("%d", a);
	//MessageBox( NULL, "卸载", str, MB_OK );
	/*return 0;*/
}
 
HMODULE WINAPI ModuleFromAddress(PVOID pv) 
{
	MEMORY_BASIC_INFORMATION mbi;
	if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
	{
		return (HMODULE)mbi.AllocationBase;
	}
	else
	{
		return NULL;
	}
}

2.建一个简单工程MouseHookTest用来校验钩子函数

   将上述生成的MouseKeyboardHook.dll文件加载到自己的工程里

   MouseHookTest.cpp文件

//================================================
//===========头文件自己加==========================
//================================================
BOOL bInstall = FALSE;//用来指示是否已经安装了钩子
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
//需要声明导出函数指针
typedef int ( *pSetHook)(DWORD * );//声明函数类型
typedef int ( *pUnsetHook)(void);
//===========================================
//============主函数==========================
//===========================================
void CMouseHookTestDlg::OnBnClickedButton1()//自定义调用函数
{
	// TODO: 在此添加控件通知处理程序代码
HMODULE hModule = ::LoadLibrary( "MouseKeyboardHook.dll" );//加载DLL库
	if( hModule!=NULL )
	{
		if( bInstall==FALSE )
		{
			pSetHook mpSetHook;
			mpSetHook = (pSetHook)::GetProcAddress( hModule, "SetHook" );//获取导出函数地址
			if( mpSetHook!=NULL )
			{
				mpSetHook( 0 );//安装全局钩子
				bInstall = TRUE;
				GetDlgItem( IDC_BUTTON1 )->SetWindowText( "卸载DLL" );
			}
			else MessageBox( "获取函数地址失败!" );
		}
		else
		{
			pUnsetHook mpUnsetHook;
			mpUnsetHook = (pUnsetHook)::GetProcAddress( hModule, "UnSetHook" );
			if( mpUnsetHook!=NULL )
			{
				mpUnsetHook();//卸载钩子
				bInstall = FALSE;
				GetDlgItem( IDC_BUTTON1 )->SetWindowText( "加载DLL" );
			}
			else MessageBox( "获取函数地址失败!" );
			::FreeLibrary( hModule );//释放加载的DLL库
		}
	}
	else MessageBox( "加载DLL失败!" );
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值