受限AppDomain中的C#类从位于主AppDomain中的其他类继承

问题描述 投票:1回答:1

我尝试在C#中创建一个简单的控制台改装项目,在该项目中,我的程序包含名为ElementInGame抽象类列表。我希望能够[[创建从.txt文件继承ElementInGame的其他类。 ElementInGame类将包含一些基本方法(虚拟方法和非虚拟方法)。但是我不希望这些其他的模块化类执行恶意代码,我希望它们只能访问继承的类中的方法/属性。这是我的ElementInGame代码:

(我的C#程序#1)

using System; namespace Modding { //The class itself inherit from MarshalByRefObject to be available in 2 differents Domains public abstract class ElementInGame : MarshalByRefObject { public ElementInGame() { Console.WriteLine("ElementInGame class created"); } public virtual int GetNumber() { return 10; } public void CountToTen() { for (int i = 0; i <= 10; i++) { Console.WriteLine(i); } } } }

然后,我的.txt文件存储在“ C:\ program.txt”中

(我的原始.txt文件)

using System; namespace Test { public class HelloWorld { public HelloWorld() { Console.WriteLine("Called Constructor() !"); } public static int TestMethod() { Console.WriteLine("Called TestMethod() !"); return 11; } } }

所以我编写主程序的代码以读取.txt文件,对其进行限制地编译,然后执行它:

((我的C#程序#2在第二个.cs文件中,长代码警告)

using System; using System.CodeDom.Compiler; using System.IO; using Microsoft.CSharp; using System.Reflection; using System.Security.Permissions; using System.Security; using System.Security.Policy; using System.Runtime.Remoting; using System.Collections.Generic; namespace Modding { public class Program : MarshalByRefObject { public static void Main(string[] args) { string assemblyPath = @"C:\program.txt"; // Where the .txt file is stored string code = File.ReadAllText(assemblyPath); //The code to compile CompilerResults compile = CompileFromCode(code); //Compile the code in the temporary files string fullPath = compile.PathToAssembly; //sample : C:\Users\MY_USER_NAME\AppData\Local\Temp\5v2p3qki.dll string pathWithoutFile = Path.GetDirectoryName(fullPath); //sample : C:\Users\MY_USER_NAME\AppData\Local\Temp string pathNameOnly = Path.GetFileNameWithoutExtension(fullPath); //sample : 5v2p3qki Program newDomainInstance = GetOtherProtectedDomainInstance(pathWithoutFile); newDomainInstance.CallMethod(pathNameOnly, "Test.HelloWorld", "TestMethod", null, null); newDomainInstance.CreateObject(pathNameOnly,"Test.HelloWorld"); List<ElementInGame> allElement = new List<ElementInGame>(); //allElement.Add ***?*** Console.ReadKey(); } public static Program GetOtherProtectedDomainInstance(string pathWithoutFile) { AppDomainSetup adSetup = new AppDomainSetup(); adSetup.ApplicationBase = pathWithoutFile; //Set some permissions to avoid malicious code PermissionSet permSet = new PermissionSet(PermissionState.None); permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); StrongName fullTrustAssembly = new StrongName( new StrongNamePublicKeyBlob(typeof(Program).Assembly.GetName().GetPublicKey()), typeof(Program).Assembly.GetName().Name, typeof(Program).Assembly.GetName().Version); AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly); ObjectHandle handle = Activator.CreateInstanceFrom( newDomain, typeof(Program).Assembly.ManifestModule.FullyQualifiedName, typeof(Program).FullName ); Program newDomainInstance = (Program)handle.Unwrap(); return newDomainInstance; } public static CompilerResults CompileFromCode(string code) { //Compile the code in a .dll locate in the temporary files //The following code is based on https://stackoverflow.com/questions/10314815/trying-to-compile-and-execute-c-sharp-code-programmatically CompilerParameters CompilerParams = new CompilerParameters(); string outputDirectory = Directory.GetCurrentDirectory(); CompilerParams.GenerateInMemory = false; CompilerParams.TreatWarningsAsErrors = false; CompilerParams.GenerateExecutable = false; CompilerParams.CompilerOptions = "/optimize"; //Adding a reference to the current project to allow the .txt file to inherit the class "ElementInGame" later string[] references = { "System.dll", Assembly.GetEntryAssembly().Location }; CompilerParams.ReferencedAssemblies.AddRange(references); CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, code); if (compile.Errors.HasErrors) { string text = "Compile error: "; foreach (CompilerError ce in compile.Errors) { text += "rn" + ce.ToString(); } throw new Exception(text); } return compile; } public static void DisplaySomething()//Useful for later { Console.WriteLine("This isn't supposed to be display"); } //Calling a method from the restricted Domain public void CallMethod(string assemblyName, string typeName, string entryPoint, object objectToExecute = null, object[] parameters = null) { MethodInfo target = Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint); try { target.Invoke(objectToExecute, parameters); } catch { Console.WriteLine("Security Error with Method " + assemblyName + " namespace : " + typeName + " method : " + entryPoint); } } //Create an instance from the restricted Domain public void CreateObject(string assemblyName, string typeName) { try { object o = Assembly.Load(assemblyName).CreateInstance(typeName); } catch { Console.WriteLine("Security Error with Constructor " + assemblyName + " namespace : " + typeName); } } } }

目前

。txt文件没有任何链接

完全使用我的C#程序代码工作正确,我得到以下输出:Called TestMethod() ! Called Constructor() !
然后我编辑.txt文件中的代码以从Modding.ElementInGame继承:

(我的[[编辑

.txt文件)

using System; namespace Test { public class HelloWorld : Modding.ElementInGame { public HelloWorld() : base() { Console.WriteLine("Called Constructor() !"); } public static int TestMethod() { Console.WriteLine("Called TestMethod() !"); return 11; } } } 所以我期望输出如:

Called TestMethod() !
ElementInGame class created
Called Constructor() !

但是在此更改之后,调用TestMethod时在[System.NullReferenceException处带有程序崩溃] >>

但是创建HelloWorld实例(.txt文件):newDomainInstance.CallMethod(pathNameOnly, "Test.HelloWorld", "TestMethod", null, null); 似乎可以正常工作(不会崩溃,执行try / catch时代码保留在try部分中),但是我的

有我的控制台上什么也没打印出来]

,所以我猜这行不通吗?更改AppDomain的权限不会更改。newDomainInstance.CreateObject(pathNameOnly,"Test.HelloWorld");

所以我的问题是:如何在程序中

create

store .txt文件的一个实例,该实例继承自ElementInGame(并将其添加到列表中)的ElementInGame)? 这样,我可以从程序中使用虚拟方法GetNumber()。我不希望.txt文件可以访问程序本身(如调用DisplaySomething()方法),通过ElementInGame just communication

我尝试在C#中创建一个简单的控制台改装项目,在该项目中,我的程序包含一个名为ElementInGame的抽象类的列表。我希望能够创建继承...

c# inheritance plugins appdomain mod
1个回答
0
投票
PermissionSet permSet = new PermissionSet(PermissionState.Unrestricted); permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
© www.soinside.com 2019 - 2024. All rights reserved.