C# AppDomain:从入口点执行程序集
C# AppDomain: Execute assembly from entry point
我正在尝试创建一个 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();
}
}
}
我尝试了两种不同的方法来实现这一点。
方法一
在程序集的入口点使用 "MethodInfo.Invoke" 方法。
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
target.Invoke(null, parameters);
由于主要方法不是public,这会产生方法访问异常。解决此问题的一个简单方法是创建主要方法 public,但我将无法访问旨在与此应用程序一起使用的程序集。
方法二
使用如下所示的"AppDomain.ExecuteAssembly"方法。
newDomain.ExecuteAssembly(filePath, parameters);
这要求应用程序域同时具有文件 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 权限才能正常工作。
您写道:"This produces a Method Access Exception due to the main method being non-public." 是的,您不应该调用不打算从外部调用的方法。您尝试 "override" 保护级别:我希望这是不可能的,因为这意味着系统中存在一个大漏洞。
使用方法 #1 并添加反射权限 RestrictedMemberAccess 以便可以调用非 public 成员是一种调用具有完全受限权限的程序集的方法。
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);
}
抱歉,方法名称不明确,如果要使用,应该更改这些名称。
我知道已经有一段时间了,但我来到这个问题,这里是我最终得到的结果。
首先,导入system.security
using System.Security;
using System.Security.Permissions;
这里是使用 DomainApp 的执行。
public static void ExecuteAssemblyLoadFileAppDomain(string file, string[] param)
{
Console.WriteLine("[*] Using ExecuteAssemblyLoadFileAppDomain1:");
PermissionSet permission = new PermissionSet(PermissionState.Unrestricted);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain domain = AppDomain.CreateDomain("King AppDomain", null, setup, permission);
try
{
Console.WriteLine($"[+] Executing '{Path.GetFileName(file)}' in '{domain.FriendlyName}' AppDomain.");
domain.ExecuteAssembly(file, param);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
AppDomain.Unload(domain);
}
}
我正在尝试创建一个 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();
}
}
}
我尝试了两种不同的方法来实现这一点。
方法一
在程序集的入口点使用 "MethodInfo.Invoke" 方法。
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
target.Invoke(null, parameters);
由于主要方法不是public,这会产生方法访问异常。解决此问题的一个简单方法是创建主要方法 public,但我将无法访问旨在与此应用程序一起使用的程序集。
方法二
使用如下所示的"AppDomain.ExecuteAssembly"方法。
newDomain.ExecuteAssembly(filePath, parameters);
这要求应用程序域同时具有文件 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 权限才能正常工作。
您写道:"This produces a Method Access Exception due to the main method being non-public." 是的,您不应该调用不打算从外部调用的方法。您尝试 "override" 保护级别:我希望这是不可能的,因为这意味着系统中存在一个大漏洞。
使用方法 #1 并添加反射权限 RestrictedMemberAccess 以便可以调用非 public 成员是一种调用具有完全受限权限的程序集的方法。
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);
}
抱歉,方法名称不明确,如果要使用,应该更改这些名称。
我知道已经有一段时间了,但我来到这个问题,这里是我最终得到的结果。
首先,导入system.security
using System.Security;
using System.Security.Permissions;
这里是使用 DomainApp 的执行。
public static void ExecuteAssemblyLoadFileAppDomain(string file, string[] param)
{
Console.WriteLine("[*] Using ExecuteAssemblyLoadFileAppDomain1:");
PermissionSet permission = new PermissionSet(PermissionState.Unrestricted);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain domain = AppDomain.CreateDomain("King AppDomain", null, setup, permission);
try
{
Console.WriteLine($"[+] Executing '{Path.GetFileName(file)}' in '{domain.FriendlyName}' AppDomain.");
domain.ExecuteAssembly(file, param);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
AppDomain.Unload(domain);
}
}