附加自定义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中运行的类(继承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杂志上有一篇精彩的文章,题为《"加载项:你信任它吗或类似的东西,但我找不到。