ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Windows消息钩取

2022-03-09 19:03:12  阅读:166  来源: 互联网

标签:NULL DLL Windows 钩子 dll 消息 钩取 DEF KeyHook


1.消息钩子

简单理解:在消息从OS移动到应用程序的时候,我们利用消息钩子在此期间偷看这些信息

钩链:多个相同的消息钩子,按照设置顺序依次调用这些钩子,组成的链条就被称为钩链


消息钩子实现的API:SetwindowsHookEx()

HHOOK SetWindowsHookEx(
    int idHook,                        // hook type
    HOOKpROC lpfn,                // hook procedure
    HINSTANCE hMod,                //hook procedure所属的DLL句柄
    DWORD dwThreadId            //需要挂钩的线程ID,为0时表示为全局钩子(Global Hook)
);


hook proceduce是由操作系统调用的回调函数;安装消息钩子时,钩子过程需要存在于某个DLL内部,且该DLL的示例句柄即为hMod。
若其他进程(如图中所示)发生键盘输入事件,OS就会强制将KeyHook.dll加载到像一个进程的内存,然后调用KeyboardProc()函数。

2.键盘消息钩子实例HookMain.exe

KeyHook.dll中含有钩子API函数(KeyboardProc),通过HookMain.exe加载KeyHook.dll并使用(SetwindowsHookEx)安装键盘钩子(KeyboardProc)

LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
);

运行 HookMain.exe,再运行Notepad,看到KeyHook.dll已经加载其中

3、源代码分析

1. HookMain.cpp

HookMain程序的主要源代码如下所示:

点击查看代码
#include "stdio.h"
#include "conio.h"
#include "windows.h"

#define    DEF_DLL_NAME        "KeyHook.dll"
#define    DEF_HOOKSTART        "HookStart"
#define    DEF_HOOKSTOP        "HookStop"

typedef void (*PFN_HOOKSTART)();
typedef void (*PFN_HOOKSTOP)();

void main()
{
    HMODULE    hDll = NULL;
    PFN_HOOKSTART    HookStart = NULL;
    PFN_HOOKSTOP    HookStop = NULL;
    char    ch = 0;

  // 加载KeyHook.dll
    hDll = LoadLibraryA(DEF_DLL_NAME);
    if( hDll == NULL )
    {
        printf("LoadLibrary(%s) failed!!! [%d]", DEF_DLL_NAME, GetLastError());
        return;
    }

  // 获取导出函数地址
    HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
    HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);

  // 开始钩取
    HookStart();

  // 等待,直到用户输入“q”
    printf("press 'q' to quit!\n");
    while( _getch() != 'q' )    ;

  // 终止钩子
    HookStop();

  // 卸载KeyHook.dll
    FreeLibrary(hDll);
}


KeyHook.dll源代码:

点击查看代码
#include "stdio.h"
#include "windows.h"

#define DEF_PROCESS_NAME        "notepad.exe"

HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
    switch( dwReason )
    {
        case DLL_PROCESS_ATTACH:
            g_hInstance = hinstDLL;
            break;

        case DLL_PROCESS_DETACH:
            break;    
    }

    return TRUE;
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    char szPath[MAX_PATH] = {0,};
    char *p = NULL;

    if( nCode >= 0 )
    {
        // bit 31 : 0 => press, 1 => release
        if( !(lParam & 0x80000000) )    //释放键盘按键时
        {
            GetModuleFileNameA(NULL, szPath, MAX_PATH);
            p = strrchr(szPath, '\\');

      //比较当前进程名称是否为notepad.exe,成立则消息不传递给应用程
            if( !_stricmp(p + 1, DEF_PROCESS_NAME) )
                return 1;
        }
    }

  //如果不是notepad.exe,则调用CallNextHookEx()函数,将消息传递给应用程序
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

#ifdef __cplusplus
extern "C" {
#endif
    __declspec(dllexport) void HookStart()
    {
        g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
    }

    __declspec(dllexport) void HookStop()
    {
        if( g_hHook )
        {
            UnhookWindowsHookEx(g_hHook);
            g_hHook = NULL;
        }
    }
#ifdef __cplusplus
}
#endif


总体上代码相对简单,调用导出函数HookStart()时,SetWindowsHookEx()函数就会将KetyboardProc()添加到键盘钩链。

代码执行流程分析

安装好键盘钩子后,无论在哪个进程中,只要发生了键盘输入事件,OS就会强制将KeyHook.dll注入到进程中,加载了KeyHook.dll的进程,发生键盘事件时会首先调用执行KeyHook.KetyboardProc()。

KetyboardProc()函数中发生键盘输入事件时,会比较当前进程的名称与“notepad.exe”是否相同,相同返回1,终止KetyboardProc()函数,意味着截获并删除了消息,这样键盘消息就不会传递到notepad.exe程序的消息队列。

标签:NULL,DLL,Windows,钩子,dll,消息,钩取,DEF,KeyHook
来源: https://www.cnblogs.com/Azh3n/p/15986544.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有