附加自定义AppDomain中的内存程序集

本文关键字:内存 程序集 AppDomain 自定义 | 更新日期: 2023-09-27 18:24:11

我创建了一个沙箱AppDomain:

public AppDomain CreateSandbox()
{
    var setup = new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase };
    var permissionSet = new PermissionSet(PermissionState.None);
    permissionSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.NoFlags));
    permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
    permissionSet.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); // TODO: Restrict IO
    var appDomain = AppDomain.CreateDomain("Sandbox", null, setup, permissionSet);
    return appDomain;
}

我还有一个从byte[] fileData:加载的程序集

var assembly = Assembly.Load(fileData);
var appDomain = CreateSandBox();

如何将此程序集或fileData字节加载到appDomain中,然后使用它?

附加自定义AppDomain中的内存程序集

您可以让新的AppDomain来完成这项工作。您必须实例化一个将在所选AppDomain中运行的类(继承MarshalByRefObject),并为您加载程序集。这涉及到.NET远程处理。在这篇MSDN文章中告诉我更多信息。尽管它提到了部分受信任的代码,但优秀的部分仍然适用。

在代码不值得信任的情况下,让继承MarshalByRefObject的类在沙箱域中运行以加载程序集是至关重要的。

代理/沙盒/帮助程序类

此类充当在主AppDomain(创建子域的地方)中运行的代码和希望在沙盒/子域中运行的任何代码之间的中介。使用子域时,出于安全原因,主域中的对象应仅与子域中运行的代理类直接对话。

通信是通过.NET Remoting在幕后进行的——这并不是你所知道的。因此,类是MarshalByRefObject

例如(修改的MSDN示例)

class Sandboxer:MarshalByRefObject
{
    public void LoadDodgyAssembly(string path) { ... }
}

主机代码

在创建子AppDomain时使用此代码。以下代码应在主AppDomain中运行:

var appDomain = CreateSandBox();
var handle = Activator.CreateInstanceFrom(
appDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
       typeof(Sandboxer).FullName );
var sandboxer = (Sandboxer) handle.Unwrap();
sandboxer.LoadDodgyAssembly("pleaserunme.dll");

返回值

注意代理类在主AppDomain中返回给调用代码的内容。如果您不信任加载的程序集,最好将方法标记为void,否则请考虑使用标记为[Serializable]的自己的可信任类型。

告诉我更多

  • 如何:在沙盒中运行部分受信任的代码

大约在2005年,MSDN杂志上有一篇精彩的文章,题为《"加载项:你信任它吗或类似的东西,但我找不到。