已安装的 Windows 钩子列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8564987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
List of installed windows hooks
提问by lightstep
How to get list of hooks installed globally in Windows (using SetWindowsHookEx API)?
如何获取在 Windows 中全局安装的钩子列表(使用 SetWindowsHookEx API)?
采纳答案by kichik
One evil way would be to hook all of the hooking functions before anything else gets a chance to.
一种邪恶的方法是在其他任何东西有机会之前钩住所有的钩子函数。
回答by Vijay
See
看
Finding hooks Compared to other operations, enumerating the installed hooks is quite easy.
Thread specific hooks are recorded in a win32k per-thread data structure tagged, rather imaginatively, as THREADINFO1. This is essentially an ETHREAD/TEB like structure but one tailored specifically for user and gdi information. One of its members (aphkStart) is a 16 element array of pointers, individually they either point to NULL, or the head of a linked list of HOOK structures. Enumerating the hooks is simply a measure of walking down those chains.
For convenience, and probably so that iteration isn't required to see if any hooks are set, the THREADINFO contains another member, fsHooks, which is a bitfield. If a bit is on, the corresponding index in the hook array is valid. Instead of 33 comparisons (16 for NULL and 17 for a for-loop), telling if there are hooks requires just one, nifty!
Global hooks, which are per desktop2, are also stored in a per-object structure, also imaginatively named (DESKTOPINFO), and are also stored in an array with an accompanying bitfield. Bridging the two is pDeskInfo, a member of THREADINFO which points to its owning DESKTOPINFO.
Despite the bellyaching in the intro, working with all these undocumented structures isn't actually too hard in practice. The Windows 7 symbols for win32k.sys include their layouts, which is nice. The symbols for the Vista/Server 2008 era don't though, this is where the assembly studying comes and saves the day.
Knowing what these structures look like is one thing, getting at them is another…
Having gotten our grubby mitts on them, we find HOOK structures record most of the relevant information themselves:
查找钩子 与其他操作相比,枚举已安装的钩子非常容易。
线程特定的钩子被记录在一个 win32k 每线程数据结构中,标记为 THREADINFO 1。这本质上是一种类似于 ETHREAD/TEB 的结构,但它是专门为用户和 gdi 信息量身定制的。它的一个成员 (aphkStart) 是一个 16 元素的指针数组,它们分别指向 NULL 或 HOOK 结构链表的头部。枚举钩子只是沿着这些链条走下去的一种措施。
为方便起见,并且可能不需要迭代来查看是否设置了任何钩子,THREADINFO 包含另一个成员 fsHooks,它是一个位域。如果某个位打开,则挂钩数组中的相应索引有效。而不是 33 次比较(16 次用于 NULL 和 17 次用于 for 循环),判断是否有钩子只需要一个,漂亮!
每个桌面2 的全局钩子也存储在每个对象的结构中,也被富有想象力地命名为 (DESKTOPINFO),并且还存储在一个带有位域的数组中。将两者连接起来的是 pDeskInfo,它是 THREADINFO 的成员,指向其拥有的 DESKTOPINFO。
尽管在介绍中有腹痛,但在实践中使用所有这些未记录的结构实际上并不太难。win32k.sys 的 Windows 7 符号包括它们的布局,这很好。然而,Vista/Server 2008 时代的符号却没有,这是汇编学习来拯救世界的地方。
知道这些结构是什么样子是一回事,了解它们是另一回事……
戴上脏手套后,我们发现 HOOK 结构本身记录了大部分相关信息:
struct tagHOOK
{
THRDESKHEAD head; // info about the creator
struct tagHOOK* phkNext; // next entry in linked list
int iHook; // WH_ hook type
UINT_PTR offPfn; // RVA to hook function in ihmod library
UINT flags; // HF_ flags (GLOBAL, ANSI)
int ihmod;
THREADINFO* ptiHooked; // the hooked thread
PVOID rpDesk; // saved desktop pointer
ULONG nTimeout :7;
ULONG fLastHookHung :1;
};
You can download the software here
An overview for detecting installed global hooks follows:
- Call PsGetCurrentThread and get the ETHREAD structure of the current thread. ETHREAD is an opaque data structure according to the MSDN documentation.
- Extract the THREADINFO structure by calling PsGetThreadWin32Thread. Both of them are undocumented.
- Extract the DESKTOPINFO.
- There you can a find all the globally installed hooks. They are organized in a array. Each element is a linked list and corresponds to a specific hook (WH_*).
An overview for detecting installed local hooks follows:
- Given a thread ID.
- Call PsLookupThreadByThreadId and get the ETHREAD structure of the specified thread.
- Extract the THREADINFO structure by calling PsGetThreadWin32Thread.
- There you can a find all the locally installed hooks for the specified thread. They are organized in a array. Each element is a linked list and corresponds to a specific hook (WH_*).
检测已安装的全局钩子的概述如下:
- 调用 PsGetCurrentThread 获取当前线程的 ETHREAD 结构。根据 MSDN 文档,ETHREAD 是一种不透明的数据结构。
- 通过调用 PsGetThreadWin32Thread 提取 THREADINFO 结构。他们俩都没有证件。
- 提取桌面信息。
- 在那里你可以找到所有全局安装的钩子。它们被组织成一个数组。每个元素都是一个链表,对应一个特定的钩子(WH_*)。
检测已安装的本地钩子的概述如下:
- 给定一个线程 ID。
- 调用 PsLookupThreadByThreadId 获取指定线程的 ETHREAD 结构。
- 通过调用 PsGetThreadWin32Thread 提取 THREADINFO 结构。
- 在那里你可以找到指定线程的所有本地安装的钩子。它们被组织成一个数组。每个元素都是一个链表,对应一个特定的钩子(WH_*)。
You can see the source here
Plugin for Process Hacker 2 (http://processhacker.sourceforge.net), displays system hooks and able to unhook (right click menu).
Grab the Process Hacker source and compile it, then add HookTools.vcxproj to Plugins.sln. VS 2013 was used. Set your library path in VC++ directories.
Process Hacker 2 插件 ( http://processhacker.sourceforge.net),显示系统挂钩并能够取消挂钩(右键单击菜单)。
获取 Process Hacker 源并编译它,然后将 HookTools.vcxproj 添加到 Plugins.sln。使用了 VS 2013。在 VC++ 目录中设置您的库路径。
or related question with answer here
或相关问题与答案在这里
- Detecting Keyboard Hooks
- https://security.stackexchange.com/questions/17904/what-are-the-methods-to-find-hooked-functions-and-apis
- 检测键盘挂钩
- https://security.stackexchange.com/questions/17904/what-are-the-methods-to-find-hooked-functions-and-apis
But I still haven't found a reliable way to do it.
但是我还没有找到一个可靠的方法来做到这一点。