RSS Feed

关于系统钩子的一些问题

2008-12-16 by bborn

上个周末闲来无事
想来做了一个computer-based training (CBT)全局系统钩子(global hook)
本来想着挺简单的事情
没想到其中碰到了很多问题
现在小小总结一下
包括我遇到的问题,想到的原因及找到的解决办法
我的系统环境是Vista Ultimate sp1, Visual Studio 2005 sp1

一般来说,做一个全局钩子,需要dll
恩 差不多是这样
不过对于鼠标键盘钩子是例外
我们还是老老实实的做dll吧
调试发现只能收到自己程序的消息
奇了怪了, 全局钩子变成了本地钩子,为什么

做一个全局钩子
需要做一个共享内存
我想主要是为了保存一个窗口句柄
以便接收消息
当然也可以不这么做
像这篇文章Using Window Messages to Implement Global System Hooks in C#

SetProp(GetDesktopWindow(), “WILSON_HOOK_HWND_CBT”, destination);
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), “WILSON_HOOK_HWND_CBT”);

不过我实在不知道他干嘛要这么费劲

我是使用#pragma data_seg()来跨进程保存数据的
使用时要注意,变量要初始化

开始的时候,我是在dll里的钩子的回调里写trace
这实在是个低级错误
后来改到主窗口的消息处理函数里
发现在调试的时候只能收到自己程序和vc的消息
想想难道在调式的时候,调式的程序挂在vc下面
而收不到别人的消息?(后来发现这个推断是错误的)
不管怎样 这次程序基本上可以工作了

做完这些工作 以为万事大吉

于是浏览了一下刚才提到的那个文章后面的讨论
后来发现有人提了这样的问题

problem with IE7 in protect mode LuxNw 23:58 31 May ’07

Hi,
i try your app on Vista with IE7 in protect mode, and it doesn’t work fine…
your app doesn’t detect IE7 message.
If i turn off protect mode all work fine.
Have you any idea how to solve the problem?

我一试,果然!!!

开始的想法,认为可能是IE7的保护模式不允许全局钩子的挂载
搜索了一下
msdn上这么解释的 了解并运行 Internet Explorer 保护模式

保护模式建立于新的完整性机制之上,以限制对安全对象(如,具有更高完整性级别的进程、文件和注册表项)的写入权限。 当以保护模式运行时,Internet Explorer 是一个低完整性进程;因此它无法获得对用户配置文件或系统位置中文件和注册表项的写入权限。

低完整性进程只能写入已经分配低完整性强制标签的文件夹、文件和注册表项。 因此,以“保护模式”运行的 Internet Explorer 和扩展程序只能写入低完整性位置,例如,新的低完整性“Internet 临时文件”文件夹、历史记录文件夹、Cookie 文件夹、收藏夹文件夹和 Windows 临时文件文件夹。 有关完整列表,请参阅常见问题(FAQ)章节内容。

此外,Windows Vista 投入市场时“保护模式”进程以低完整性级别运行,这样可防止其将特定的窗口消息发送到完整性更高的进程。

问题的原因找到了
怎么解决了?
继续看msdn

允许应用程序接收 Window 消息
如上文所述,UIPI 会阻止窗口消息从低完整性进程发送至具有更高完整性的进程。 如果运行于“保护模式”下的扩展程序需要通过窗口消息与提升的应用程序通信,则可以从提升的应用程序调用 ChangeWindowMessageFilter() 以传送特定的消息。

注意 如果要与“保护模式”通信,最佳的做法是以低完整性运行应用程序。 否则,请只使用进程间通信 (IPC) 的安全形式,例如远程过程调用 (RPC),在“保护模式”和完整性较高的进程之间进行通信。

不过我的sdk中并不包含这个函数
所以需要通过load User32.dll 来调用

这样基本上就好用了
这时候发现在vc中调式也没问题了
原来是这样…

在这些过程中 发现关于WH_CBT钩子的资料比较少
而我在思考其中问题的时候也费了不少脑子
虽然事后发现都不是我想的原因 :(
所以才想把这些记录下来
如果有不正确的地方 请指正 :)

随便看看


2 条评论 »

  1. 李浩 说道:

    奋斗,你好,我需要用c#写一个全局钩子捕获目标窗口比如word、记事本等从剪贴板获取数据(即,粘贴)时的消息。我正在看Using Window Messages to Implement Global System Hooks in C#这篇文章,也在研究这位作者写的程序,因为我刚刚学钩子,还不清楚这位作者的方法能否解决我的问题。我在网上看到许多人说c#只可以做低层次的鼠标和键盘全局钩子,其它的不可以,而c++却是可以做到的。但是我对c++不熟,当然如果c#无法解决我的问题的话,我也只好去使用c++做全局钩子。
    你可以给我提供一些帮助吗?这是我的邮箱sbwdlihao@gmail.com,非常感谢!

  2. bborn 说道:

    读一下 Windows核心编程 或者 google: windows hook , 得到的收获应该比问我多的多

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">