Windows消息钩子个别都很熟习了。它的用途良多,耳熟能详的就有——利用键盘钩子获取目标进程的键盘输入,从而取得各类密码以到达不可告人的目标。友人想让他的软件不被别人的全局钩子监督,有没有措施实现呢·谜底是确定的,不过缺陷也是有的。
首先简单看看全局钩子如何注入别的进程。
消息钩子是由Win32子系统供给,其中心局部通过NtUserSetWindowsHookEx为用户提供了设置消息钩子的系统服务,用户通过它注册全局钩子。当系统获取某些事件,好比用户按键,键盘driver将扫描码等传入win32k的KeyEvent处理函数,处置函数判断有无相应hook,有则callhook。此时,系统获得Hook对象信息,若目的进程不装载对应的Dll,则装载之应用KeUserModeCallback“调用”用户例程,它与Apc调用不同,它是仿造中止返回环境,其调用是“即时”性质的。
进入用户态的KiUserCallbackDispatcher后,KiUserCallbackDispatcher依据传递的数据获取所需调用的函数、参数等,随后调用。针对上面的例子,为装载hook dll,得到调用的是LoadLibraryExW,随落后入LdrLoadDll,装载结束后返回,后面的步骤就不叙述了。
从上面的探讨咱们可以得出一个最简略的防侵入计划:在加载hook dll之前hook相应api使得加载失败,不外有一个缺点:体系并不会由于一次的失败而废弃,每次有新闻发生欲call hook时系统都会试图在你的过程加载dll,这对机能有些微影响,不过应当感到不到。剩下一个问题就是不是所有的LoadLibraryExW都应拦阻,这个轻易解决,比方断定返回地址。下面给出一个例子片段,能够增加一些判定使得某些容许加载的hook dll被加载。
这里hook api使用了微软的detours库,可自行修正。
以下内容为程序代码:
typedef HMODULE (__stdcall .LOADLIB)( LPCWSTR lpwLibFileName, HANDLE hFile, DWORD dwFlags);
extern "C" { DETOUR_TRAMPOLINE(HMODULE __stdcall Real_LoadLibraryExW( LPCWSTR lpwLibFileName, HANDLE hFile, DWORD dwFlags), LoadLibraryExW); }
ULONG user32 0;
HMODULE __stdcall Mine_LoadLibraryExW( LPCWSTR lpwLibFileName, HANDLE hFile, DWORD dwFlags) { ULONG addr;
_asm mov eax, .ebp+4. _asm mov addr, eax
if ((user32 0xFFFF0000) (addr 0xFFFF0000)) { return 0; }
HMODULE res (LOADLIB(Real_LoadLibraryExW)) ( lpwLibFileName, hFile, dwFlags);
return res; }
BOOL ProcessAttach() { DetourFunctionWithTrampoline((PBYTE)Real_LoadLibraryExW, (PBYTE)Mine_LoadLibraryExW); return TRUE; }
BOOL ProcessDetach() { DetourRemove((PBYTE)Real_LoadLibraryExW, (PBYTE)Mine_LoadLibraryExW); return TRUE; }
CAnti_HookApp::CAnti_HookApp() //在应用用户界面服务前调用ProcessAttach { user32 (ULONG)GetModuleHandle("User32.dll"; ProcessAttach(); }