2015-02-11 103 views
1

我試圖創建一個Windows沙箱應用程序中執行彙編,在「如何」發現這裏建造:「https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspxC#應用程序域:從入口點

在這個例子從一個DLL而加載特定的類型我希望能夠使用受限制的權限從其入口點執行程序集。

我用於測試目的的程序是一個簡單的hello world應用程序。

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Hello World!"); 
      Console.Read(); 
     } 
    } 
} 

我嘗試了兩種不同的方法來嘗試實現這一點。

方法1.

使用在組件的入口點的「MethodInfo.Invoke」的方法。

MethodInfo target = Assembly.Load(assemblyName).EntryPoint; 
target.Invoke(null, parameters); 

由於主要方法是非公開的,因此會產生方法訪問異常。解決這個問題的一個簡單方法是公開主要方法,但是我不會有這種類型的訪問權限,以便與此應用程序一起使用。

方法2

使用如下所示的 「AppDomain.ExecuteAssembly」 的方法。

newDomain.ExecuteAssembly(filePath, parameters); 

這就要求應用程序域同時具有文件IO權限和UI權限要執行大會,但我希望能夠從具有這些權限限制裝配。

有沒有辦法在權限受限的應用程序域內從入口點執行程序集?

編輯:從打開文件對話框中提供程序集的位置,然後傳遞給以下方法。

public int RunAssembly(string filePath, string[] parameters) 
{ 
    AppDomainSetup adSetup = new AppDomainSetup(); 
    adSetup.ApplicationBase = Path.GetDirectoryName(filePath); 

    PermissionSet permSet = new PermissionSet(PermissionState.None); 
    permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 

    StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>(); 

    newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly); 

    return newDomain.ExecuteAssembly(filePath, parameters); 
} 

正如你所看到的,我希望賦予新的應用程序域的唯一權限是運行能力。而它需要ExecuteAssembly方法的文件IO和UI權限才能正常工作。

+0

請發佈您的加載程序代碼了。方法#1從正常的應用程序域正常工作。 – Jester 2015-02-11 14:05:08

+0

出於好奇,在閱讀Space Engineers修改論壇最近發佈的文章後,你是否開始使用Code Access Security?(我沒有經常看到關於這個主題的問題,我只是在一兩天前在該網站上做了一個大的帖子) – 2015-02-11 15:08:48

+0

我已經爲方法#2添加了加載代碼。 Jester:你認爲「普通」appdomain是什麼意思?斯科特:不,我在大學項目中因爲需要而選擇了這個。 – Phil 2015-02-11 16:29:44

回答

0

使用方法#1並添加反射權限RestrictedMemberAccess,以便可以調用非公共成員是一種調用具有完全受限權限的程序集的方法。

MethodInfo target = Assembly.Load(assemblyName).EntryPoint; 
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert(); 
target.Invoke(null, parameters); 

全加載代碼:

public int RunAssembly(string filePath, Object[] parameters) 
{ 
    AppDomainSetup adSetup = new AppDomainSetup(); 
    adSetup.ApplicationBase = Path.GetDirectoryName(filePath); 

    PermissionSet permSet = new PermissionSet(PermissionState.None); 
    permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 

    StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>(); 

    newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly); 

    ObjectHandle handle = Activator.CreateInstanceFrom(
     _newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName, 
     typeof(Sandboxer).FullName 
     ); 

    newDomainInstance = (Sandboxer)handle.Unwrap(); 

    string assemblyName = Path.GetFileNameWithoutExtension(filePath); 

    return newDomainInstance.ExecuteAssembly(assemblyName, parameters); 
} 

public int ExecuteAssembly(string assemblyName, Object[] parameters) 
{ 
    MethodInfo target = Assembly.Load(assemblyName).EntryPoint; 
    (new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert(); 

    return target.Invoke(null, parameters); 
} 

對不起,我不明確方法名,這些應該如果要使用它改變。

1

您寫道:「由於主要方法是非公開的,因此會產生方法訪問異常。」是的,你不應該調用一個不打算從外部調用的方法。你試圖「覆蓋」保護級別:我希望這不可能,因爲它意味着系統中的一個大漏洞。

+0

是的,我明白爲什麼程序集的入口點不應該公開,因爲它不是從除CLR之外的任何東西中調用。這留下了什麼是用程序調用具有有限特定權限集的程序集的最佳方法,例如第一次編輯中存在的權限集。 – Phil 2015-02-11 16:56:28