用c语言编写全局键盘钩子

KeyHook.c:用于生成DLL文件

#include <Windows.h>
#include <stdio.h>

static HHOOK hkb=NULL;
static HINSTANCE hins;
LRESULT RetVal;


// 使用__declspec(dllexport)声明导出函数
__declspec(dllexport) LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam);
__declspec(dllexport)  BOOL InstallHook();
__declspec(dllexport) BOOL UnstallHook();
__declspec(dllexport) DWORD SaveDataToFile(
					 LPSTR szFilePath,
					 LPVOID lpData,
					 DWORD dwDataSize);
/*************************************
* DllMain
**************************************/
BOOL WINAPI DllMain(
	HINSTANCE hinstDLL,  // DLL模块的句柄
	DWORD fdwReason,     // 调用的情况
	LPVOID lpReserved )  // reserved
{
	// 在不同的情况下都会调用DllMain函数,分别处理
	switch( fdwReason ) 
	{ 
		// 加载Dll
	case DLL_PROCESS_ATTACH:
		{
			hins = hinstDLL;
			printf("The dll loaded!\n");
			break;
		}
		// 新建线程
	case DLL_THREAD_ATTACH:
		break;
		// 线程退出
	case DLL_THREAD_DETACH:
		break;
		// 释放Dll
	case DLL_PROCESS_DETACH:
		hins = NULL;
		printf("The dll released!\n");
		break;
	}
	return TRUE;
}


LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{	
	if(((DWORD)lParam&0x40000000) && (HC_ACTION==nCode))
	{
		switch(wParam)
		{
			// ESC F1~F12
		case VK_ESCAPE:
			MessageBox(NULL,"SPACE",NULL,NULL);
			SaveDataToFile("C:\\Users\\zqc\\Desktop\\show.txt","SPACE",lstrlen("SPACE"));
			break;
		case VK_F1:
			MessageBox(NULL,"F1",NULL,NULL);
			SaveDataToFile("C:\\Users\\zqc\\Desktop\\show.txt","F1",lstrlen("F1"));
		// 0~9
		case '1':
			SaveDataToFile("C:\\Users\\zqc\\Desktop\\show.txt","1",lstrlen("1"));
			break;
		default:
			RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );	
			return  RetVal;
		}
	}
}


/********************************************************
*install a hook procedure to monitor the system for all 
*threads in the same desktop as the calling thread
*******************************************************/
BOOL InstallHook()
{
	hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
	if(hkb != NULL)
	{
		printf("Setwindowshook done!\n");
	}
	return TRUE;
}



BOOL UnstallHook()
{   	
	BOOL unhooked = UnhookWindowsHookEx(hkb);
	return unhooked;
} 


/* ************************************
*  SaveDataToFile
* 功能	将数据存储到文件末尾
* 参数	LPSTR szFilePath	文件路径
*		LPVOID lpData		需存储的数据
*		DWORD dwDataSize	数据大小(字节)
**************************************/
DWORD SaveDataToFile(
					 LPSTR szFilePath,
					 LPVOID lpData,
					 DWORD dwDataSize)
{
	//文件句柄
	HANDLE hFileWrite;
	//成功写入的数据大小
	DWORD dwWritedDateSize;

	//打开已经存在的文件,读取内容。	
	hFileWrite = CreateFile(szFilePath,	// 要打开的文件名
		GENERIC_WRITE,			// 以写方式打开
		0,						// 可共享读
		NULL,					// 默认安全设置
		OPEN_ALWAYS,			// 打开已经存在的文件,没用则创建
		FILE_ATTRIBUTE_NORMAL,	// 常规文件属性
		NULL);					// 无模板
	
	//判断是否打开成功
	if(hFileWrite==INVALID_HANDLE_VALUE)
	{
		printf("打开文件失败:%d\n",GetLastError());
	}

	//设置文件指针到文件尾
	SetFilePointer(hFileWrite,0,0,FILE_END);

	//将数据写入文件
	if(!WriteFile(hFileWrite,lpData,dwDataSize,&dwWritedDateSize,NULL))
	{
		printf("写文件失败:%d\n",GetLastError());
	}
	else
	{
		printf("写文件成功,写入%d字节。\n",dwWritedDateSize);
	}
	CloseHandle(hFileWrite);
	return 0;
}


TestDll.c:用于测试DLL

/* 头文件 */ 
#include <stdio.h> 
#include <windows.h>
#include <conio.h>
/* 类型定义 */

// 指向函数的指针类型
typedef DWORD (*MY_EXPORT_PROC)();

// main
VOID main(VOID) 
{ 
	HINSTANCE hinstLib; 
	MY_EXPORT_PROC lpProcAdd,lpProcAdd1; 
	BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 

	// 获得Dll模块句柄
	hinstLib = LoadLibrary(TEXT("SetWindowHook.dll")); 

	// 是否加载成功
	if (hinstLib != NULL) 
	{ 
		// 获得指定导出函数的地址
		lpProcAdd = (MY_EXPORT_PROC) GetProcAddress(hinstLib, "InstallHook"); 
	
		// 判断是否成功
		if (NULL != lpProcAdd) 
		{
			fRunTimeLinkSuccess = TRUE;
			//如果加载成功,则运行函数installhook
			(lpProcAdd) (); 
		} 
		Sleep(10000);
		
		//释放DLL之前先UnstallHook		
		lpProcAdd1 = (MY_EXPORT_PROC) GetProcAddress(hinstLib, "UnstallHook");
		// 判断是否成功
		if (NULL != lpProcAdd1) 
		{
			fRunTimeLinkSuccess = TRUE;
			//如果加载成功,则运行函数Unstallhook
			(lpProcAdd1) (); 
		}

		// 释放DLL
		fFreeResult = FreeLibrary(hinstLib); 
	} 

	// 出错
	if (! fRunTimeLinkSuccess) 
		printf("error; %u\n",GetLastError()); 
	getch();
}




发布了22 篇原创文章 · 获赞 8 · 访问量 15万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章