在吾爱上待了一段时间了,学习了很多东西,感觉无论怎么要为其做点贡献,我水平比较低,如果有不对的地方希望大家指正,或许对一些人会有些帮助。在做逆向破解的时候遇到了钩子,才知道“勾取”是代码逆向中非常重要且有趣的主题。
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>. [C++] 纯文本查看 复制代码 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函数定义 [C++] 纯文本查看 复制代码 LPESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
); wParam指用户按下的键盘按键的虚拟键值,“A”“a”具有完全相同的虚拟键值, 用ToAscii()API函数可以获得实际按下的键盘ASCII值。 ps:键盘记录器(Key Logger)监视或记录用户键盘输入得到程序。 //////////////////////////////////////////////////////////////////////////////////////////////////// //HookMain.cpp [C++] 纯文本查看 复制代码 #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 [C++] 纯文本查看 复制代码 #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)
{
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)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 __cpluslus
}
//#endif
|