2010-06-12 138 views
11

如何在C#中爲外部進程創建沙箱? 作爲一個沙箱,我瞭解一個從C#開始的進程環境,即阻止該進程干擾其他任何內容 - 內核,系統變量,系統配置,內存,註冊表,磁盤,硬件,除起始位置之外的位置等等。如何在C#中爲外部進程創建沙箱?

我想要在一個地方執行可執行文件,並確保這個地方只能被這個進程改變的地方。此外,可執行文件可以用C,C++,C#等編寫。

回答

2

使用Sandboxie作爲我認爲您希望在某種程度上達到的示例。恕我直言,你將無法做到這一點在託管代碼。

如果您希望能夠限制應用程序的操作和效果,無論它是託管應用程序還是本地應用程序,甚至是Java應用程序。這意味着您需要監控應用程序採取的每一個行動,並採取適當的行動以確保它不會影響您的系統。適當的操作可能意味着您將應用程序寫入重定向到磁盤上的備用位置,編寫虛擬化註冊表以便真正的註冊表不受影響等等。所有這些都需要很多低級別的工作,即託管代碼不會今天提供。

注意我說的是純託管代碼,您當然可以使用Interop Services等來利用某些代碼區域的非託管實現,或者您可以使用託管C++。但是,根據您希望沙盒執行的具體細節,您可能需要實現一個內核模式驅動程序,以確保您可以充分虛擬化沙盒用戶模式應用程序的環境。

+0

你說過重定向到另一個註冊表或磁盤位置。如何完整地使用註冊表,並且不用重定向?會更簡單嗎?因爲這些應用程序不需要任何這些功能。我只是想阻止他們。 – SuitUp 2010-06-15 12:31:06

+1

@SuitUp,雖然這可能更容易,但仍然需要相同或類似的機制來攔截呼叫並使其失敗。這個重要的簡化是你不需要虛擬化註冊表等,但攔截的複雜性仍然存在。你可以使用像Detours這樣的庫進行攔截,但說實話,我懷疑這會給你一個健壯和可靠的沙盒解決方案,當然,我假設你需要一個完整的可靠和安全的解決方案,這將需要更多的基本呼叫攔截。 – 2010-06-15 17:06:07

+0

你的假設是正確的。你能給我一些技術細節嗎? – SuitUp 2010-07-13 23:03:15

3

如果你只是想運行託管代碼,這是很容易用一個AppDomain創建一個沙箱環​​境瓦特/受限制的權限集:

 PermissionSet ps = new PermissionSet(PermissionState.None); 
     // ps.AddPermission(new System.Security.Permissions.*); // Add Whatever Permissions you want to grant here 

     AppDomainSetup setup = new AppDomainSetup(); 
     Evidence ev = new Evidence(); 

     AppDomain sandbox = AppDomain.CreateDomain("Sandbox", 
      ev, 
      setup, 
      ps); 

     sandbox.ExecuteAssembly("ManagedAssembly.exe"); 

但只要你打開大門,非託管/不安全代碼所有投注都關閉,並且保護第三方代碼變得非常困難。如前所述,基本上必須在執行代碼和操作系統之間創建一個墊片,以限制它可以執行的操作,除非它足以作爲受限用戶運行,並且僅依靠ACL/UAC來保護您。

注意:該代碼示例不是一個工作示例,只是代碼的樣子。一些w/Evidence和AppDomainSetup可能是必需的,並且考慮到安全性影響,您當然應該研究/測試它。這裏有一個關於這個主題的好文章:http://msdn.microsoft.com/en-us/magazine/cc163701.aspx

+1

非託管/不安全代碼和一些代碼片段如何? – SuitUp 2010-07-14 10:32:48

+1

說實話,我真的不知道從何處開始使用非託管/不安全的代碼,並找出需要深入瞭解Windows操作系統,內核/系統調用,內存分配和訪問的幾個月的項目。在微軟工作的人甚至無法正確使用這些東西。 – 2010-07-18 07:09:37

+1

我的建議:更改您的要求,要麼只接受託管代碼,要麼向用戶明確說明他們只應使用他們信任的第三方可執行文件。 除非您只是將流程作爲不同的用戶運行,在這種情況下請檢查ProcessStartInfo類的Domain/UserName/Password屬性。 – 2010-07-18 07:18:56