您的位置 首页 装修

setwindowhookex

setwindowhookexsetwindowhookex茵蒂克丝如何创建一个窗口手动创建窗口的流程实际代码安装钩子(Installhook)钩子简介SetWindowsH

setwindowhookex

setwindowhookex

茵蒂克丝如何创建一个窗口手动创建窗口的流程实际代码安装钩子 (Install hook)钩子简介SetWindowsHookEx 函数设置监听【键盘】消息设置监听【鼠标】消息如何创建一个窗口

另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口。

那么,为什么讲到 hook(钩子)的时候要去创建窗口呢?其实这个问题说起来也不复杂,简单点说,按博主这样写不用写DLL也不用资源文件,实际上是把问题简化了一些。通常 hook 是用来监听自己窗口上的键盘和鼠标输入的,监听全局的通常是设置一些全局的热键(如QQ的 Ctrl+Alt+Z 调出QQ窗口),这些常见的功能也都是要依托窗口才能存在。所以我们先来简单说下手动建立一个窗口的流程。

手动创建窗口的流程设置注册窗口结构体使用【窗口结构体】注册窗口创建窗口显示窗口窗口过程处理消息循环实际代码

这里不会详细讲这个,有感兴趣的可以去追博主的 SDK教程 或者去搜 杨中科的《C语言也能干大事》

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081#include <windows.h>// 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:setwindowhookexPostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // 更多详细都可以去百度的 http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = "myWindowClass";// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT("窗口标题"), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 6. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}

因为是比较死的形式,以上代码大家混个脸熟,大概知道各个部分的作用就行了,博主也从来没有专门记过。

安装钩子 (Install hook)简介

窗口建好了之后就要开始转到我们的正题了,首先我们需要明确的是,这个钩子(hook)到底是什么,那么博主这里也不做太书面的解释留下几个链接:

百度百科:hook
MSDN: Hooks
博客园: Beginning HOOK

各位可以多多参考,那么博主说下自己的理解:

windows 系统中的【hook 机制】,就类似于一个【消息过滤网】,如果我们向操作系统申请并成功对某个窗口安装了一个【hook】指定了【回调函数】,那么这个【回调函数】也就相当于我们人为对这个窗口添加了一个【消息过滤网】。此时当 windows 操作系统要对这个窗口发送任何消息的时候(例如按键、鼠标点击等消息)操作系统会先调用我们在【消息过滤网】中设置的【回调函数】去接受、处理、过滤等等,当然如果你在【回调函数】中拿到了数据却没有继续传递给窗口的话,就相当于拦截了这些消息。

打个简单的比方,如果你在系统全局安装了一个【键盘消息】的钩子,并且在其指定的【回调函数】中没有把这个键盘消息继续传递给系统上的窗口,那么你的所有【键盘消息】都被这个【hook】也就我们挂在这个【消息过滤网】上的【回调函数】给拦截了,这也意味着你的键盘会失灵。

SetWindowsHookEx 函数

那么 SetWindowsHookEx 函数就是我们用来在 windows 操作系统上安装钩子的函数,我们简单来看一下这个函数的原型:

