首页 > 编程语言 >Win32编程之全局钩子(十七)

Win32编程之全局钩子(十七)

时间:2023-09-26 17:33:58浏览次数:47  
标签:wParam break hModule 钩子 lParam 编程 Win32 TEXT hHook

一、动态链接库

库头文件:

#pragma once

#include <Windows.h>

extern "C" {
	__declspec(dllexport) void __stdcall SetHookVal(HHOOK hookVal);
	__declspec(dllexport) LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam);
}

库源文件: 

#include "HookMsg.h"
#include <Windows.h>

/* 共享数据段 */
#pragma data_seg("shared")
HHOOK g_hHook = 0;
#pragma data_seg()

#pragma comment(linker, "/section:shared,rws")

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        OutputDebugString(TEXT("HookMsg DLL_PROCESS_ATTACH"));
        break;
    case DLL_THREAD_ATTACH:
        OutputDebugString(TEXT("HookMsg DLL_THREAD_ATTACH"));
        break;
    case DLL_THREAD_DETACH:
        OutputDebugString(TEXT("HookMsg DLL_THREAD_DETACH"));
        break;
    case DLL_PROCESS_DETACH:
        OutputDebugString(TEXT("HookMsg DLL_PROCESS_DETACH"));
        break;
    }
    return TRUE;
}

void __stdcall SetHookVal(HHOOK hookVal)
{
    g_hHook = hookVal;
}

LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code < 0) {
        return CallNextHookEx(g_hHook, code, wParam, lParam);
    }
    
    switch (wParam) {
    case WM_LBUTTONDOWN: {
        OutputDebugString(TEXT("HookMsg MouseProc WM_LBUTTONDOWN"));
        PMOUSEHOOKSTRUCT pInfo = (PMOUSEHOOKSTRUCT)lParam;
        WCHAR buff[30] = { 0 };
        wsprintf(buff, TEXT("HookMsg (%d, %d)"), pInfo->pt.x, pInfo->pt.y);
        OutputDebugString(buff);
    }
    default:
        break;
    }

    return CallNextHookEx(g_hHook, code, wParam, lParam);
}

二、全局钩子调用  

typedef LRESULT (CALLBACK *MOUSE_PROC) (int code, WPARAM wParam, LPARAM lParam);
typedef void (WINAPI *HOOK_VAL) (HHOOK hookVal);

void SetWinHook() {
    OutputDebugString(TEXT("hookApp Load Library"));
    g_hModule = LoadLibrary(TEXT("HookMsg.dll"));
    if (g_hModule != NULL) {
        MOUSE_PROC pMouse = (MOUSE_PROC)GetProcAddress(g_hModule, "MouseProc");
        HOOK_VAL pSetHook = (HOOK_VAL)GetProcAddress(g_hModule, "SetHookVal");
        HHOOK hHook = SetWindowsHookEx(WH_MOUSE, pMouse, (HINSTANCE)g_hModule, 0);
        pSetHook(hHook);
    }
}

 三、挂钩指定线程 

HHOOK g_hHook = 0;
HMODULE g_hModule = NULL;

typedef LRESULT(CALLBACK* MOUSE_PROC) (int code, WPARAM wParam, LPARAM lParam);
typedef void (WINAPI* HOOK_VAL) (HHOOK hookVal);

