Self-cloning executable with .NET reflection - c#

I'm trying a sort of experiment in C# .NET. I'd like to create a program that clones itself (eventually as a mutated clone). Finally, I want it to produce a "son" that also needs to have the ability to clone himself and so on!
I want to make something like this:
static void Main(string[] args)
{
string Son_Name = "son";
string Full_Son_Name = Son_Name + ".exe";
AssemblyName aName = new AssemblyName(Son_Name);
AssemblyBuilder aBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mBuilder = aBuilder.DefineDynamicModule("Module", Full_Son_Name, false);
TypeBuilder tBuilder = mBuilder.DefineType("Program", TypeAttributes.Public);
MethodBuilder methodBuilder = tBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static);
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
MethodInfo m_ReadLine = typeof(System.Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static);
Clone_My_Main_method(methodbuilder);//I need something to do THAT
aBuilder.SetEntryPoint(methodBuilder);
tBuilder.CreateType();
aBuilder.Save(Full_Son_Name);
So, with this code I succeded in making a dynamic assembly at runtime, and save it as "son.exe" or execute it. Now I need to "build" that assembly, reading my main and copying it into the son assembly.
I started using ilgenerator.emit, but I'm going into an infinite "programming" loop. I thought to make the parent.exe, disassemble it with ildasm, translate all the CIL code in ilgenerator.emit opcodes and emit all of that with ilgenerator.emit. Simply, I think this is a tedious work and cannot...work.
In fact, I'd like to READ at runtime my own main method, and then put it onto the dynamic assembly with some trick.
Anyone has any idea?
Thanks :)

You should use Mono Cecil, which can read and modify .Net assemblies.

Related

How to Apply XmlIncludeAttribute to TypeBuilder?

I am developing a library in C# that generates runtime types using System.Reflection.Emit.TypeBuilder class and i want to generate the following class hierarchy:
[XmlInclude(typeof(Derived))]
public class Base
{
}
public class Derived : Base
{
}
I use the TypeBuilder class in the following way:
class Program
{
public static void Main(string[] args)
{
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);
var moduleBuilder = assembly.DefineDynamicModule("Test");
var baseTypeBuilder = moduleBuilder.DefineType("Base", TypeAttributes.Public, typeof(Object));
var derivedTypeBuilder = moduleBuilder.DefineType("Derived", TypeAttributes.Public);
derivedTypeBuilder.SetParent(baseTypeBuilder);
baseTypeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(XmlIncludeAttribute).GetConstructor(new[] { typeof(Type) }), new[] { derivedTypeBuilder }));
var baseType = baseTypeBuilder.CreateType();
var derivedType = derivedTypeBuilder.CreateType();
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
}
}
The call:
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
I receive the following error:
Could not load file or assembly 'Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Any ideas are well-appreciated: how can i apply a custom attribute on a TypeBuilder for base class that refers to a TypeBuilder for a derived class?
P.S: I'm using Visual Studio 2017 (v15.7.5) and a C# Class Library (.NET Framework project template) NOT .NET Core or .NET Standard
Cannot provide much reason but a solution that will work without additional load/unload or whatever from and to disk:
Adding a separate field containing the actual Assembly, one can just subscribe to AppDomain.CurrentDomain.AssemblyResolve and check if the dynamic assembly was requested.
If it was, you just need to return your field and it works perfectly fine.
Example:
class Program
{
static Assembly ass;
public static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);
var moduleBuilder = assembly.DefineDynamicModule("Test");
var baseTypeBuilder = moduleBuilder.DefineType("Base", TypeAttributes.Public, typeof(Object));
var derivedTypeBuilder = moduleBuilder.DefineType("Derived", TypeAttributes.Public);
derivedTypeBuilder.SetParent(baseTypeBuilder);
baseTypeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(XmlIncludeAttribute).GetConstructor(new[] { typeof(Type) }), new[] { derivedTypeBuilder }));
var baseType = baseTypeBuilder.CreateType();
var derivedType = derivedTypeBuilder.CreateType();
ass = baseType.Assembly;
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
Console.WriteLine(attribute.Type.FullName);
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return ass;
}
}
I've reproduced your exception. It's looks like the .NET Framework want to read a module from disk.
So simplest workaround would be to save your assembly to the disk:
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("Test"),
AssemblyBuilderAccess.RunAndSave); // allow run & save
var moduleBuilder = assembly.DefineDynamicModule("Test",
"Test.dll"); // specify a file name where module will be stored
...
var baseType = baseTypeBuilder.CreateType();
var derivedType = derivedTypeBuilder.CreateType();
assembly.Save("Test.dll");
Now I was able to get attribute without exception:
var attribute = baseType.GetCustomAttribute<XmlIncludeAttribute>();
Well, I can tell you why the fix #X39 posted works. Stepping through the forest of framework code (perhaps fallbacks for different cultures) for the baseType.GetCustomAttribute(); call, when finally reaching appdomain.cs I see:
At this point, _AssemblyResolve is null (which is the private backing field for AppDomain.CurrentDomain.AssemblyResolve) and after stepping through to return null;, the code crashes with the error you posted.
More info: https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=netframework-4.7.2
#X39 feel free to merge my answer and let me know so that I can remove mine, I did not want to edit your answer directly.

