用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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章