I'm just about finished with my own sniffer code, which I think will be more efficient and more effective than the ones previously posted. As soon as I iron out a couple issues and document it properly, I'll post it. I write all my code with MSVC++, so it'll be up to some other motivated individual to adapt it to some other compiler should there be any incompatibilities.
The code is a DLL, injected into the system with SetWindowsHookEx using RUNDLL32.EXE. The DLL can be renamed at will, and since it is activated and deactivated with RUNDLL32.EXE, it will be horrendously difficult to detect. Since it lives in the address space of EQGAME, it doesn't suffer any "elevated priviledges" blocks the other sniffers have to circumvent or workaround in NT. It also doesn't require the toolhelp libraries, and is not subject to timing issues like the sleep() problems people have seen.
Some of the concerns I've had about the sniffers posted so far is the use of .conf files which could be scanned for, or easy-to-detect string sequences in a binary. So I've pretty-much eliminated those easy-to-see sequences and file-based configs, and went with command-line params to the RUNDLL32.EXE instead. Stealth naming of the DLL is also important so even if Verant enumerated the DLL's attached to its process space, they'd be unable to determine whether the DLL was a system DLL, a 3rd party legitimate DLL, or a hack DLL...they'd have to do a more exhaustive check on the binary's signature.
SetWindowsHookEx() is used by a lot of utilities, Logitech's mouse driver being an example of one. Their LGMOUSHK.DLL injects itself into the system this way and intercepts mouse events with the WH_MOUSE hook to provide mouse button enhancements. It is impossible to enumerate these hooks via API, or to detect when hooks are present in your application's message pumps.
Maggotboy