Why setting a read only field with dynamic method causes error in this class?

One can store in a read only field of a class using strfld op code in dynamic method if it has its owner set to that class and JIT checks are turned off. An example is here. This approach, however, failed to work with the class that comes from F#, namely FSharpOption. Please analyse an example below:
using Microsoft.FSharp.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
#if true
using MyType = Microsoft.FSharp.Core.FSharpOption<string>;
#else
using MyType = System.Tuple<string>;
#endif
namespace ConsoleApplication27
{
class Program
{
static void Main(string[] args)
{
var something = new MyType("test");
var dynMethod = new DynamicMethod("ChangeField", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new [] { typeof(MyType) }, typeof(MyType), true);
var generator = dynMethod.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldstr, "success");
generator.Emit(OpCodes.Stfld, typeof(MyType).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)[0]);
generator.Emit(OpCodes.Ret);
var method = (Action<MyType>) dynMethod.CreateDelegate(typeof(Action<MyType>));
method(something);
Console.WriteLine(typeof(MyType).GetProperties()[0].GetGetMethod().Invoke(something, new object[0]));
}
}
}
First of all, you have to reference FSharp.Core library to run it. Then, by changing #if true to #if false you can switch between writing a read only field fo Tuple and FSharpOption. For the former it works perfectly even though both have similar structure, that is a single read only field accessible via property. For the latter it causes verification failure. Why is that so?
Very very late response.
This is very odd.
By replacing the MyType with the module of the field type. it all starts to work
var dynMethod = new DynamicMethod("ChangeField", MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard, typeof(void), new[] {typeof(MyType)}, typeof(MyType), true);
Becomes:
var dynMethod = new DynamicMethod("ChangeField", MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard, typeof(void), new[] {typeof(MyType)}, typeof(string).Module, true);
That is:
typeof(MyType), true);
becomes
typeof(string).Module, true);
The type of the field being set is string so we take the module of that.
I would love to hear a better explanation on why this is.
The plot thickens
it turns out, that typeof(string).module makes it work for any type.
even if I define my own type like this:
using System;
using System.Reflection;
using System.Reflection.Emit;
#if true
using MyType = Microsoft.FSharp.Core.FSharpOption<string>;
#else
using MyType = System.Tuple<ConsoleApplication27.Poco>;
#endif
namespace ConsoleApplication27
{
public class Poco
{
}
class Program
{
static void Main(string[] args)
{
var something = new MyType(null);
var dynMethod = new DynamicMethod("ChangeField", MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard, typeof(void), new[] {typeof(MyType)}, typeof(string).Module, true);
var generator = dynMethod.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Stfld,
typeof(MyType).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)[0]);
generator.Emit(OpCodes.Ret);
var method = (Action<MyType>) dynMethod.CreateDelegate(typeof(Action<MyType>));
method(something);
Console.WriteLine(typeof(MyType).GetProperties()[0].GetGetMethod().Invoke(something, new object[0]));
}
}
}
Now nothing makes sense. the FSharpOption type lives in the F# module.
The Poco class lives in my program module.
and still it all works when the module passed is the corelib module.
But not if I pass any of the two (above) that would make sense..

