首页 文章

C#AppDomain:从入口点执行程序集

提问于
浏览
1

我正在尝试创建一个Windows沙箱应用程序,基于"How to"在此处找到:“https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspx

在示例中,它从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);

由于主方法是非公共的,因此会产生方法访问异常 . 解决这个问题的一个简单方法是将main方法设为public,但我不会对要与此应用程序一起使用的程序集进行此类访问 .

方法2 .

使用“AppDomain.ExecuteAssembly”方法,如下所示 .

newDomain.ExecuteAssembly(filePath, parameters);

这要求app域具有要执行的程序集的文件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权限才能正常工作 .

2 回答

  • 0

    您写道:“由于主要方法是非公开的,因此会产生方法访问异常 . ”是的,你不应该调用一个不打算从外面调用的方法 . 你试图“覆盖”保护级别:我希望它不可能,因为它意味着系统中的一个大漏洞 .

  • 1

    使用方法#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);
    }
    

    抱歉模糊的方法名称,如果要使用它们应该更改 .

相关问题