我创建了一个沙箱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中,然后使用它?
发布于 2015-11-25 09:49:13
你让你的新AppDomain来做它。您必须实例化一个类(它继承了MarshalByRefObject),该类将在所选的AppDomain中运行并为您加载程序集。这涉及到.NET远程处理。在这篇MSDN文章中告诉我更多的信息。。虽然它提到了部分受信任的代码,但仍然适用一些重要的部分。
在沙箱域中运行继承MarshalByRefObject的类来加载程序集至关重要,以防代码不值得信任。
代理/Sandbox/Helper类
该类充当运行在主AppDomain中的代码(在其中创建子域)和希望在沙箱/子域中运行的任何代码之间的中介。当使用子域时,主域中的对象只应直接与出于安全原因而在子域中运行的代理类对话。
通信是通过.NET远程处理在幕后--而不是你会知道它。这就是为什么这个类是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杂志上有一篇很棒的文章,题为“外接程序:你相信它吗?”或类似的东西,但我找不到。
https://stackoverflow.com/questions/33912975
复制相似问题