123456HHOOK WINAPI SetWindowsHookEx(_In_ int idHook, // 安装的钩子类型_In_ HOOKPROC lpfn, // 处理消息的回调函数_In_ HINSTANCE hMod, // 当前实例句柄_In_ DWORD dwThreadId // 线程ID);

钩子类型有很多种,本页中留的大部分链接上都有讲到这里就不废话了,关于 hMod(当前实例句柄)和 dwThreadId(线程ID)之间的一些小九九博主这里也不多说,各位可以到下方的链接中去看看,博主这里就举一个容易实现的实例。

百度百科: SetWindowsHookEx
MSDN: SetWindowsHookEx

设置监听【键盘】消息

PKBDLLHOOKSTRUCT 是 WH_KEYBOARD_LL 方式中用来接收消息的结构体,大家可以到 WindUser.h 中多逛逛。

我们监听键盘的时候主要用的是该结构体的 vkCode(value code)和 scanCode 这两个字段。即键盘的【值码】和【扫描码】那么为什么判断一个按键要分成两个部分呢,原因是因为世界上的键盘有很多种,不同国家、不同厂商生产的键盘甚,至同一个键盘上【同样的键】不同的地方按下都可能会有差异。vkCode 是常见的一般都是公用的键盘值,而 scanCode 扫描码则是用来辅助区分的一个一个参数,例如同样是按下 ctrl 键,他们的 vkCode 是相同的但是 scanCode 却不同。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <windows.h>HHOOK myhook; // 保存当前钩子句柄/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { char text[50], data[20]; // 输出字符串const char *info = NULL; // 类型字符指针PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam; // 获取按键消息HDC hdc; // 画图设备句柄// 判断是否收到键盘消息if (nCode >= 0){// 判断消息类型if (wParam == WM_KEYDOWN) info = "普通按鍵抬起";else if (wParam == WM_KEYUP) info = "普通按鍵按下";else if (wParam == WM_SYSKEYDOWN) info = "系統按鍵抬起";else if (wParam == WM_SYSKEYUP) info = "系統按鍵按下";// 初始化数组ZeroMemory(text, sizeof(text));ZeroMemory(data, sizeof(data));// 拼装字符串wsprintf(text, "%s - 键盘码 [%04d], 扫描码 [%04d] ", info, p->vkCode, p->scanCode);wsprintf(data, "按鍵目测为: %c ", p->vkCode);// 此处调用 GDI 画图函数来将截取到的内容画在窗口上hdc = GetDC(画图的窗口句柄); // 获取要画图的设备句柄TextOut(hdc, 10, 10, text, strlen(text)); // 在窗口上画文字 TextOut(hdc, 10, 30, data, strlen(data)); // 参数分别是 目标设备, x坐标, y坐标, 字符串内容, 字符串长度ReleaseDC(画图的窗口句柄, hdc); // 释放设备句柄}// 将消息继续往下传递return CallNextHookEx(myhook, nCode, wParam, lParam);} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){/* 其他代码 */// 设置键盘全局监听myhook = SetWindowsHookEx( WH_KEYBOARD_LL, // 监听类型【键盘消息】KeyboardProc, // 处理函数hInstance, // 当前实例句柄0 // 监听线程ID(NULL为全局监听)); // 判断是否成功if(myhook == NULL){ wsprintf(text, "键盘监听失败!error : %d n", GetLastError());MessageBox(hwnd, text, TEXT("错误"), MB_OK);}/* 其他代码 */}

注:其中在输出按键的时候,直接用 %c 输出了 p->vkCode 部分,这个实际上不是很准确。

顺便提一句,各位也不要用这个功能去做什么坏事,比如去监听QQ窗口的键盘消息然后偷到密码盗别人号之类的, 博主已经试过了 这个本身有带防护的,用户在输密码的时候,会有干扰的键盘消息也一起冒出来所以没那么简单能到到别人输的密码。至于写个程序去拦截别人的键盘还有鼠标消息让别人的电脑不能用的情况,这个确实很容易做到,而且貌似杀毒软件都没办法防,只能自己在自己的电脑上留个后门,怎么写后门?后面的网络编程会说这个。

键盘监听完整代码:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135#include <windows.h>HWND hgWnd;HHOOK myhook;/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;const char *info = NULL;char text[50], data[20];PAINTSTRUCT ps;HDC hdc;if (nCode >= 0){if (wParam == WM_KEYDOWN) info = "普通按鍵抬起";else if (wParam == WM_KEYUP) info = "普通按鍵按下";else if (wParam == WM_SYSKEYDOWN) info = "系統按鍵抬起";else if (wParam == WM_SYSKEYUP) info = "系統按鍵按下";ZeroMemory(text, sizeof(text));ZeroMemory(data, sizeof(data));wsprintf(text, "%s - 键盘码 [%04d], 扫描码 [%04d] ", info, p->vkCode, p->scanCode);wsprintf(data, "按鍵目測為: %c ", p->vkCode);hdc = GetDC(hgWnd); TextOut(hdc, 10, 10, text, strlen(text));TextOut(hdc, 10, 30, data, strlen(data));ReleaseDC(hgWnd,hdc);}return CallNextHookEx(myhook, nCode, wParam, lParam);} // 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ hgWnd = hwnd;switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = "myWindowClass";// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT("窗口标题"), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 设置键盘全局监听myhook = SetWindowsHookEx( WH_KEYBOARD_LL, // 监听类型【键盘】KeyboardProc, // 处理函数hInstance, // 当前实例句柄0 // 监听窗口句柄(NULL为全局监听)); if(myhook == NULL){ wsprintf(text, "键盘监听失败!error : %d n", GetLastError());MessageBox(hwnd, text, TEXT("错误"), MB_OK);}// 5. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}运行截图

键盘监听

设置监听【鼠标】消息

与键盘监听类似,各位直接看代码:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148#include <windows.h>HWND hgWnd;HHOOK myhook;/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSLLHOOKSTRUCT p = (LPMSLLHOOKSTRUCT)lParam;POINT pt = p->pt;DWORD mouseData = p->mouseData;const char *info = NULL;char text[60], pData[50], mData[50];PAINTSTRUCT ps;HDC hdc;if (nCode >= 0){if (wParam == WM_MOUSEMOVE) info = "鼠标移动    ";else if(wParam == WM_LBUTTONDOWN) info = "鼠标【左键】按下";else if(wParam == WM_LBUTTONUP) info = "鼠标【左键】抬起";else if(wParam == WM_LBUTTONDBLCLK) info = "鼠标【左键】双击";else if(wParam == WM_RBUTTONDOWN) info = "鼠标【右键】按下";else if(wParam == WM_RBUTTONUP) info = "鼠标【右键】抬起";else if(wParam == WM_RBUTTONDBLCLK) info = "鼠标【右键】双击";else if(wParam == WM_MBUTTONDOWN) info = "鼠标【滚轮】按下";else if(wParam == WM_MBUTTONUP) info = "鼠标【滚轮】抬起";else if(wParam == WM_MBUTTONDBLCLK) info = "鼠标【滚轮】双击";else if(wParam == WM_MOUSEWHEEL) info = "鼠标【滚轮】滚动";ZeroMemory(text, sizeof(text));ZeroMemory(pData, sizeof(pData));ZeroMemory(mData, sizeof(mData));wsprintf( text, "当前状态: %10s ", info);wsprintf(pData, "0x%x - X: [%04d], Y: [%04d] ", wParam, pt.x, pt.y);wsprintf(mData, "附带数据: %16u ", mouseData);hdc = GetDC(hgWnd); TextOut(hdc, 10, 10, text, strlen(text));TextOut(hdc, 10, 30, pData, strlen(pData));TextOut(hdc, 10, 50, mData, strlen(mData));ReleaseDC(hgWnd,hdc);}return CallNextHookEx(myhook, nCode, wParam, lParam);} // 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ hgWnd = hwnd;switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = "myWindowClass";// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT("窗口标题"), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 设置鼠标全局监听myhook = SetWindowsHookEx( WH_MOUSE_LL, // 监听类型【鼠标】MouseProc, // 处理函数hInstance, // 当前实例句柄0 // 监听窗口句柄(NULL为全局监听)); if(myhook == NULL){ wsprintf(text, "键盘监听失败!error : %d n", GetLastError());MessageBox(hwnd, text, TEXT("错误"), MB_OK);}// 5. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}

MouseHook

上一讲: Windows API 教程(六) 动态链接库
下一讲: Windows API 教程(八) 注册快捷键

Advertisements

</div></div><div id="jp-post-flair" ><div ><div ><h3 >分享:</h3><div ><ul><li ><iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" title="Twitter Tweet Button" src="https://platform.twitter.com/widgets/tweet_button.c5b006ac082bc92aa829181b9ce63af1.zh-cn.html#dnt=false&amp;id=twitter-widget-0&amp;lang=zh-cn&amp;original_referer=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;related=wordpressdotcom&amp;size=m&amp;text=Windows%20API%20%E6%95%99%E7%A8%8B%EF%BC%88%E4%B8%83%EF%BC%89%20hook%20%E9%92%A9%E5%AD%90%E7%9B%91%E5%90%AC&amp;time=1530069532892&amp;type=share&amp;url=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;via=wordpressdotcom" data-url="https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/"></iframe></li><li ><div data-href="https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/" data-layout="button_count" fb-xfbml-state="rendered" fb-iframe-plugin-query="app_id=249643311490&amp;container_width=0&amp;href=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;layout=button_count&amp;locale=zh_CN&amp;sdk=joey"><span ><iframe name="f7afa5127141dc" width="1000px" height="1000px" frameborder="0" allowtransparency="true" allowfullscreen="true" scrolling="no" allow="encrypted-media" title="fb:share_button Facebook Social Plugin" src="https://www.facebook.com/v2.3/plugins/share_button.php?app_id=249643311490&amp;channel=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter%2Fr%2FxaOI6zd9HW9.js%3Fversion%3D42%23cb%3Df2fa769af17575c%26domain%3Dlellansin.wordpress.com%26origin%3Dhttps%253A%252F%252Flellansin.wordpress.com%252Ff2570795c9ce9b4%26relation%3Dparent.parent&amp;container_width=0&amp;href=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;layout=button_count&amp;locale=zh_CN&amp;sdk=joey" ></iframe></span></div></li><li ><div ><div data-annotation="bubble" data-href="https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/" id="___plusone_0" ><iframe ng-non-bindable="" frameborder="0" hspace="0" marginheight="0" marginwidth="0" scrolling="no" tabindex="0" vspace="0" width="100%" id="I0_1530069532478" name="I0_1530069532478" src="https://apis.google.com/se/0/_/+1/fastbutton?usegapi=1&amp;annotation=bubble&amp;origin=https%3A%2F%2Flellansin.wordpress.com&amp;url=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25E6%2595%2599%25E7%25A8%258B%25EF%25BC%2588%25E4%25B8%2583%25EF%25BC%2589-hook-%25E9%2592%25A9%25E5%25AD%2590%25E7%259B%2591%25E5%2590%25AC%25EF%25BC%2588%25E7%25BC%2596%25E5%2586%2599%25E4%25B8%25AD%25EF%25BC%2589%2F&amp;gsrc=3p&amp;jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.zh_CN.XFQo0FTB5VE.O%2Fm%3D__features__%2Fam%3DwQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCNKHGrrnuBI733L0s-bjVihwBhTYg#_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe%2C_renderstart%2Concircled%2Cdrefresh%2Cerefresh&amp;id=I0_1530069532478&amp;_gfid=I0_1530069532478&amp;parent=https%3A%2F%2Flellansin.wordpress.com&amp;pfname=&amp;rpctoken=29653332" data-gapiattached="true" title="G+"></iframe></div></div></li><li ></li></ul></div></div></div>

在“C/C++”中

<a href=”https://lellansin.wordpress.com/2013/07/13/windows-api教程(五)-线程编程/” title=”Windows API教程(五) 线程编程

经过了一段时间的思考,以及一阵子的忙碌时期之后觉得“进程通信”放在进程编程之后有点太早了。而且,有些…” rel=”nofollow” data-origin=”1305″ data-position=”1″>Windows API教程(五) 线程编程在“C/C++”中

<a href=”https://lellansin.wordpress.com/2014/07/28/windows-gdi-教程(一)-一个简单的绘图程序/” title=”Windows GDI 教程(一) 一个简单的绘图程序

常见的图形编程库,除了 GDI 外还有 GDI+、OpenGL、DirectX等等,GDI 是其中最…” rel=”nofollow” data-origin=”1305″ data-position=”2″>Windows GDI 教程(一) 一个简单的绘图程序在“C/C++”中

setwindowhookex

setwindowhookex

上的键盘和鼠标输入的,监听全局的通常是设置一些全局的热键(如QQ的 Ctrl+Alt+Z 调出QQ窗口),这些常见的功能也都是要依托窗口才能存在。所以我们先来简单说下手动建立一个窗口的流程。手动创建窗口的流程设置注册窗口结构体使用【窗口结构体】注册窗口创建窗口显示窗口窗口过程处理消息循环实际代码这里不会详细讲这个,有感兴趣的可以去追博主的 S

setwindowhookex

WindowsAPI教程(七)hook钩子监听 setwindowhookex

DK教程 或者去搜 杨中科的《C语言也能干大事》123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081#include <windows.h>// 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // 更多详细都可以去百度的 http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = “myWindowClass”;// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT(“窗口注册失败!”), TEXT(“错误”), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT(“窗口标题”), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT(“窗口创建失败”), TEXT(“错误”),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 6. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}因为是比较死的形式,以上代码大家混个脸熟,大概知道各个部分的作用就行了,博主也从来没有专门记过。安装钩子 (Install hook)简介窗口建好了之后就要开始转到我们的正题了,首先我们需要明确的是,这个钩子(hook)到底是什么,那么博主这里也不做太书面的解释留下几个链接:百度百科:hookMSDN: Hooks博客园: Beginning HOOK各位可以多多参考,那么博主说下自己的理解:windows 系统中的【hook 机制】,就类似于一个【消息过滤网】,如果我们向操作系统申请并成功对某个窗口安装了一个【hook】指定了【回调函数】,那么这个【回调函数】也就相当于我们人为对这个窗口添加了一个【消息过滤网】。此时当 windows 操作系统要对这个窗口发送任何消

setwindowhookex

); TextOut(hdc, 10, 10, text, strlen(text));TextOut(hdc, 10, 30, pData, strlen(pData));TextOut(hdc, 10, 50, mData, strlen(mData));ReleaseDC(hgWnd,hdc);}return CallNextHookEx(myhook, nCode, wParam, lParam);} // 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ hgWnd = hwnd;switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAP

