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 上下載了。
首先當然主要還是我個人對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