Feeling

    三人行,必有我师焉

   ::  :: 新随笔 :: 联系 ::  :: 管理 ::
  185 随笔 :: 0 文章 :: 392 评论 :: 0 Trackbacks
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 on 2007-12-07 15:08 三人行,必有我师焉 阅读(2447) 评论(17)  编辑  收藏

评论

# re: 准备对SWT-Extension realease了[未登录] 2007-12-07 17:41 差沙
楼主佩服,这方面不是很懂, 但一看就是好东东,强帖留名  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-08 03:18 gr8vyguy
挺好的,只是点File System导致JVM退出。

其实我也做了一些这方面的扩展。包括Hook。还没看你的Hook的怎么实现的。
我是用SWT的OS.SetWindowsHookEx + org.eclipse.swt.internal.Callback.
不需要再定义native的函数。只是实现了键盘和鼠标两个钩子。

另外你的Registry基本是抄Core Java II里的吧,我做了一套仿C#里Registry的接口的。

有意的话,我可以把我的代码捐出来,加到你的Project里!

还有这个最好叫SWT Extension on Windows。

  回复  更多评论
  

# re: 准备对SWT-Extension realease了[未登录] 2007-12-08 11:41 BeanSoft
支持!  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-08 18:45 三人行,必有我师焉
To:gr8vyguy
我知道你的Hook的做法,不过那只能实现线程钩子,我想实现的是系统全局钩子,不是一个概念。Core Java II 我没有看过,不知道里面有Registry的实现。File System导致JVM退出,遗留的Bug,暂时不知道怎么解决。  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-09 04:03 gr8vyguy
@三人行,必有我师焉
我实现的是绝对是系统全局钩子。

Registry? 那就奇怪了,我再仔细看看,如果搞错了那就不好意思了。

  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-09 13:32 cnfree
@gr8vyguy
全局鈎子嗎?不可能用swt实现的,因为没有dll的handle,是无法实现数据共享的。如果你确信你真的实现了,拜托你给我一个例子,不甚感激。你说的那种方法我很久以前就尝试过了,但是没有搞定。

http://www.blogjava.net/cnfree/archive/2006/11/27/83754.html ,我以前的一篇文章,当时以为实现了,后来发现数据在Java的HookProc里无法共享,也就是说,你能拿到 LParam,但是取不出相关数据,只能用用WParam,因此就算你可以实现全局钩子,你说的那种Case是无法获得所有的信息。

别人的文章:http://www.javaworld.com.tw/jute/post/view?bid=35&id=175440&sty=3&age=0

PS:我已经做成了插件,可以直接在插件开发中使用了。  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-09 20:26 gr8vyguy
@cnfree
没有全局的钩子我的抓图软件怎么实现
http://www.blogjava.net/xilaile/archive/2007/05/02/114983.html

普通的钩子函数的确需要定义在独立的DLL中才能挂进去,不过你不要忘了还存在一类Low Level的钩子,不需呀dll的
  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-10 11:47 三人行,必有我师焉
@gr8vyguy
没有JDK1.6,所以运行不起来,但是看过了你的代码。
1,你添加了2个native方法:
static final native boolean InstallMouseHook(int i, int j);
static final native boolean UninstallMouseHook(int i);
所以我不能从你的程序里断定你用的是哪种钩子
2,和我上个回复所说的一样,你只是使用了wParam,没有用到lParam,
wParam 包含了Mouse行为信息, lParam则是一个MSLLHOOKSTRUCT结构体指针,我想你应该是不能够根据这个指针拿到结构体的,而MSLLHOOKSTRUCT可以用来拿到坐标信息。其实就对窗口某一部位截图而言,根本就不需要Hook,SWT+Swing的Robot就可以实现了。

好了不用再争论了,Mouse Hook自有 Mouse_LL没有的优势,可以在98下运行,保证了系统兼容性。毕竟连纯C#也只能实现Mouse_LL和Keyboard_LL两种Hook。

我现在还有点问题,就是如果我要拦截Hook,比如我以前的一个需求,拦截一个浏览器的菜单让它不显示出来,如果浏览器嵌在Java程序内部,那么在Java内部的HookProc正好处理这个事件,但是如果拦截的外部的浏览器,又该如果解决。  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-10 15:26 gr8vyguy
HookProc应该先于WindowProc, 判断一下,不下传不就行了  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-10 16:38 三人行,必有我师焉
@gr8vyguy
是的,关键是现在的Hookproc是在C++里实现的,和Java完全没有关系,如果在Java实现,就无法数据共享了。但是判断是否下传的逻辑是在Java里,我在考虑怎么把这两者结合起来。  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-12 17:18 leigh
可以使用 DuplicateHandle 来实现跨进程的句柄。
  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2007-12-12 18:21 三人行,必有我师焉
跨进程我已经实现了,在Java里拦截JNI的HookProc,并对数据做出一些修改,这才是困难所在。  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2008-01-08 18:02 黑灵
good job  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2008-05-16 22:08 brucehu
请问你那个不需要jre的程序是怎么实现的  回复  更多评论
  

# re: 准备对SWT-Extension realease了 2009-06-20 11:02 狄德罗
有没有SWT linux Extension我想用这个在linux下实现窗口失去键盘焦点  回复  更多评论
  

# re: 准备对SWT-Extension realease了[未登录] 2012-05-07 13:58 涤生
哥们你这个keyproess有bug.一旦遇到系统的alert触发的时候就挂了  回复  更多评论
  

# re: 准备对SWT-Extension realease了[未登录] 2013-11-15 15:13 javapon
想对USB做个监听,发现用这个方法Hook.CALLWNDPROC 有的时候能监听到鼠标的拔出和插入, 由于对C一头雾水,请问如果是这个方法 ,usb设备插入和拔出对应的HookData.getMessage是多少,  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 
GitHub |  开源中国社区 |  maven仓库 |  文件格式转换