setwindowhookex WindowsAPI教程(七)hook钩子监听

I WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = “myWindowClass”;// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT(“窗口注册失败!”), TEXT(“错误”), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT(“窗口标题”), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT(“窗口创建失败”), TEXT(“错误”),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 设置鼠标全局监听myhook = SetWindowsHookEx( WH_MOUSE_LL, // 监听类型【鼠标】MouseProc, // 处理函数hInstance, // 当前实例句柄0 // 监听窗口句柄(NULL为全局监听)); if(myhook == NULL){ wsprintf(text, “键盘监听失败!error : %d n”, GetLastError());MessageBox(hwnd, text, TEXT(“错误”), MB_OK);}// 5. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}上一讲: Windows API 教程(六) 动态链接库下一讲: Windows API 教程(八) 注册快捷键 Advertisements</div></div><div id=”jp-post-flair” ><div ><div ><h3 >分享:</h3><div ><ul><li ><iframe id=”twitter-widget-0″ scrolling=”no” frameborder=”0″ allowtransparency=”true” title=”Twitter Tweet Button” src=”https://platform.twitter.com/widgets/tweet_button.c5b006ac082bc92aa829181b9ce63af1.zh-cn.html#dnt=false&amp;id=twitter-widget-0&amp;lang=zh-cn&amp;original_referer=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;related=wordpressdotcom&amp;size=m&amp;text=Windows%20API%20%E6%95%99%E7%A8%8B%EF%BC%88%E4%B8%83%EF%BC%89%20hook%20%E9%92%A9%E5%AD%90%E7%9B%91%E5%90%AC&amp;time=1530069532892&amp;type=share&amp;url=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;via=wordpressdotcom” data-url=”https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/”></iframe></li><li ><div data-href=”https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/” data-layout=”button_count” fb-xfbml-state=”rendered” fb-iframe-plugin-query=”app_id=249643311490&amp;container_width=0&amp;href=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;layout=button_count&amp;locale=zh_CN&amp;sdk=joey”><span ><iframe name=”f7afa5127141dc” width=”1000px” height=”1000px” frameborder=”0″ allowtransparency=”true” allowfullscreen=”true” scrolling=”no” allow=”encrypted-media” title=”fb:share_button Facebook Social Plugin” src=”https://www.facebook.com/v2.3/plugins/share_button.php?app_id=249643311490&amp;channel=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter%2Fr%2FxaOI6zd9HW9.js%3Fversion%3D42%23cb%3Df2fa769af17575c%26domain%3Dlellansin.wordpress.com%26origin%3Dhttps%253A%252F%252Flellansin.wordpress.com%252Ff2570795c9ce9b4%26relation%3Dparent.parent&amp;container_width=0&amp;href=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25e6%2595%2599%25e7%25a8%258b%25ef%25bc%2588%25e4%25b8%2583%25ef%25bc%2589-hook-%25e9%2592%25a9%25e5%25ad%2590%25e7%259b%2591%25e5%2590%25ac%25ef%25bc%2588%25e7%25bc%2596%25e5%2586%2599%25e4%25b8%25ad%25ef%25bc%2589%2F&amp;layout=button_count&amp;locale=zh_CN&amp;sdk=joey” ></iframe></span></div></li><li ><div ><div data-annotation=”bubble” data-href=”https://lellansin.wordpress.com/2013/08/15/windows-api-%e6%95%99%e7%a8%8b%ef%bc%88%e4%b8%83%ef%bc%89-hook-%e9%92%a9%e5%ad%90%e7%9b%91%e5%90%ac%ef%bc%88%e7%bc%96%e5%86%99%e4%b8%ad%ef%bc%89/” id=”___plusone_0″ ><iframe ng-non-bindable=”” frameborder=”0″ hspace=”0″ marginheight=”0″ marginwidth=”0″ scrolling=”no” tabindex=”0″ vspace=”0″ width=”100%” id=”I0_1530069532478″ name=”I0_1530069532478″ src=”https://apis.google.com/se/0/_/+1/fastbutton?usegapi=1&amp;annotation=bubble&amp;origin=https%3A%2F%2Flellansin.wordpress.com&amp;url=https%3A%2F%2Flellansin.wordpress.com%2F2013%2F08%2F15%2Fwindows-api-%25E6%2595%2599%25E7%25A8%258B%25EF%25BC%2588%25E4%25B8%2583%25EF%25BC%2589-hook-%25E9%2592%25A9%25E5%25AD%2590%25E7%259B%2591%25E5%2590%25AC%25EF%25BC%2588%25E7%25BC%2596%25E5%2586%2599%25E4%25B8%25AD%25EF%25BC%2589%2F&amp;gsrc=3p&amp;jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.zh_CN.XFQo0FTB5VE.O%2Fm%3D__features__%2Fam%3DwQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCNKHGrrnuBI733L0s-bjVihwBhTYg#_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe%2C_renderstart%2Concircled%2Cdrefresh%2Cerefresh&amp;id=I0_1530069532478&amp;_gfid=I0_1530069532478&amp;parent=https%3A%2F%2Flellansin.wordpress.com&amp;pfname=&amp;rpctoken=29653332″ data-gapiattached=”true” title=”G+”></iframe></div></div>&lt

