Feeling

    三人行,必有我师焉

   ::  :: 新随笔 :: 联系 ::  :: 管理 ::
  52 随笔 :: 0 文章 :: 172 评论 :: 0 Trackbacks

2007年12月7日 #

SWT-Extension这个项目做了很久,但一直都没有realease,只是个人做着玩玩,很重要的一个原因是对Windows System Hook的机制没有能够很好地实现出来。Hook本身不算是很难的技术,在C++,C#里都能够很容易的实现,为什么运用Java就那么困难呢?

首先当然主要还是我个人对C++并不在行了,其次就是Java和C++交互的问题了。要想通过C++把数据传给Java,就要通过JNI标准的接口来实现,也就是要通过 JNIENV 来实现,但是HookProc 这个CallBack 是给系统进程调用的,不是给你Java调用的,你说系统进程调用了 HookProc 之后,没法把这个事件传递给Java,那么还有一个方法,用Java不间断的轮循Hook里的数据,这倒是能实现,网上也有一个老外的例子,但不好的地方就是当我系统没工作的时候,你Java还在那儿轮循我干嘛?这不是浪费资源吗?所以呢,这解铃还需系铃人,系统的事件还得让系统来通知你才好。在Java里,有一个IO阻塞,比如当调用System.in.read()的时候,系统就是等待你的输入,如果你不输入,系统就一直等着不工作。还有线程,有wait方法,非要等着其他的线程通过notify把你唤醒你才能工作。在C++里也有这么一套机制:CreateEvent 和WaitForSingleObject,也就是说我先创建一个事件,然后将这个事件置于未激活状态,让它一直等待,将线程阻塞住,当HookProc被系统进程调用的时候,就将这个事件激活,通知Java程序你可以开始干活了,干完活以后再次被阻塞,直到这个Hook被uninstall掉。当然这其中还有一些 C++ 代码的细节性问题,比如怎么让不同的进程共享同一个事件,这里要说明的就是不同的进程可以共享同一个事件,但是不能共享同一个事件句柄,同一个事件,在不同的进程里有不同的句柄,句柄是不能跨进程的。 

我个人认为Hook应当是SWT-Extension里一个很重要的组成部分,SWT本身只能实现线程钩子,对于系统级的钩子无能为力。因为系统机钩子需要实现数据共享操作,还需要DLL入口句柄,这些我已都在SWT-Extension中实现了。唯一让我遗憾的是没有办法实现日志钩子,这是一个很有用的钩子,可以用来记入当前用户行为的操作,然后重新演示,我想如果做自动化测试这个会很有用,或者给游戏软件练功什么的,呵呵。之所以不能实现是因为这个钩子很特别,它要的不是DLL的句柄,而是应用程序的句柄,这没有办法从Java程序里获得,我试过javaw.exe,但是也不行,会导致系统假死。以后有时间在研究吧。

做完Hook,终于可以松一口气,发一个小小的realease了,剩下的就是document工作要做了,一个枯燥无味的工作,就当练习一下英语好了。

这里发一个Hook的截图:




没有了标题栏的Eclipse
最新的Build和代码也可以在 http://feeling.sf.net 上下载了。
posted @ 2007-12-07 15:08 三人行,必有我师焉 阅读(893) | 评论 (14)编辑 收藏