DWORD GetMainThreadIdFormName(const WCHAR* szName) {
    DWORD idThread = 0; //主线程ID
    DWORD idProcess = 0; //进程ID

    PROCESSENTRY32 pe; //进程信息
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //获取系统进程列表快照
    if (Process32First(hSnapshot, &pe)) {
        //返回系统中第一个进程的信息
        do {
            if (_wcsicmp(pe.szExeFile, szName) == 0) {
                idProcess = pe.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &pe)); //下一个进程
    }
    CloseHandle(hSnapshot); //删除快照

    if (idProcess == 0) {
        return 0;
    }

    //获取进程的主线程ID
    THREADENTRY32 te;
    te.dwSize = sizeof(THREADENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); //系统所有线程快照
    if (Thread32First(hSnapshot, &te)) {
        //第一个线程
        do {
            if (idProcess == te.th32OwnerProcessID) {
                idThread = te.th32ThreadID;
                break;
            }
        } while (Thread32Next(hSnapshot, &te)); //下一个线程   
    }

    CloseHandle(hSnapshot); //删除快照
    return idThread;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE: {
        OutputDebugString(TEXT("hookApp Load Library"));
        //获取指定进程的主线程ID
        DWORD ulThreadId = GetMainThreadIdFormName(TEXT("notepad.exe"));
        g_hModule = LoadLibrary(TEXT("HookMsg.dll"));
        if (g_hModule != NULL) {
            MOUSE_PROC pMouse = (MOUSE_PROC)GetProcAddress(g_hModule, "MouseProc");
            HOOK_VAL pSetHook = (HOOK_VAL)GetProcAddress(g_hModule, "SetHookVal");
            HHOOK hHook = SetWindowsHookEx(WH_MOUSE, pMouse, (HINSTANCE)g_hModule, ulThreadId);
            pSetHook(hHook);
        }

        break;
    }
    case WM_DESTROY: {
        if (g_hHook != 0) {
            UnhookWindowsHookEx(g_hHook);
            FreeLibrary(g_hModule);
        }
        PostQuitMessage(0);
        break;
    }               
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

标签:wParam,break,hModule,钩子,lParam,编程,Win32,TEXT,hHook
From: https://www.cnblogs.com/TechNomad/p/17730740.html

相关文章

  • Linux shell编程学习笔记1:关于shell的前世今生
    一、什么是Shell?Shell英文单词的原意是“外壳”,在计算机领域专指在操作系统(OperatingSystem)外层,提供用户界面(UserInterface)的程序,主要负责将用户的命令(Command)转化为操作系统可识别的指令(Instruction)。二、UnixshellUnix诞生于1969年,是最早提供shell,从而将操作系统和用户界面......
  • 在小公司编程是一种什么样的体验?
    前言知乎上有一个提问:在小公司编程是一种什么样的体验?↓↓↓今天,我们就这个话题,一起来做个讨论。这里有没有曾经待过小公司或者现在正窝在小公司的程序员?如果有,这个问题相信你是最有发言权的。一个软件产品从前期的调研到中途的开发直至最后的发布环节,不知道整个链......
  • Vue-进阶,404页面控制及路由钩子
    路由转发传参我们在使用vue-router时,可能会在Vue实例对象中,写一些方法使用路由的方式完成跳转,其实这种方式也是可以进行转发的this.$router.push("/main"); 如上,可以使用字符串拼接,把参数拼接在后面,然后转发,完成参数传递this.$router.push("/main/"+this.form.username);......
  • 软件工程(结对编程项目)
    Github作业链接成员:刘鸿杰林程星软件工程计科21级4班作业要求作业3要求连接作业目标实现四则运算题目的命令行程序PSP表格PSP2.1ersonalSoftwareProcessStages预估耗时(分钟)实际耗时(分钟)Planning计划1010·Estimate·估计这个任务需......
  • 如何在低代码平台中应用可视化编程
    可视化编程,亦即可视化程序设计:以“所见即所得”的编程思想为原则,力图实现编程工作的可视化,即随时可以看到结果,程序与结果的调整同步。可视化编程的理念来源于可视化技术,它指的是一种把计算机程序中的文本指令转换为用户可以完全理解和操作的图形化界面。传统上,用户通过文本编程来......
  • Spring 04 SpringAOP 切面编程
    Aop:面向切面,在不修改代码的前提下对方法进行增强 pom.xml<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version>......
  • Windows网络编程(一)
    一、WSAStartup函数WSAStartup是Windows套接字API中的一个函数,它用于初始化Winsock库,这是Windows中用于网络编程的库。使用Winsock,您可以创建客户端和服务器应用程序,以便它们能够通过网络进行通信。函数的原型如下:intWSAStartup(WORDwVersionRequested,......
  • win32汇编-80386的内存分页机制
     读者可以注意到,在实模式下寻址的时候,“段寄存器+偏移地址”经过转换计算以后得到的地址是“物理地址”,也就是在物理内存中的实际地址。而保护模式下,“段选择器+偏移地址”转换后的地址被称为“线性地址”而不是“物理地址”。那么,线性地址就是物理地址吗?答案可能是“是”,也可......
  • 编程笔记·开篇
    2023年9月,经过一夜的辗转难眠,最后在一个清晨,我坐上了久违的地铁......
  • 多线程实现实例-简单的聊天小程序TCP编程尝试
    运用TCP编程,实现一个从客户端到服务端多线程聊天的功能。 获取信息线程的代码Get.javapackagecom.xyq.HW;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.net.Socket;publicclassGetextendsThread{......