bess 发表于 2014-11-15 19:18

Windows消息勾取

   在吾爱上待了一段时间了,学习了很多东西,感觉无论怎么要为其做点贡献,我水平比较低,如果有不对的地方希望大家指正,或许对一些人会有些帮助。在做逆向破解的时候遇到了钩子,才知道“勾取”是代码逆向中非常重要且有趣的主题。


1>.钩子(HOOK)
延伸意思就是“偷看或截取信息时所用的手段或工具”。


2>.消息钩子      windows操作系统向用户提高GUI(图形用户界面),是以事件驱动的方式工作的。      什么是事件(Event),在操作系统中,移动鼠标都是事件,借助键盘、鼠标选择菜单、按钮等都是。      敲击键盘时,消息会从OS移动到应用程序,所谓的消息钩子就是在此期间进行偷看这些信息。       例子:键盘消息
[*]发生键盘输入事件时,WM_KEYBOWN消息就会别添加到【OS message queue】消息队列
[*]OS判断哪个应用程序中发生了事件,然后就从【OS message queue】取出消息,添加到相应的应用程序的【application message queue】中。
[*]应用程序会监视自身的【application message queue】,发现新添加VM_KEYBOWN消息后,就会调用相应的事件去处理。
         OS消息队列与应用程序消息队列之间存在一条“钩链”,在键盘消息钩子函数的内部,除了可以查看消息之外,还可以修改消息本身,而且还能对消息实施拦截,阻止消息传递。      tips:最具代表行的是MS Visual Studio中提供的SPY++,它是一个功能非常强大的消息勾取程序,能够查看操作系统中来往的所有消息
3>.SetWndowsHookEx()

HHOOK SetWindowsHookEx(

    int idHook,    //hook类型   参数为0时,则安装全局钩子,会影响所有进程

    HOOKPROC lpfn,//hook过程

    HINSTANCE hMod,//hook过程所属的DLL句柄

    DWORD dwThreadId    //想要挂载的线程ID

);“钩子过程”是由操作系统调用的回调函数,安装消息钩子是,“钩子”过程需要存在于某个DLL内部,切该DLL的事例句柄即hMod。ps:使用SetWindowsHookEx设置好的钩子之后,在某个进程中生成指定的消息时,操作系统会将相关的DLL文件强制注入相应进程,然后调用注册的“钩子”过程。
4.键盘消息勾取练习KeyHook.dll文件是一个含有钩子过程(KeyboardPro)的DLL文件,HookMain.exe是最先加载keyHook.dll并安装键盘钩子程序。其他进程中发生键盘输入事件,OS就会强制KeyHook.dll加载相应的进程的内存,然后调用KeyboardProc函数.keyboardProc函数定义LPESULT CALLBACK KeyboardProc(

         int code,

         WPARAM wParam,

         LPARAM lParam

);wParam指用户按下的键盘按键的虚拟键值,“A”“a”具有完全相同的虚拟键值,用ToAscii()API函数可以获得实际按下的键盘ASCII值。ps:键盘记录器(Key Logger)监视或记录用户键盘输入得到程序。//////////////////////////////////////////////////////////////////////////////////////////////////////HookMain.cpp#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_HOOKSTAR)();

typedef void(*PFN_HOOKSTOP)();



void main()

{

HMODULE hDll = NULL;

PFN_HOOKSTAR HookStart = NULL;

PFN_HOOKSTOP HookStop = NULL;

char ch=0;



//加载KeyHook.dll

hDll = LoadLibraryA(DEF_DLL_NAME);



//获取导出函数地址

HookStart=(PFN_HOOKSTAR)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.cpp#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 = {0,};

char *p = NULL;



if(nCode = 0)

{

if(!(lParam&0x80000000) )//释放键盘按键时

{

GetModuleFileNameA(NULL,szPath,MAX_PATH);

p = strrchr(szPath,'\\');

//比较当前进程名称,若为notepad.exe,则消息不回传递给应用程序(或下一个钩子

if(!_stricmp(p+1,DEF_PROCESS_NAME))

return 1;

}

}

return CallNextHookEx(g_hHook,nCode,wParam,lParam);

}



//DLL

//#ifdef __cplusplus

extern"C"

{

//#endif

__declspec(dllexport)voidHookStart()

{

g_hHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,g_hInstance,0);

}

__declspec(dllexport)voidHookStop()

{

if(g_hHook)

{

UnhookWindowsHookEx(g_hHook);

g_hHook = NULL;

}

}

//#ifdef __cpluslus

}

//#endif

小洲 发表于 2014-11-15 19:32

这是什么东西

bess 发表于 2014-11-15 19:36

小洲 发表于 2014-11-15 19:32
这是什么东西

怎么了,{:1_937:}消息钩子,后面给出的代码,是个例子,是勾取notepad.exe里面输入的内容

mygod123 发表于 2014-11-15 19:45

这是什么东西

lhpm641 发表于 2014-11-15 20:33

长知识了。谢谢

风恋残影 发表于 2014-11-15 20:51

zxdhh 发表于 2014-11-15 21:09

楼主继续加油!!{:301_1000:}

bess 发表于 2014-11-15 21:30

zxdhh 发表于 2014-11-15 21:09
楼主继续加油!!

谢谢支持!我会把学到的和大家分享,希望大家不要嫌弃

佐少love 发表于 2015-2-3 16:48

问下你写的钩子测试了吗?
为什么我把你发的代码复制过来,在运行的时候老是卡死?
我这个代码我在《软件调试》里面看过,按照书上说的编写,老是程序会卡死!
页: [1]
查看完整版本: Windows消息勾取