首页 > 其他分享 >键盘记录器编写笔记

键盘记录器编写笔记

时间:2022-10-05 08:55:27浏览次数:68  
标签:字符 键盘记录 函数 Windows 笔记 DLL 键盘 获取 编写

目录

键盘Hook

目的

  • 利用Windows钩子监控键盘事件,记录键盘字符,编译成dll在后台运行

实现

  • 工程位于E:\Project\Cpp\Keyboard\KeyboardRecorder\Crack

头文件

  • 包含windows.h

全局变量

  • 定义模块句柄HINSTANCE hin

DllMain函数

  • DLL的入口函数,按照固定格式必写

  • 在DLLMain中初始化hin=HModule

Install函数

  • extern "C" __declspec(dllexport)定义为导出函数
  • 调用SetWindowsHookEx钩子监控键盘事件,并注册回调函数KeyboardProc
  • Sleep,主要工作在回调函数中完成,不Sleep的话进程很快退出

Remove函数

  • UnhookWindowsHookEx卸载钩子

KeyboardProc函数

  • 键盘回调,参数分别保存消息代码,虚拟键代码和扫描代码
  • CreateFile创建文件,GetFileSize和SetFilePointer移动指针追加字符
	HANDLE pFile = CreateFile("C:\\key.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	DWORD dwHigh;
	DWORD dwPos = GetFileSize(pFile, &dwHigh);
	SetFilePointer(pFile, dwPos, 0, FILE_BEGIN);
  • 通过GetKeyboardState获取256字节的虚拟键代码
  • 通过GetKeyState判断shift键是否按下
  • 调用ToAscii函数,传入上述值,获取键盘Ascii码
  • 将键盘字符通过WriteFile写入文件
  • 返回CallNextHookEx

DLL调试

  • 转化为exe来逐步调试,但实际上我并没能够进入回调函数内的断点
  • 生成DLL,rundll运行并通过MessageBox来打印调试信息,并通过GetLastError来获取内部报错
char ch[10];
snprintf(ch, 10, "[INFO]%d", GetLastError());
MessageBox(NULL,ch,NULL,0);
  • rundll在后台运行,每次调试后可通过下列方式杀死进程
1.资源监视器
资源监视器->CPU->关联句柄,输入运行的文件夹,结束下面的进程
2.tasklist
tasklist | findstr rundll
taskkill /pid pid /F

遇到的问题

  • 由于dll是由rundll启动的,所以通过getModuleHandle获取不到主模块,传入SetWindowsHookEx错误,解决方法:在dllMain函数中获取模块值
  • 通过GetKeyNameTextA(lParam, szKey, 100)能够直接获取键盘字符,但是不能识别大小写和shift
  • (此部分实现在Crack_scan.cpp中)通过wParam判断键盘按下/弹上,通过vkCode取扫描码,将扫描码逐个转化为目标字符,该方法更细粒度,但实际调试发现取不到vkCode,故放弃
  • (此部分实现在Crack.cpp中)最后选用了ToAscii函数来转化字符,可处理大小写和shift
  • 尝试通过GetActiveWindow获取窗口标题,但结果不准确
  • 将文件写入C盘会有权限问题,解决办法:一是写入Windows/Temp目录,二是点击目标文件夹属性->安全->编辑->full control,增加写权限

Windows API例程

https://hub.おうか.tw/microsoft/Windows-classic-samples/tree/1d363ff4bd17d8e20415b92e2ee989d615cc0d91

标签:字符,键盘记录,函数,Windows,笔记,DLL,键盘,获取,编写
From: https://www.cnblogs.com/z5onk0/p/16755040.html

相关文章

  • 一款很简单的键盘记录器,只保留了基础功能
    //Crack.cpp:定义DLL应用程序的入口点。#include"pch.h"HINSTANCEhin; //模块句柄:即本模块在内存中的首地址BOOLAPIENTRYDllMain(HMODULEhModule, //入口函......
  • 阅读笔记一
    今天开始阅读了程序员修炼之道,感悟颇多。第一节名为我的源码被猫吃了该章节主要讲述了人要为自己的所作所为负责,程序员也要为自己接受的任务负责,不管你是不是因为什么其......
  • 【笔记】字符串相关
    Trie字典树构造trie上的每个节点表示一个字符,而trie的根到trie上某个节点的路径即代表了一个字符串。实现较为简单,每个节点记录字符集大小个儿子的\(\text{idx}\)......
  • 编写webpack 插件
    Webpack插件为第三方开发者释放了Webpack的最大可能性。利用多级回调开发者可以把他们自己的需要的功能引入到Webpack里面来。Build插件比Buildloader更进一步。因为你需......
  • Asp-Net-Core开发笔记:集成Hangfire实现异步任务队列和定时任务
    前言最近把Python写的数据采集平台往.NetCore上迁移,原本的采集任务使用多进程+线程池的方式来加快采集速度,使用Celery作为异步任务队列兼具定时任务功能,这套东西用着还行......
  • Pandas 学习笔记
    一、用Pandas创建Excel文件importpandasaspddf=pd.DataFrame({'ID':[1,2,3],'Name':['liujun','daifen','duanziqian']})#创建一个数据集df=df.set_index('ID'......
  • 栈&单调栈笔记
    栈先进后出,由于STL中的stack内存分配逻辑是deque,常数极大,所以通常用数组或vector模拟。对于数组模拟栈,数组的第一个位置通常被设为栈顶,下面是已被封装成类的代码......
  • C++自学笔记 多态性的实现 How virtual work in C++
     静态联编所支持的多态性称为编译时的多态性。当调用重载函数时,编译器可以根据调用时所使用的实参在编译时就确定下应调用哪个函数。动态联编所支持的多态性称为运行时......
  • C++自学笔记 多态性 Polymorphism
      virtual关键字虚函数/虚方法  前缀virtual关键字表示子类父类有联系 virtual的作用是告诉编译器,对该函数的调用是通过指针或者引用的话,在运行时才可以确......
  • 【学习笔记】索引
    索引mysql官方对索引的定义为:索引(index)是帮助Mysql高效获取数据的数据结构,提取句子主干,就可以得到索引的本质:索引是数据结构。 索引的分类主键索引(PRIMARYKEY)......