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

发布时间 2023-09-26 17:31:44作者: TechNomad

一、动态链接库

库头文件:

#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;
}