基于键盘钩子的dota改键(单线程+DLL)MFC实现(源码+总结)
来源:互联网 发布:陕西省广电网络营业厅 编辑:程序博客网 时间:2024/05/18 02:54
呼。。终于可以摒弃网上带广告的改键工具了。。 历经三天,写出自己的dota改键软件最简单版了。 还学习了两个新知识,钩子和动态链接库。下面以一个新手的角度,总结下这三天遇到的大小问题。
一般钩子在什么时刻被调用?
操作系统把消息放进进程的消息队列后, 进程GetMessage()前。
钩子分类?
局部钩子:只能监视本进程内的线程。
远程钩子:远程钩子分为以下两种(两种一般都要DLL注入,极个别不用)
远程单线程钩子:监视单一线程。(魔兽改键。。 我用的就是这个~~)
全局钩子:监视所有线程。
钩子过程函数中,怎么样修改键值?
经测试,不可以修改健值。可能采取了副本复制之类的吧。可以keybd_event产生新消息,并屏蔽原消息。也可以用SendMessage...
貌似还可以用 WH_KEYBOARD_LL 来避免 DLL注入。。以后有心情再研究。备注下:
WH_KEYBOARD WH_KEYBOARD_LL 的区别?
WH_KEYBOARD的钩子过程在GetMessage或PeekMessage要取回一个键盘消息时调用,直接在被监视的线程中执行
WH_KEYBOARD_LL的钩子过程在一个键盘消息被投递到一个线程的消息队列之前调用,这个是向安装钩子的线程发送消息,让安装钩子的线程执行钩子过程,WH_KEYBOARD_LL必须是全局钩子,而且不需要在dll中
附上屏蔽组合键方法 WIN型 ALT型 与 CTRL 型
p = (PKBDLLHOOKSTRUCT) lParam; switch (wParam) { case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: fEatKeystroke = // 屏蔽Win(p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN) || // 屏蔽Alt+Tab ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) || // 屏蔽Alt+Esc ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||// 屏蔽Ctrl+Esc ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0)); break; default: break; }
DLL源码 主要部分:
#include <windows.h>//设置数据段为共享#pragma data_seg(".wzy")HHOOK g_hKeyboard=NULL;static WORD g_KeyNumber[10]={0};int g_lenth=0;#pragma data_seg()#pragma comment( linker,"/section:.wzy,RWS" )LRESULT CALLBACK KeyboardProc( int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information){if(code == HC_ACTION){// 显血功能if( wParam == VK_HOME && (((lParam>>31)&1) == 0) ) //按下HOME键{keybd_event(VK_OEM_4,0,0,0); //就一直按下 [ 键来显血return 1;}if( wParam == VK_END && (((lParam>>31)&1) == 0) ) //按下END键{keybd_event(VK_OEM_4,0,KEYEVENTF_KEYUP,0); //就弹起 [ 键来 结束显血return 1;}if( wParam == g_KeyNumber[0]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD7,0,0,0);keybd_event(VK_NUMPAD7,0,KEYEVENTF_KEYUP,0);return 1;}if( wParam == g_KeyNumber[1]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD8,0,0,0);keybd_event(VK_NUMPAD8,0,KEYEVENTF_KEYUP,0);return 1;}if( wParam == g_KeyNumber[2]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD4,0,0,0);keybd_event(VK_NUMPAD4,0,KEYEVENTF_KEYUP,0);return 1;}if( wParam == g_KeyNumber[3]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD5,0,0,0);keybd_event(VK_NUMPAD5,0,KEYEVENTF_KEYUP,0);return 1;}if( wParam == g_KeyNumber[4]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD1,0,0,0);keybd_event(VK_NUMPAD1,0,KEYEVENTF_KEYUP,0);return 1;}if( wParam == g_KeyNumber[5]){if( ((lParam>>31)&1) == 1) // 如果是弹起,忽略掉return 1;keybd_event(VK_NUMPAD2,0,0,0);keybd_event(VK_NUMPAD2,0,KEYEVENTF_KEYUP,0);return 1;}}return CallNextHookEx(g_hKeyboard,code,wParam,lParam);}_declspec(dllexport) void SetHook(HWND hwnd,WORD KeyNumber[],int lenth){//参数先拷好。for(int i=0;i<lenth;++i)g_KeyNumber[i]=KeyNumber[i];g_lenth = lenth;g_hKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle("KeyboardProc.dll"),GetWindowThreadProcessId( FindWindow("Warcraft III",0),NULL)); }_declspec(dllexport) void DelHook(HWND hwnd){UnhookWindowsHookEx(g_hKeyboard);g_hKeyboard = NULL; //没卸载成功也强制弄成NULL}
对话框部分,主要是一个定时器:
// 增加定时器 判断魔兽是否已经打开void CChangeKeyDlg::OnTimer(UINT nIDEvent) {// TODO: Add your message handler code here and/or call defaultif(nIDEvent==1){if( m_bCheck == FALSE ){if( ::FindWindow("Warcraft III",0) ){m_bCheck = TRUE;WORD modi;UpdateData(TRUE);m_Key7.GetHotKey( KeyNumber[0] , modi);m_Key8.GetHotKey( KeyNumber[1] , modi);m_Key4.GetHotKey( KeyNumber[2] , modi);m_Key5.GetHotKey( KeyNumber[3] , modi);m_Key1.GetHotKey( KeyNumber[4] , modi);m_Key2.GetHotKey( KeyNumber[5] , modi);MessageBox("目标进程开启了");DelHook(m_hWnd);SetHook(m_hWnd,KeyNumber,6); // 一发现目标进程,就安装钩子。}}else{if( ::FindWindow("Warcraft III",0) == 0) {DelHook(m_hWnd);m_bCheck = FALSE;}}}
源码下载地址(DLL版):http://download.csdn.net/detail/a576323437/4613035
- 基于键盘钩子的dota改键(单线程+DLL)MFC实现(源码+总结)
- 基于低级键盘钩子的dota改键(全局+免DLL注入)MFC实现(源码+总结)
- 基于钩子的改键
- MFC4.2实现键盘钩子捕获,基于DLL实现
- MFC4.2实现键盘钩子捕获,基于DLL实现
- 钩子学习:一个键盘线程钩子的实现
- VC++实现监视系统的键盘操作(2) 创建记录键盘动作的全局钩子DLL
- Windows全局钩子dll(键盘)
- Windows全局钩子dll(键盘)
- 键盘钩子的实现
- 键盘钩子的实现
- 基于WH_CBT的键盘钩子
- MFC线程钩子和全局钩子[HOOK DLL]
- 简单魔兽改键的基本原理及基于MFC实现
- 钩子1(线程级的钩子)
- 全局键盘钩子与线程键盘钩子获取键码的不同方式
- VC++实现监视系统的键盘操作 创建记录键盘动作的全局钩子DLL
- VC++实现监视系统的键盘操作(3)调用键盘钩子DLL
- 最长回文串(Longest Palindromic Substring)
- jquery 中查找函数parent ,parents,find和children的一点研究
- woj 1315 高级机密
- UTF8是将Unicode的规定转化为比较省字节的一种存储和传送方式
- IAR在win7上的破解
- 基于键盘钩子的dota改键(单线程+DLL)MFC实现(源码+总结)
- clientdataset--DataSetProvider---uniquery三层cds事件触发顺序
- 项目延期原因及应对之道
- JAVA正则替换字符串的全角、半角标点符号
- Oracle ADF on JBoss
- Bessie Come Home
- poj 3207 Ikki's Story IV - Panda's Trick(2-sat简单应用)
- MIDAS用事件及其触发顺序
- USB信号简介