2012-07-05 83 views
1

我正在寫一個需要調用不安全本地代碼的Windows Java應用程序,並且我需要阻止此代碼訪問Java對象和JVM數據結構,否則它可能會導致JVM崩潰或攻擊敏感數據。在你問之前,這個本地代碼先前已經過驗證 - 它只能調用一些API並且不能有特定的指令,所以我們知道它不會獲得VirtualProtect本身或其他內存區域來獲得更多訪問和混亂。如何實現本機代碼沙箱?

無論如何,我的第一個嘗試是將這些代碼封裝到單獨的進程(沙箱)中,並使用IPC與Java進行通信。有一個JNI DLL可以在Java端執行IPC的東西。基本上,每次我們需要運行不安全的本機代碼時,Java應用程序都會調用JNI函數,使用自動重置的Windows事件喚醒沙箱,然後等待完成。沙箱運行不安全的本地代碼,並使用另一個自動重置的Windows事件喚醒JVM,並繼續生活。如果速度不那麼緩慢,這將是完美的。

問題是,不安全的本機代碼可能包含一些執行非常快速計算的功能,並且可以從Java調用數百萬次,因此調用開銷應該最小。但是這種開銷是巨大的,因爲JVM喚醒沙箱和Windows事件,反之亦然,當沙箱返回時。此進程是進程內(非IPC)解決方案的8倍,其中不安全的本機代碼被包裝在JNI DLL中(因此調用發生在同一時間片的同一線程中)。

我的第一個猜測是,當JVM喚醒沙盒時,Windows只會將沙箱線程放在就緒集上,因此它只會在幾毫秒後才運行。沙箱返回時也會發生同樣的情況。不計算兩個(可能是昂貴的)上下文切換。

微軟文檔here說以下內容:

如果一個更高優先級的線程變得可用來運行,系統停止執行該低優先級的線程(沒有允許它使用它的時間片來完成),併爲較高優先級的線程分配一個全時間片。

爲了測試這個理論,我將THREAD_PRIORITY_TIME_CRITICAL分配給沙箱線程。有一些收益。性能從8倍到5倍於進程(非IPC)解決方案的時間。但是我需要更多,否則這個Java應用程序可能無法進行生產更改!

你能幫助我在兩個方面:

  • 告訴我,如果有一個更快的方法來喚醒另一個進程,如強制上下文切換或執行進程間過程調用。

  • 告訴我如何在運行不安全的本機代碼時保護JVM。我聽說Google Native Client會這樣做,但我只找到this documentation。如果您瞭解更多信息,請提供有關如何實施的更多詳細信息的鏈接。

+0

如果性能問題是Windows事件或IPC,您是否追查過?通常我認爲IPC是限制因素。 – 2012-07-05 15:57:02

+0

是的,我有孤立。IPC使用共享內存來告訴沙箱執行哪個本地函數及其參數。 JNA DLL寫入這個內存,沙箱剛剛讀取,調用不安全的代碼並寫入結果。除非參數是大緩衝區,否則這些內存讀/寫操作會導致進程內解決方案的開銷不到10%。所以這不是IPC。緩慢與Windows事件或上下文切換無關。 – fernacolo 2012-07-05 16:58:47

+0

我也很好奇你想要防範哪些威脅?顯然,在第二個過程中運行是最好的保護,但它可能有助於知道是否有特定的事情,你想要的目標。例如,你是否擔心它會寫入其他記憶領域,發現異常情況,或只是對無法預見的事情提供一般性保護? – 2012-07-05 18:22:10

回答