Emit - how to include library in self-contained exe-file

I found the following code at Dr Dobbs (slightly rewritten):
namespace TestEXEApp
{
public class Program
{
static void Main(string[] args)
{
AssemblyName an = new AssemblyName();
an.Name = "TestEXEApp";
AppDomain ad = AppDomain.CurrentDomain;
AssemblyBuilder ab = ad.DefineDynamicAssembly(an,
AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(an.Name, "Hello.exe");
TypeBuilder tb = mb.DefineType("TestEXEApp.Program",
TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder fb = tb.DefineMethod("Main",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(int), new Type[] { typeof(string[]) });
ILGenerator ilg = fb.GetILGenerator();
ilg.Emit(OpCodes.Ldstr, "Hello, World!");
ilg.Emit(OpCodes.Call, typeof(TestClasses.Class1).GetMethod("Test",
new Type[] { typeof(string) }));
ilg.Emit(OpCodes.Ldc_I4_0);
ilg.Emit(OpCodes.Ret);
// Seal the lid on this type
Type t = tb.CreateType();
// Set the entrypoint (thereby declaring it an EXE)
ab.SetEntryPoint(fb, PEFileKinds.ConsoleApplication);
// Save it
ab.Save("Hello.exe");
Console.WriteLine("Press enter...");
Console.ReadLine();
}
}
}
Also, I have the following class in a separate project called TestClasses:
namespace TestClasses
{
public class Class1
{
public static void Test(String t)
{
Console.WriteLine("Test: " + t);
}
}
}
Now, when I compile this, I get (obviously) the two files "TestEXEApp.exe" and "TestClasses.dll". If I run it, I get a new file, "Hello.exe", and if I run this new file, it prints "Test: Hello, World!". So far, so good. Now, the problem is, this new file obviously depends on TestClasses.dll. So if I emit it into another directory, or move it for some reason, it can no longer execute.
Is there some way for Reflection.Emit to in some way include the TestClasses.Class1 code into the Hello.exe executable, so that it becomes 100% self-contained (apart from the dependence on the .NET framework, obviously)? Or, if that can't be done, how can I get the program to output a copy of TestClasses.dll, so that I always have the dll-file written in the same directory as Hello.exe?

How to dynamically create a class derived from an interface and then preserve it for later use [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm writing a program that would have the possibility to learn for itself.
Example:
a word 'day' was typed
look for interface named 'day'
does it exists?
No => create class based on that interface (and implement the interface) and save it for next use then create instance of that class
Yes => create instance of that class
Google gave me this: How to dynamically create a class in C#?
This solution is the closest I can think of for my scenario, but it assumes you already know how many properties you will need and doesn't implement an interface at all.
I have no experience at all with system.reflection but I'm eager to learn!
Anyone know an example for my case?
Any help is appriciated.
Thank You!
EDIT: MY SOLUTION
(Because nobody gave me a straight answer I figured it out myself)
public void createObject(string name)
{
//Namespace where the interfaces are located
string strnamespace = "Intelligence.Omnia.Categories";
//Get interfacecollection
List<Type> interfaceCollection = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsInterface && t.Namespace == strnamespace).ToList();
foreach (Type myinterface in interfaceCollection)
{
//interface names
List<string> interfaceNames = new List<string>();
if (myinterface.Name == name)
{
//Add interface name
interfaceNames.Add(myinterface.Name);
//Add current interfaceproperties
List<PropertyInfo> myProps = myinterface.GetProperties().ToList();
//Does the current interface inhiretes from other interfaces?
foreach (Type inhiretences in myinterface.GetInterfaces())
{
//Add interface name
interfaceNames.Add(inhiretences.Name);
//Add those properties aswell!
foreach (PropertyInfo pi in inhiretences.GetProperties())
{
myProps.Add(pi);
}
}
createType(name, myProps, interfaceNames);
}
}
}
static void createType(string name, List<PropertyInfo> props, List<string> interfacesnames)
{
//create instance of CSharpCodeProvider
CSharpCodeProvider csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } });
//DLL
string pathDLL = AppDomain.CurrentDomain.BaseDirectory + "Objects.dll";
CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.dll", "System.Linq.dll", "System.Threading.Tasks.dll", "Intelligence.dll" });
parameters.OutputAssembly = pathDLL;
parameters.GenerateExecutable = false;
ICodeCompiler icc = csc.CreateCompiler();
//>>>>Generated CODE
//Add namespaces
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace ns = new CodeNamespace("Objects");
compileUnit.Namespaces.Add(ns);
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
ns.Imports.Add(new CodeNamespaceImport("System.Linq"));
ns.Imports.Add(new CodeNamespaceImport("System.Text"));
ns.Imports.Add(new CodeNamespaceImport("System.Threading.Tasks"));
ns.Imports.Add(new CodeNamespaceImport("Intelligence"));
ns.Imports.Add(new CodeNamespaceImport("Intelligence.Omnia"));
ns.Imports.Add(new CodeNamespaceImport("Intelligence.Omnia.Categories"));
//Define your class
CodeTypeDeclaration classType = new CodeTypeDeclaration("Object"+name);
classType.Attributes = MemberAttributes.Public; //make it public
foreach(string interfaceName in interfacesnames) //let it inherit from the interfaces
{
classType.BaseTypes.Add(interfaceName);
}
ns.Types.Add(classType);
//Add constructor
CodeConstructor constr = new CodeConstructor();
constr.Attributes = MemberAttributes.Public;
classType.Members.Add(constr);
//Add all the properties
foreach (var prop in props)
{
//If you want private fields
//CodeMemberField field = new CodeMemberField(prop.PropertyType, prop.Name);
//classType.Members.Add(field);
CodeMemberProperty property = new CodeMemberProperty();
property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
property.Type = new CodeTypeReference(prop.PropertyType);
property.Name = prop.Name;
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), prop.Name)));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), prop.Name), new CodePropertySetValueReferenceExpression()));
classType.Members.Add(property);
}
//Write the file for later use
TextWriter tw = new StreamWriter(new FileStream(AppDomain.CurrentDomain.BaseDirectory + "Objects\\" + name + ".cs", FileMode.Create));
csc.GenerateCodeFromCompileUnit(compileUnit, tw, null);
tw.Close();
//Compile the class
CompilerResults results = icc.CompileAssemblyFromFile(parameters, AppDomain.CurrentDomain.BaseDirectory + "Objects\\" + name + ".cs");
results.Errors.Cast<CompilerError>().ToList().ForEach(error => System.Windows.Forms.MessageBox.Show(error.ErrorText));
}
As #Stefan says you can dynamically create type using the DLR built into .net 4.0+ but you can also use the older reflection based mechanism in CodeDom. My suggestion is to look at IronPython as this can do what you want really easily. However if you want C#, then you need to understand that C# is compiled and you need to use the compilation in System.CodeDom.Compiler.
Nothing can infer knowledge from word Day to what the interface Day is - you have to supply this is some way. However if you know the rules by which the interface will exist, you can create it dynamically. You can also go further and create additional types based on the interface. Again no code can be written magically - you need to supply the code semantics and syntax.
However if you have this you could separate the code into multiple assemblies (CompileAssemblyFromSource). Then dynamically load the assemblies to load the types (step 2). You can create types and assemblies at runtime (see OS: Generating DLL assembly dynamically at run time).
This code is from the above linked SO answer, and shows you how to an assembly from some string of code.
using System.CodeDom.Compiler;
using System.Diagnostics;
using Microsoft.CSharp;
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.OutputAssembly = "My_Assembly_Day.dll";
CompilerResults results = icc.CompileAssemblyFromSource(parameters, ".... some C# code ....");
This SO answer shows you how to load assemblies to discover types:
https://stackoverflow.com/a/14184863/30225
edit: To answer comments.
You can name your assembly anything you like - my suggestion is to name it with interface/class combination. The above is just an example of how you can name it
You can either load the existing (pre created assemblies) at load time (first step in the program), or you can dynamically load the assemblies at runtime when needed.
Once you've loaded the assemblies the types are available to you (Activator.CreateInstance) for example.
If you get to your step and for instance type IDay is not available, you can dynamically create it using type text. Of course to get the CodeDom compiler to work, you'll need to ensure that all the things that this code references is supplied to the compilation unit. And compile that into an assembly on the disk. You can create the interface & the class that same time or in two steps.
Once step 4 is done you can load that assembly like in step 3 & 4.
at the end of the day the answer boils down to:
Find the existing type from existing types set
If existing type is not available create it in an assembly dynamically.
Load that type
Instantiate that type.
The concern comes when using that type. You can either create more code using CodeDom (in effect this gives you the ability to recreate classes that may already exist BTW) or you can use types dynamically in your code. The first has the compilation overhead, while the second has the complexity in writing code that doesn't have hard coded types - a job made very simple btw using the C# dynamic keyword. Either way this is a very run of the mill .net coding technique when using types dynamically, and many existing applications use techniques like this for managing plugins.
Caveat:
Please remember that the smallest unloadable unit in .net is the AppDomain. When you load assemblies you load them into an AppDomain. If you want unload assemblies (and thus types) to replace them fo instance, you need to unlaod the AppDomain. This means that you need to ensure that any dynamically loaded assemblies are loaded into new AppDomains which in turn can be unloaded when needed.

