简明的Detours Hook教程
来源:互联网 发布:淘宝双十一大红包 编辑:程序博客网 时间:2024/06/05 02:48
tag: Hook, Detours,Windows,CreateRemoteThread,MessageBox
前言
项目开发中需要跟踪其它程序的API调用情况。但厂商又无源码提供,故只好自己动手去Trace了。
Google/Baidu了许久,也搜集了很多代码。也经过实验和测试,总结了本文供大家参考。
本文针对Windows Hook技术在编程中的应用进行讨论,并着重对应用比较广泛的Detours使用方法做了阐述。
Hook/钩子的基本原理
Windows 钩子的本质是一段用以处理系统消息的程序,通过系统调用,将其挂入到系统。钩子的种类有很多,每一种钩子负责截获并处理相应的消息。钩子机制允许应用程序截获并处理发往指定窗口的消息或特定事件,其监视的窗口即可以是本进程内的也可以是由其他进程所创建的。在特定的消息发出,并在到达目的窗口之前,钩子程序先行截获此消息并得到对其的控制权。此时在钩子函数中就可以对截获的消息进行各种修改处理,甚至强行终止该消息的继续传递。
Detours库是Microsoft研究院的一个开发库,最新版本为3.0。它可以拦截任意的API调用,拦截代码是在动态运行时加载的,替换目标API最前面的几条指令,使其无条件的跳转到用户提供的拦截函数。
Hook/钩子的安装与卸载
开始代码了,真的非常easy!以Hook MessageBox为例:
准备工作:Detours lib/h files, VC++ 6/2005/2008....
A. 封装Dll.
1. VC++向导创建一个MFC Dll项目,一路向西,默认缺省选项。
改写DllMain如下:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:::OutputDebugString( "DLL_PROCESS_ATTACH\n" );InstallHook();break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;case DLL_PROCESS_DETACH:::OutputDebugString( "DLL_PROCESS_DETACH\n" );UnInstallHook();break;}return TRUE;}
2. 增加InstallHook/UnInstallHook函数:
////////////BOOL APIENTRY InstallHook(){DetourTransactionBegin();DetourUpdateThread( GetCurrentThread() );g_pOldMessageBoxA = DetourFindFunction( "User32.dll","MessageBoxA" );g_pOldMessageBoxW = DetourFindFunction( "User32.dll","MessageBoxW" );DetourAttach( &g_pOldMessageBoxA, MyMessageBoxA );DetourAttach( &g_pOldMessageBoxW, MyMessageBoxW );LONG ret = DetourTransactionCommit();return ret==NO_ERROR;}////////////BOOL APIENTRY UnInstallHook(){DetourTransactionBegin();DetourUpdateThread( GetCurrentThread() );DetourDetach(&g_pOldMessageBoxA, MyMessageBoxA);DetourDetach(&g_pOldMessageBoxW, MyMessageBoxW);LONG ret=DetourTransactionCommit();return ret==NO_ERROR;}
注意上文代码中的MessageBoxA和MessageBoxW字样,这就是我们所要拦截的API函数咯。至于为何不是MessageBox,却是MessageBoxA和MessageBoxW这样的怪样子,新手们去看看Windows核心编程啦。
3. 我们的拦截函数
typedef int (WINAPI *PfuncMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);typedef int (WINAPI *PfuncMessageBoxW)( HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);////////////int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType){return ((PfuncMessageBoxA)g_pOldMessageBoxA)(hWnd, "Hook This!","My hook",uType);}////////////int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption,UINT uType){return ((PfuncMessageBoxW)g_pOldMessageBoxW)(hWnd,L"Hook This!",L"My hook",uType);}
此例中我们只是更改了MessageBox的Text和Caption。
4. 记得保留原版的MessageBox。
build一下,发现错误:g_pOldMessageBoxA还未定义? 还记得上文中的
g_pOldMessageBoxA = DetourFindFunction( "User32.dll","MessageBoxA" );
这个函数指针需要保留。
PVOID g_pOldMessageBoxW=NULL;
PVOID g_pOldMessageBoxA=NULL;
DLL就万事大吉,只欠东风了。
B. 注射器
所谓的注射器,就是东风了,要不然光有dll也用,还需要用注射器把我们的dll注入到肉鸡中。老生常谈,还是老一套的CreateRemoteThread。这个方法是如此的简单而且优雅。
HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE, pid);if (hProcess != NULL){TRACE( "InjectHook \n" );HANDLE hThread;char szLibPath [_MAX_PATH];void* pLibRemote = 0;DWORD hLibModule = 0;HMODULE hKernel32 = ::GetModuleHandle("Kernel32");if( !::GetSystemDirectory(szLibPath, _MAX_PATH))return;strcat(szLibPath, "C:\\windows\\HookDll.dll");pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );if( pLibRemote == NULL )return;::WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath,sizeof(szLibPath),NULL);hThread = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,"LoadLibraryA"), pLibRemote, 0, NULL );if( hThread != NULL ){::WaitForSingleObject( hThread, INFINITE );::GetExitCodeThread( hThread, &hLibModule );::CloseHandle( hThread );}}
解释一下以上的szLibPath, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread。
这是远线程,不是在你的进程里,而szLibPath指向的是你的进程里的数据,到了目标进程,这个指针都不知道指向哪儿去了,同样CreateRemoteThread中的pfnStartAddr这个地址上的代码到了目标进程里也不知道是什么了,不知道是不是你想要的LoadLibraryA了。但是,问题总是可以解决的,Windows有些很强大的API函数,他们可以在目标进程里分配内存,可以将你的进程中的数据拷贝到目标进程中。
抛砖引玉。欢迎臭鸡蛋!
- 简明的Detours Hook教程
- MS的detours库 API hook
- Detours 使用方法 HOOK API
- 比Detours更给力的Hook库
- 使用x86的detours库编写hook-dll
- 运用Detours库hook API
- 运用Detours库hook API
- 运用Detours库hook API
- Detours API HOOK快速入门
- 运用Detours库hook API
- 运用Detours库hook API
- 运用Detours库hook API
- 运用Detours库hook API
- 使用 detours 做 api hook
- 运用Detours库hook API
- Win API HOOK 之 Detours
- 运用Detours库hook API
- Hook :Microsoft Detours 2.1简介
- Linux内核proc文件系统的冰山一角 源自对/proc/net/dev文件中各网卡参数的疑问
- ubuntu 11.10安装及配置
- jqGrid与Struts2的结合应用(六) —— 使用colModel设置查询功能
- RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播 RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播
- CSS3系列教程:边框半径和圆角
- 简明的Detours Hook教程
- Windows编程模型
- U盘装系统中bios怎么设置USB启动(图文教程)
- [转]史上最快消息内核——ZeroMQ .
- HDU 2057 A+B again 16进制数输入输出
- Away3d之SkyBox
- 配置centos6.3(更新中)
- 3D编程-绘制任意多边形
- BitmapFactory.Options.inSampleSize 的用法