C# AppDomain: Execute assembly from entry point

亡梦爱人 提交于 2020-05-13 14:56:28

问题


I am trying to create a Windows sandbox application, building upon the "How to" found here: "https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspx"

In the example it loads a specific type from a DLL whereas I would like to be able to execute an assembly from its entry point with restricted permissions.

The program I am using for testing purposes is a simple hello world application.

using System;

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

I have tried two different methods to try and achieve this.

Method 1.

Use the "MethodInfo.Invoke" method on the entry point of the assembly.

MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
target.Invoke(null, parameters);

This produces a Method Access Exception due to the main method being non-public. A simple way around this would be to make the main method public but I will not have this sort of access to the assemblies that are intended to be used with this application.

Method 2.

Use the "AppDomain.ExecuteAssembly" method as shown below.

newDomain.ExecuteAssembly(filePath, parameters);

This requires that the app domain has both File IO Permission and UI Permission for the assembly to be executed but I want to be able to restrict the assembly from having these permissions.

Is there a way to execute an assembly from it's entry point within a permission restricted app domain?

EDIT: The assembly's location is provided from an Open File Dialog and is then passed to the following method.

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);
}

As you can see the only permission I would like to give the new app domain is the ability to run. Whereas it required File IO and UI permissions for the ExecuteAssembly method to work correctly.


回答1:


You wrote: "This produces a Method Access Exception due to the main method being non-public." Yes, you shouldn't call a method which is not intended to be called from outside. You try to "override" the protection level: I hope it's not possible as it means a big hole in the system.




回答2:


Using Method #1 and adding the reflection permission RestrictedMemberAccess so that non-public members can be invoked is a way of invoking an assembly with fully restricted permissions.

MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
target.Invoke(null, parameters);

The full loading code:

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);
}

Sorry for the ambiguous method name, these should be changed if it to be used.



来源:https://stackoverflow.com/questions/28455968/c-sharp-appdomain-execute-assembly-from-entry-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!