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

C#AppDomain:从入口点执行程序集,c#,.net,reflection,.net-assembly,appdomain,C#,.net,Reflection,.net Assembly,Appdomain,我正在尝试创建一个Windows沙盒应用程序,它基于此处的“操作方法”: 在本例中,它从DLL加载特定类型,而我希望能够从其入口点以受限权限执行程序集 MethodInfo target = Assembly.Load(assemblyName).EntryPoint; (new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert(); target.Invoke(null, paramete

我正在尝试创建一个Windows沙盒应用程序,它基于此处的“操作方法”:

在本例中,它从DLL加载特定类型,而我希望能够从其入口点以受限权限执行程序集

MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
target.Invoke(null, parameters);
我用于测试的程序是一个简单的helloworld应用程序

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方法公开,但我将无法访问用于此应用程序的程序集

using System;

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

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

newDomain.ExecuteAssembly(filePath, parameters);
这要求应用程序域对要执行的程序集同时具有文件IO权限和UI权限,但我希望能够限制程序集具有这些权限

MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
target.Invoke(null, parameters);
是否有方法在权限受限的应用程序域中从程序集的入口点执行程序集

编辑:程序集的位置由打开的文件对话框提供,然后传递给以下方法

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);
}
public int RunAssembly(字符串文件路径,字符串[]参数)
{
AppDomainSetup adSetup=新建AppDomainSetup();
adSetup.ApplicationBase=Path.GetDirectoryName(文件路径);
PermissionSet permSet=新的PermissionSet(PermissionState.None);
AddPermission(新的SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly=typeof(沙盒).Assembly.Evidence.GetHostEvidence();
newDomain=AppDomain.CreateDomain(“沙盒”,null,adSetup,permSet,fullTrustAssembly);
返回newDomain.ExecuteAssembly(文件路径、参数);
}
正如你所看到的,我想给新应用程序域的唯一权限是运行。然而,ExecuteAssembly方法需要文件IO和UI权限才能正常工作。

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

使用方法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);
}
public int RunAssembly(字符串文件路径,对象[]参数)
{
AppDomainSetup adSetup=新建AppDomainSetup();
adSetup.ApplicationBase=Path.GetDirectoryName(文件路径);
PermissionSet permSet=新的PermissionSet(PermissionState.None);
AddPermission(新的SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly=typeof(沙盒).Assembly.Evidence.GetHostEvidence();
newDomain=AppDomain.CreateDomain(“沙盒”,null,adSetup,permSet,fullTrustAssembly);
ObjectHandle=Activator.CreateInstanceFrom(
_newDomain,typeof(沙盒).Assembly.ManifestModule.FullyQualifiedName,
类型(沙盒)。全名
);
newDomainInstance=(沙盒)handle.Unwrap();
string assemblyName=Path.GetFileNameWithoutExtension(filePath);
返回newDomainInstance.ExecuteAssembly(程序集名称、参数);
}
public int ExecuteAssembly(字符串assemblyName,对象[]参数)
{
MethodInfo目标=Assembly.Load(assemblyName).EntryPoint;
(新建ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
返回target.Invoke(null,参数);
}

很抱歉,方法名称不明确,如果要使用,应该更改这些名称。

我知道已经有一段时间了,但我想到了这个问题,在这里我得到了什么

首先,导入系统安全

使用系统安全;
使用System.Security.Permissions;
下面是使用DomainApp执行的过程

public static void ExecuteAssemblyLoadFileAppDomain(字符串文件,字符串[]参数)
{
Console.WriteLine(“[*]使用ExecuteAssemblyLoadFileAppDomain1:”);
PermissionSet权限=新的PermissionSet(PermissionState.Unrestricted);
AppDomainSetup=新建AppDomainSetup();
setup.ApplicationBase=AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain domain=AppDomain.CreateDomain(“King AppDomain”,null,setup,permission);
尝试
{
WriteLine($“[+]在“{domain.FriendlyName}”AppDomain.”中执行“{Path.GetFileName(file)}”;
domain.ExecuteAssembly(文件,参数);
}
捕获(例外e)
{
控制台写入线(e);
}
最后
{
卸载(域);
}
}

请也发布加载程序的代码。方法#1在普通appdomain中运行良好。出于好奇,您是否在阅读了Space Engineers modding论坛上的最新帖子后开始使用代码访问安全性?(我不经常看到关于这个主题的问题,一两天前我在那个网站上发了一篇关于这个主题的帖子)我已经为方法2添加了加载代码。杰斯特:你所说的“普通”appdomain是什么意思?Scott:不,我之所以选择它是因为在大学项目中需要它。是的,我理解为什么程序集的入口点不应该是公共的,因为它不是设计用来从CLR以外的任何地方调用的。这就留下了一个问题,即用有限的特定权限集(例如,第一次编辑中存在的权限集)以编程方式调用程序集的最佳方法是什么。您可以使用带有
bindingsflags的反射调用来调用非公共方法。非公共的
(请参阅:)