【HOOK技术】键盘钩子

  今天对WINDOWS的HOOK技术进行了应用:

主要包括以下:

1,HOOK技术原理的了解;

2,HOOK技术中的常见钩子应用:键盘钩子,鼠标钩子,消息钩子

3,钩子DLL在调用程序EXE中的调试。

 

首先,HOOK技术中的几个常用函数:

View Code
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
);
View Code
BOOL UnhookWindowsHookEx(
HHOOK hhk // handle to hook procedure to remove
);

 

其次,工程步骤,第一步,钩子DLL的创建,源代码如下:

View Code
// KeyHook.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include <fstream>

using namespace std;

#define DLLEXPORT extern "C" __declspec(dllimport)

//变量
HHOOK hhkHook =NULL; //定义钩子句柄
HINSTANCE hInstance =NULL; //程序实例
fstream chOut; //输出文件

//导出函数
DLLEXPORT int add(int a, int b); //测试
DLLEXPORT BOOL InstallHook(); //安装钩子
DLLEXPORT BOOL UnInstallHook(); //卸载钩子

//定义函数
LRESULT CALLBACK KeyboardProc(

int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
);



//入口
BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hInstance = (HINSTANCE)hModule;
return TRUE;
}

//钩子的实现部分
LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam )

{
if (code == HC_ACTION)
{
//获取当前的按键 wParam
char ch[1] = {0};

ch[0] = wParam;

BOOL bKeyUp = FALSE; //键是否按下或弹起
BOOL bKeyAlt = FALSE; //ALT键
//检查按键的键 lParam
//判断ALT键
if (lParam & 0x20000000)

{
bKeyAlt =TRUE;
}
if (bKeyAlt)
{
//当前按下ALT
::MessageBox(0,"ALT","KeyBoardLocked",MB_OK);

}

//判断键是否按下或弹起
if (lParam & 0x80000000)

{
bKeyUp = TRUE;
}
if (bKeyUp)
{
//当前按键已经弹起
//写文件
chOut.write(ch, 1);

chOut.flush();
}
}

// if(!::FindWindow(0,"KeyBoardLocked"))
// {
// ::MessageBox(0,"键盘已经锁定!!!","KeyBoardLocked",MB_OK);
// }
// return CallNextHookEx(hhkHook, code, wParam, lParam);

return 1; //不调用 CallNextHookEx 将会屏蔽掉键盘
}


BOOL InstallHook()
{
chOut.open("c:\\keyhook.log", ios::app | ios::out);
hhkHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, hInstance, 0);

if (hhkHook != NULL)
{
return TRUE;
}
else
{
return FALSE;
}
}

BOOL UnInstallHook()
{
if (chOut.is_open)
{
chOut.close();
}

return UnhookWindowsHookEx(hhkHook);
}


第二步,钩子调用程序,源代码如下:

View Code
//变量定义
HMODULE m_hDll = NULL;

typedef BOOL (*INSPROC)(void);
typedef BOOL (*UNINSPROC)(void);

在一个对话框中,添加了两个按钮

View Code
void CKeyHookTestDlg::OnButton1() 
{
// TODO: Add your control notification handler code here
m_hDll = LoadLibrary("KeyHook.dll");


if(m_hDll==NULL)
{
MessageBox("fail");
}
else
{
INSPROC instproc;
instproc = (INSPROC)GetProcAddress(m_hDll, "InstallHook");
BOOL bResult = instproc();
}
}

void CKeyHookTestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
UNINSPROC uninstproc;

uninstproc = (UNINSPROC)GetProcAddress(m_hDll, "UnInstallHook");
BOOL bResult = uninstproc();

::FreeLibrary(m_hDll);
m_hDll = NULL;
}


再次,就是调用程序对钩子DLL进行调试。

1,创建工作区间时,DLL工程和EXE工程在一个工作区间;

2,设置EXE工程为"Set as active project";
3,将DLL工程编译后生成的LIB文件,加载到EXE工程中,方法有2个

  #pragma comment(lib, "XXX.lib") 或者在"project"->"setting"->"link": "Object/library modules:"设定

4,以上就可以进行调试了。

在这里一个小技巧提示:

1,将DLL工程的dll生成路径设置为EXE工程exe生成路径

2,将将EXE工程调用lib文件所在路径设置为DLL工程的dll生成路径



 

posted @ 2011-11-04 18:46  陈昂  阅读(4167)  评论(6编辑  收藏  举报