钩子函数

以下代码摘录自《VC++深入详解》:

首先我们新建一个DLL,并编写钩子函数和钩子过程函数:

# include <windows.h> HHOOK g_hMouse = NULL; HHOOK g_hKeyboard = NULL; #pragma data_seg( "MySec" ) HWND g_hWnd = NULL; #pragma data_seg()

#pragma comment( linker,"/section:MySec,RWS" ) LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam ) { return 1; } LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam ) { if ( VK_F2 == wParam ) { SendMessage( g_hWnd,WM_CLOSE,0,0 ); UnhookWindowsHookEx( g_hMouse ); UnhookWindowsHookEx( g_hKeyboard ); } return 1; } void SetHook( HWND hwnd ) { g_hWnd = hwnd; g_hMouse = SetWindowsHookEx( WH_MOUSE,MouseProc,GetModuleHandle( "Hook" ),0 ); g_hKeyboard = SetWindowsHookEx( WH_KEYBOARD,KeyboardProc,GetModuleHandle( "Hook" ),0 ); }

并编写一个模块定义文件:

LIBRARY Hook EXPORTS SetHook @2

编译连接即可。为了防止系统给全局变量g_hWnd开辟新的空间,我们在DLL中添加一个新的区段,并设置成共享属性,将其加入其中。这样一来g_hWnd就不会产生副本,也就是可以一直保存着客户程序的句柄了。

 

这里,我们用LordPE程序查看生成的dll文件:

钩子函数_第1张图片

看见生成了一个MySec区段,根据其标志位可知其属性为:

IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 The section contains initialized data. 该区块包含以初始化的数据。 ----------------------------------- IMAGE_SCN_MEM_SHARED 0x10000000 The section can be shared in memory. 该区块为共享区块。 ----------------------------------- IMAGE_SCN_MEM_READ 0x40000000 The section can be read. 该区块可读,可执行文件中的区块总是设置该 标志。 ----------------------------------- IMAGE_SCN_MEM_WRITE 0x80000000 The section can be written to. 该区块可写。

接下来,我们新建一个MFC程序,选择对话框风格。拷贝dll文件至MFC程序路径下,并在菜单“工程”->“设置”中引入lib文件:

钩子函数_第2张图片

接下来在程序中声明SetHook函数:

_declspec( dllimport ) void SetHook( HWND hwnd );

并修改OnInitDialog函数如下:

BOOL CHookTestDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon // TODO: Add extra initialization here
    int cxScreen,cyScreen; cxScreen = GetSystemMetrics( SM_CXSCREEN ); cyScreen = GetSystemMetrics( SM_CYSCREEN ); SetWindowPos( &wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW ); SetHook( m_hWnd ); return TRUE;  // return TRUE unless you set the focus to a control
}

这里,整个钩子程序就设置好了,运行将屏蔽所有鼠标与键盘消息,只有按下“F2”键才可以退出。

你可能感兴趣的:(钩子函数)