Windows 钩子,基本的dll注入

来源:互联网 发布:3306端口入侵教程 编辑:程序博客网 时间:2024/05/16 12:45

Windows操作系统是基于钩子完成的消息传递与用户交互,它以事件驱动的方式运行。每一个窗口都拥有自己的消息队列,当外部设备触发消息时,消息被发送到系统消息队列,再有操作系统安排将消息发送到特定进程上,这即是消息链。

所谓消息钩子,即是在系统将消息发送到用户程序前,提前截获此消息,并进行处理,也可以把它直接发送给用户程序。如:

当键盘(外部设备)发生键盘输入时,WM_KEYBOARD消息被添加到操作系统的消息队列中,再由操作系统将消息取出,判断此消息是哪个程序发生的,然后将这个消息发送到此用户程序中。应用程序有自己的Message Pump,不断从消息队列中取出消息进行处理。

本文使用消息钩子实现简单的消息勾取功能,目标程序为记事本,使用此钩子可以勾取记事本的键盘事件,使记事本中不能接收到键盘输入消息,也就不能像文本框中输入数据。

注意:消息钩子必须写在dll中,并由dll进行函数调用,将钩子回调函数注入目标进程的虚拟内存,这样达到消息勾取的目的,也是最简单的dll注入。


环境介绍:

编译器:gcc version 4.8.1 (tdm64-2)

系统环境: win7 sp1 x64


文件整理: 一个hook.c文件用于将dll注入到目标进程,一个key.c文件用于定义hook回调函数和调用安装钩子、卸载钩子的函数。

/* author : ez date : 2015/4/3 describe : program to inject .dll into target process*/#include <windows.h>#include <stdio.h>#include <conio.h>#define dll_name "hook.dll"#define hookproc "hookproc"#define hookstop "hookstop"typedef void (*phookproc) ();typedef void (*phookstop) ();int  main (int argc, char** argv) {phookproc pstart = 0;phookstop pstop = 0;HMODULE mdu = LoadLibrary (dll_name);if (! mdu) {printf ("load library error!\r\n");exit (0);}pstart = (phookproc) GetProcAddress (mdu, hookproc);pstop  = (phookstop) GetProcAddress (mdu, hookstop);pstart ();printf ("press q to end this program...\r\n");while (_getch () != 'q') ;pstop ();FreeLibrary (mdu);return 0; }

以上文件开启一个控制台,用于调用dll中的安装钩子函数,将钩子安装到所有进程中。

/* author : ez date : 2015/4/3 describe : a dll  that support export function to installand uninstall hook from current process*/#include <stdio.h>#include <windows.h>#define process_name "notepad.exe"HINSTANCE _hinstance = NULL;HHOOK _hhook = NULL;HWND _hwnd = NULL;BOOL WINAPI DllMain (HINSTANCE hinst, DWORD dwreason, LPVOID lpreserved){switch (dwreason) {case DLL_PROCESS_ATTACH:_hinstance = hinst;break;case DLL_PROCESS_DETACH:break;}return TRUE;}LRESULT CALLBACK message_proc (int ncode, WPARAM wparam, LPARAM lparam) {char path [0xFF] = {0, };char* p = NULL;if (! ncode) {if (! (lparam & 0x80000000)) {int path_len = GetModuleFileName (NULL, path, 0xFF);p = strrchr (path, '\\');if (! _stricmp (p + 1, process_name)) {return 1;}}}return CallNextHookEx (_hhook, ncode, wparam, lparam);}#ifdef __cplusplusextern "C" {#endif__declspec (dllexport) void  __stdcall hookproc () {_hhook = SetWindowsHookEx (WH_KEYBOARD, message_proc, _hinstance, 0);}__declspec (dllexport) void __stdcall hookstop () {if (_hhook) {UnhookWindowsHookEx (_hhook);_hhook = NULL;}}#ifdef __cplusplus}#endif

最后编译:

dll 的编译: gcc key.c -shared -o key.dll -Wl,--out-implib,key.o

可执行程序编译: gcc -o hook hook.c


下面简单介绍以上代码调用的Windows API:

1、HMODULE WINAPI LoadLibrary(
    _In_LPCTSTR lpFileName    // file name and path
);

将PE文件加载到当前进程的虚拟内存中,其返回值为进程虚拟内存中加载dll位置的起始位置(我计算机上为8位十六进制整数)。

2、FARPROC GetProcAddress(
   HMODULE hModule,   // module handler
   LPCSTR lpProcName  // func name
);

从加载到虚拟内存中的dll 中查找导出函数,即查找EAT,用函数名查找。

3、HOOK WINAPI SetWindowsHookEx (
 _In_ int idHook,
 _In_ HOOKPROC lpfn,
 _In_ HINSTANCE hMod,
 _In_ DWORD dwThreadId
);

设置windows hook,最后一个参数如果设置为0,则设置到所有的线程中。

4、BOOL WINAPI UnhookWindowsHookEx( __in HHOOK hhk);

卸载windows hook。


可以使用此技术,加载全局的鼠标和键盘钩子,在windows操作系统启动后执行,这样键盘和鼠标都会“无效”。
1 0
原创粉丝点击