Create a .NET program that produces custom EXE's

I want to create a program that produces an executable slideshow.
So I need it to output an EXE with some required code and certain embedded resources (pictures) in it.
Does .NET provide such capability?
You can use CSharpCodeProvider class to compile code at runtime and add embedded resources. Have a look at this article where I explain how to do it: SlideShow Builder
This is easy to accomplish.
You can add pictures as embedded resources and then use the technique of Reflection to discover and retrieve the embedded pictures.
So the program you write is independent of the list of pictures, which are just embedded resources. You can embed pictures as resources using Visual Studio, or create a custom program to do it.
You can find some examples at http://msdn.microsoft.com/en-us/library/aa287676(v=VS.71).aspx and http://www.java2s.com/Code/CSharp/Development-Class/Saveandloadimagefromresourcefile.htm.
Good luck!
Like what SK-Logic said there is
http://msdn.microsoft.com/en-us/library/system.reflection.emit.aspx
here is example of that
http://olondono.blogspot.com/2008/02/creating-code-at-runtime.html
You could also create a the project file and create the code files and use the Process class to call the compiler if you want help doing this I can give an example
this will generate a process for you with the specified name (you'll still need to add code for the pictures):
public static Process GenerateRuntimeProcess(string processName, int aliveDuration, bool throwOnException = true)
{
Process result = null;
try
{
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = processName }, AssemblyBuilderAccess.Save);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(processName, processName + ".EXE");
TypeBuilder typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, null, null);
ILGenerator il = methodBuilder.GetILGenerator();
il.UsingNamespace("System.Threading");
il.EmitWriteLine("Hello World");
il.Emit(OpCodes.Ldc_I4, aliveDuration);
il.Emit(OpCodes.Call, typeof(Thread).GetMethod("Sleep", new Type[] { typeof(int) }));
il.Emit(OpCodes.Ret);
typeBuilder.CreateType();
assemblyBuilder.SetEntryPoint(methodBuilder.GetBaseDefinition(), PEFileKinds.ConsoleApplication);
assemblyBuilder.Save(processName + ".EXE", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
result = Process.Start(new ProcessStartInfo(processName + ".EXE")
{
WindowStyle = ProcessWindowStyle.Hidden
});
}
catch
{
if (throwOnException)
{
throw;
}
result = null;
}
return result;
}
you can findmore info on System.Reflection.Emit on MSDN here or a tutorial here or here.
if I were you I'd also look into just using powerpoint and/or the viewer app and some command line options as detailed here. maybe you don't need to "make an app that makes another app that is a slideshow" at all..

Categories