12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 311|回复: 0

Windows消息钩取

[复制链接]

63

主题

63

帖子

136

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
136
发表于 2021-2-19 17:04:19 | 显示全部楼层 |阅读模式
Windows消息钩取

一、钩子和消息钩子

钩子,英文Hook,泛指偷看或截取信息时所用的手段或工具。
Windows操作系统向用户提供GUI,它是以变乱驱动(Event Driven)方式工作。变乱发生后,OS将事先定义好的消息发送给相应的应用程序,应用程序分析收到的消息后执行相应动作。以敲击键盘为例,
通例Windows消息流:

  • 发生键盘输入变乱,WM_KEYDOWN消息被添加到OS消息队列;
  • OS判断哪个应用程序发生了变乱,从OS消息队列中取出消息,添加到相应应用程序的app消息队列;
  • 应用程序监视自身的消息队列,发现新添加的WM_KEYDOWN消息,调用相应的变乱处置处罚程序举行处置处罚。
附带钩子的信息流:

  • 发生键盘输入变乱,WM_KEYDOWN消息被添加到OS消息队列;
  • OS判断哪个应用程序发生了变乱,从OS消息队列中取出消息,发送给应用程序;
  • 钩子程序截取信息,对消息采取一定的动作(因钩子目标而定);
  • 如钩子程序不拦截消息,消息最终传输给应用程序,此时的消息大概经过了钩子程序的修改。
二、SetWindowsHookEx()

这是一个实现消息钩子的API,其定义如下:
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。
使用SetWindowsHookEx()设置好钩子后,在某个进程中生成指定消息时,OS就会将相关的DLL文件逼迫注入(injection)相应进程,然后调用注册的钩子程序。
三、键盘消息钩取

以下以书上例子举行练习,起首过程原理图如下:

KeyHook.dll文件是一个含有钩子过程(KeyboardProc)的DLL文件,HookMain.exe是最先加载KeyHook.dll并安装键盘钩子的程序。HookMain.exe加载KeyHook.dll后使用SetWindowsHookEx()安装键盘钩子;若其他进程(如图中所示)发生键盘输入变乱,OS就会逼迫将KeyHook.dll加载到像一个进程的内存,然后调用KeyboardProc()函数。
实验:HookMain.exe
关于实验操作部门建议跟随书上走一遍流程,体验Hook的魅力。
四、源代码分析

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);}[/mw_shl_code]### 2. KeyHook.dllKeyHook.dll源代码:[mw_shl_code=cpp,true]#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 __cplusplusextern "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()添加到键盘钩链。
3. 代码执行流程分析

安装好键盘钩子后,无论在哪个进程中,只要发生了键盘输入变乱,OS就会逼迫将KeyHook.dll注入到进程中,加载了KeyHook.dll的进程,发生键盘变乱时会起首调用执行KeyHook.KetyboardProc()。
KetyboardProc()函数中发生键盘输入变乱时,会比力当前进程的名称与“notepad.exe”是否相同,相同返回1,终止KetyboardProc()函数,意味着截获并删除了消息,这样键盘消息就不会传递到notepad.exe程序的消息队列。
五、调试

使用OD打开HookMain.exe文件:

1. 查找核心代码

我们关心的是核心的键盘钩取部门的代码,如何查找核心代码?

  • 逐步跟踪(除非迫不得已!)
  • 检索相关API
  • 检索相关字符串
我们已经知道程序的功能,会在控制台显示字符串“press ‘q’ to quit!”,以是先查抄程序导入的字符串(Search for -All referencen text strings):

地址40104d处引用了要查找的字符串,双击跳转:

来到main函数处。
2. 调试main函数

在401000处下断,开始调试,了解main函数中主要的代码流。401006地址处调用LoadLibraryA(Keyhook.dll),然后由40104b地址处的CALL EBX指令调用KeyHook.HookStart()函数。跟进检察:

这里的代码是被加载到HookMain.exe进程中的KeyHook.dll的HookStart()函数,第一句就是调用SetWindowsHookExW()函数,在举行参数入栈操作后,我们可以在栈中看到函数的4个参数值。
参考

《逆向工程核心原理》



来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-5-20 00:30 , Processed in 0.084960 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表