setwindowhookex

setwindowhookex

息的时候(例如按键、鼠标点击等消息)操作系统会先调用我们在【消息过滤网】中设置的【回调函数】去接受、处理、过滤等等,当然如果你在【回调函数】中拿到了数据却没有继续传递给窗口的话,就相当于拦截了这些消息。打个简单的比方,如果你在系统全局安装了一个【键盘消息】的钩子,并且在其指定的【回调函数】中没有把这个键盘消息继续传递给系统上的窗口,那么你的所有【键盘消息】都被这个【hook】也就我们挂在这个【消息过滤网】上的【回调函数】给拦截了,这也意味着你的键盘会失灵。SetWindowsHookEx 函数那么 SetWindowsHookEx 函数就是我们用来在 windows 操作系统上安装钩子的函数,我们简单来看一下这个函数的原型:123456HHOOK WINAPI SetWindowsHookEx(_In_ int idHook, // 安装的钩子类型_In_ HOOKPROC lpfn, // 处理消息的回调函数_In_ HINSTANCE hMod, // 当前实例句柄_In_ DWORD dwThreadId // 线程ID);钩子类型有很多种,本页中留的大部分链接上都有讲到这里就不废话了,关于 hMod(当前实例句柄)和 dwThreadId(线程ID)之间的一些小九九博主这里也不多说,各位可以到下方的链接中去看看,博主这里就举一个容易实现的实例。百度百科: SetWindowsHookExMSDN: SetWindowsHookEx设置监听【键盘】消息PKBDLLHOOKSTRUCT 是 WH_KEYBOARD_LL 方式中用来接收消息的结构体,大家可以到 WindUser.h 中多逛逛。我们监听键盘的时候主要用的是该结构体的 vkCode(value code)和 scanCode 这两个字段。即键盘的【值码】和【扫描码】那么为什么判断一个按键要分成两个部分呢,原因是因为世界上的键盘有很多种,不同国家、不同厂商生产的键盘甚,至同一个键盘上【同样的键】不同的地方按下都可能会有差异。vkCode 是常见的一般都是公用的键盘值,而 scanCode 扫描码则是用来辅助区分的一个一个参数,例如同样是按下 ctrl 键,他们的 vkCode 是相同的但是 scanCode 却不同。12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <windows.h>HHOOK myhook; // 保存当前钩子句柄/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { char text[50], data[20]; // 输出字符串const char *info = NULL; // 类型字符指针PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam; // 获取按键消息HDC hdc; // 画图设备句柄// 判断是否收到键盘消息if (nCode >= 0){// 判断消息类型if (wParam == WM_KEYDOWN) info = “普通按鍵抬起”;else if (wParam == WM_KEYUP) info = “普通按鍵按下”;else if (wParam == WM_SYSKEYDOWN) info = “系統按鍵抬起”;else if (wParam == WM_SYSKEYUP) info = “系統按鍵按下”;// 初始化数组ZeroMemory(text, sizeof(text));ZeroMemory(data, sizeof(data));// 拼装字符串wsprintf(text, “%s – 键盘码 [%04d], 扫描码 [%04d] “, info, p->vkCode, p->scanCode);wsprintf(data, “按鍵目测为: %c “, p->vkCode);// 此处调用 GDI 画图函数来将截取到的内容画在窗口上hdc = GetDC(画图的窗口句柄); // 获取要画图的设备句柄TextOut(hdc, 10, 10, text, strlen(text)); // 在窗口上画文字 TextOut(hdc, 10, 30, data, strlen(data)); // 参数分别是 目标设备, x坐标, y坐标, 字符串内容, 字符串长度ReleaseDC(画图的窗口句柄, hdc); // 释放设备句柄}// 将消息继续往下传递return CallNextHookEx(myhook, nCode, wParam, lParam);} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){/* 其他代码 */// 设置键盘全局监听myhook = SetWindowsHookEx( WH_KEYBOARD_LL, // 监听类型【键盘消息】KeyboardProc, // 处理函数hInstance, // 当前实例句柄0 // 监听线程ID(NULL为全局监听)); // 判断是否成功if(myhook == NULL){ wsprintf(text, “键盘监听失败!error : %d n”, GetLastError());MessageBox(hwnd, text, TEXT(“错误”), MB_OK);}/* 其他代码 */}注:其中在输出按键的时候,直接用 %c 输出了 p->vkCode 部分,这个实际上不是很准确。顺便提一句,各位也不要用这个功能去做什么坏事,比如去监听QQ窗口的键盘消息然后偷到密码盗别人号之类的, 博主已经试过了 这个本身有带防护的,用户在输密码的时候,会有干扰的键盘消息也一起冒出来所以没那么简单能到到别人输的密码。至于写个程序去拦截别人的键盘还有鼠标消息让别人的电脑不能用的情况,这个确实很容易做到,而且貌似杀毒软件都没办法防,只能自己在自己的电脑上留个后门,怎么写后门?后面的网络编程会说这个。键盘监听完整代码:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135#include <windows.h>HWND hgWnd;HHOOK myhook;/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;const char *info = NULL;char text[50], data[20];PAINTSTRUCT ps;HDC hdc;if (nCode >= 0){if (wParam == WM_KEYDOWN) info = “普通按鍵抬起”;else if (wParam == WM_KEYUP) info = “普通按鍵按下”;else if (wParam == WM_SYSKEYDOWN) info = “系統按鍵抬起”;else if (wParam == WM_SYSKEYUP) info = “系統按鍵按下”;ZeroMemory(text, sizeof(text));ZeroMemory(data, sizeof(data));wsprintf(text, “%s – 键盘码 [%04d], 扫描码 [%04d] “, info, p->vkCode, p->scanCode);wsprintf(data, “按鍵目測為: %c “, p->vkCode);hdc = GetDC(hgWnd); TextOut(hdc, 10, 10, text, strlen(text));TextOut(hdc, 10, 30, data, strlen(data));ReleaseDC(hgWnd,hdc);}return CallNextHookEx(myhook, nCode, wParam, lParam);} // 5. 窗口过程处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ hgWnd = hwnd;switch(msg){case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc; // http://baike.baidu.com/view/1750396.htmHWND hwnd;MSG Msg;char text[30];const char szClassName[] = “myWindowClass”;// 1. 设置注册窗口结构体wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小wc.style = 0; // 窗口的样式wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数wc.hInstance = hInstance; // 本模块的实例句柄wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄wc.lpszMenuName = NULL; // 指向菜单的指针wc.lpszClassName = szClassName; // 指向类名称的指针wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标// 2. 使用【窗口结构体】注册窗口if(!RegisterClassEx(&wc)){MessageBox(NULL, TEXT(“窗口注册失败!”), TEXT(“错误”), MB_ICONEXCLAMATION | MB_OK);return 0;}// 3. 创建窗口hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // 窗口的扩展风格szClassName, // 指向注册类名的指针TEXT(“窗口标题”), // 指向窗口名称的指针WS_OVERLAPPEDWINDOW, // 窗口风格CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高NULL, // 父窗口的句柄NULL, // 菜单的句柄hInstance, // 应用程序实例的句柄NULL // 指向窗口的创建数据);if(hwnd == NULL){MessageBox(NULL, TEXT(“窗口创建失败”), TEXT(“错误”),MB_ICONEXCLAMATION | MB_OK);return 0;}// 4. 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 设置键盘全局监听myhook = SetWindowsHookEx( WH_KEYBOARD_LL, // 监听类型【键盘】KeyboardProc, // 处理函数hInstance, // 当前实例句柄0 // 监听窗口句柄(NULL为全局监听)); if(myhook == NULL){ wsprintf(text, “键盘监听失败!error : %d n”, GetLastError());MessageBox(hwnd, text, TEXT(“错误”), MB_OK);}// 5. 消息循环while(GetMessage(&Msg, NULL, 0, 0) > 0){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}运行截图设置监听【鼠标】消息与键盘监听类似,各位直接看代码:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148#include <windows.h>HWND hgWnd;HHOOK myhook;/**************************************************************** WH_KEYBOARD hook procedure 鍵盤钩子处理过程****************************************************************/LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSLLHOOKSTRUCT p = (LPMSLLHOOKSTRUCT)lParam;POINT pt = p->pt;DWORD mouseData = p->mouseData;const char *info = NULL;char text[60], pData[50], mData[50];PAINTSTRUCT ps;HDC hdc;if (nCode >= 0){if (wParam == WM_MOUSEMOVE) info = “鼠标移动    ”;else if(wParam == WM_LBUTTONDOWN) info = “鼠标【左键】按下”;else if(wParam == WM_LBUTTONUP) info = “鼠标【左键】抬起”;else if(wParam == WM_LBUTTONDBLCLK) info = “鼠标【左键】双击”;else if(wParam == WM_RBUTTONDOWN) info = “鼠标【右键】按下”;else if(wParam == WM_RBUTTONUP) info = “鼠标【右键】抬起”;else if(wParam == WM_RBUTTONDBLCLK) info = “鼠标【右键】双击”;else if(wParam == WM_MBUTTONDOWN) info = “鼠标【滚轮】按下”;else if(wParam == WM_MBUTTONUP) info = “鼠标【滚轮】抬起”;else if(wParam == WM_MBUTTONDBLCLK) info = “鼠标【滚轮】双击”;else if(wParam == WM_MOUSEWHEEL) info = “鼠标【滚轮】滚动”;ZeroMemory(text, sizeof(text));ZeroMemory(pData, sizeof(pData));ZeroMemory(mData, sizeof(mData));wsprintf( text, “当前状态: %10s “, info);wsprintf(pData, “0x%x – X: [%04d], Y: [%04d] “, wParam, pt.x, pt.y);wsprintf(mData, “附带数据: %16u “, mouseData);hdc = GetDC(hgWnd

WindowsAPI教程(七)hook钩子监听【setwindowhookex】

setwindowhookex

;/li><li ></li></ul></div></div></div>在“C/C++”中<a href=”https://lellansin.wordpress.com/2013/07/13/windows-api教程(五)-线程编程/” title=”Windows API教程(五) 线程编程经过了一段时间的思考,以及一阵子的忙碌时期之后觉得“进程通信”放在进程编程之后有点太早了。而且,有些…” rel=”nofollow” data-origin=”1305″ data-position=”1″>Windows API教程(五) 线程编程在“C/C++”中<a href=”https://lellansin.wordpress.com/2014/07/28/windows-gdi-教程(一)-一个简单的绘图程序/” title=”Windows GDI 教程(一) 一个简单的绘图程序常见的图形编程库,除了 GDI 外还有 GDI+、OpenGL、DirectX等等,GDI 是其中最…” rel=”nofollow” data-origin=”1305″ data-position=”2″>Windows GDI 教程(一) 一个简单的绘图程序在“C/C++”中

setwindowhookex

WindowsAPI教程(七)hook钩子监听

茵蒂克丝如何创建一个窗口手动创建窗口的流程实际代码安装钩子 (Install hook)钩子简介SetWindowsHookEx 函数设置监听【键盘】消息设置监听【鼠标】消息如何创建一个窗口另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口。那么,为什么讲到 hook(钩子)的时候要去创建窗口呢?其实这个问题说起来也不复杂,简单点说,按博主这样写不用写DLL也不用资源文件,实际上是把问题简化了一些。通常 hook 是用来监听自己窗口

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。

作者: 026xm

没有了

已是最早文章

为您推荐

dns故障

dns故障

dns故障dns故障昨天15时许,国内部分用户发现无法访问.com域名网站,腾讯、百度、京东、优酷等大批网站无法正常访问。域名服务商称,”断网”的原因与DNS故障有关

马化腾微博

马化腾微博

马化腾微博马化腾微博对于微博是否将互通,马化腾认为,Facebook、Google+是不是能互通呢?现在互通还不现实。曹国伟则表示,同意马化腾的观点,并称在一个地方发就可以了。(

96106

96106

9610696106北京电召平台96106推出飞嘀打车APP(搜索结果截图)【z607.com报道】8月18日消息,今日有媒体报道,北京统一电召出租车平台96106推

firefoxchina

firefoxchina

firefoxchinafirefoxchina最近Mozilla开发者社区发布的一篇博客《Firefox:您可能还不知道的46项功能》引起了很多Web开发人员

比亚迪宋6座

比亚迪宋6座

比亚迪宋6座比亚迪宋6座如此前预告,4月17日,比亚迪官方宣布,宋MAX6座版正式上市,共计提供7款车型,售价区间为7.99万-12.99万元;与此同时,7座版增加2款高配车型。

返回顶部