List of installed windows hooks List of installed windows hooks windows windows

List of installed windows hooks


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:

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:

  1. Call PsGetCurrentThread and get the ETHREAD structure of the current thread. ETHREAD is an opaque data structure according to the MSDN documentation.
  2. Extract the THREADINFO structure by calling PsGetThreadWin32Thread. Both of them are undocumented.
  3. Extract the DESKTOPINFO.
  4. 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:

  1. Given a thread ID.
  2. Call PsLookupThreadByThreadId and get the ETHREAD structure of the specified thread.
  3. Extract the THREADINFO structure by calling PsGetThreadWin32Thread.
  4. 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_*).

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.


or related question with answer here

But I still haven't found a reliable way to do it.


One evil way would be to hook all of the hooking functions before anything else gets a chance to.