12558网页游戏私服论坛

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

Windows消息钩取

[复制链接]
发表于 2020-8-10 21:14:08 | 显示全部楼层 |阅读模式
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-22 01:32 , Processed in 0.152343 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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