In the previous posts, I’d explained about low-level languages and play around kernel-mode reversing but now let’s dig into the high-level languages.
In this post, I’m gonna share a comprehensive method that took more than two weeks for me to build such small and perfect function to play with .Net framework reflection.
I also share this functions in my GitHub which can be accessed through this link.
.Net reflection gives .net framework a high flexibility by dynamically invoking functions from .net IL files and it has good features which can be used in order to build a plugin-based application in both desktop applications and web applications.
But for now, let me show you what these functions are and how we can use them.
I create two methods to cover all the possibilities in which a target function can be defined, the first one is for situations where you have a function that doesn’t need any argument.
It implemented as below :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
static object InvokeAssemblyWithoutArgumant(string Path, string MethodName, object[] ArgumantsToContructor = null) { object ret = null; System.Reflection.Assembly myDllAssembly = System.Reflection.Assembly.LoadFile(Path); if (ArgumantsToContructor == null) { foreach (Type item in myDllAssembly.GetTypes()) { ret = item.GetMethod(MethodName).Invoke(Activator.CreateInstance(item), null); } } else { foreach (Type item in myDllAssembly.GetTypes()) { ret = item.GetMethod(MethodName).Invoke(Activator.CreateInstance(item, ArgumantsToContructor), null); } } return ret; } |
and the second one :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
static object InvokeAssemblyWithArgumant(string Path, string MethodName, object[] argumantToMethod, object[] ArgumantsToContructor = null) { object ret = null; System.Reflection.Assembly myDllAssembly = System.Reflection.Assembly.LoadFile(Path); if (ArgumantsToContructor == null) { foreach (Type item in myDllAssembly.GetTypes()) { ret = item.GetMethod(MethodName).Invoke(Activator.CreateInstance(item), argumantToMethod); } } else { foreach (Type item in myDllAssembly.GetTypes()) { ret = item.GetMethod(MethodName).Invoke(Activator.CreateInstance(item, ArgumantsToContructor), argumantToMethod); } } return ret; } |
The second one is used for situations where you wanna pass the parameter(s) to the function.
For instance …
Consider you built a class library (.dll plugin) from the Visual Studio with the following syntax :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class Class1 { public Class1(string Arg1) { //Make program ready for first usage System.Windows.Forms.MessageBox.Show("Constructor Invoked !" + Arg1); } public static string MyPluginFunction1(int a, int b) { System.Windows.Forms.MessageBox.Show("I'm here in MyPluginFunction.(Args:" + a + "-" + b + ")"); // Do what to want to do as a plugin return "Successful"; } public static string MyPluginFunction2() { System.Windows.Forms.MessageBox.Show("I'm here in MyPluginFunction (without arg)."); // Do what to want to do as a plugin return "Successful"; } } |
If you want to call MyPluginFunction1 then you should use the second method which gives an array of object to pass to the method.
1 2 3 4 |
//dll path (Plugin Path) string PathToPlugin = Environment.CurrentDirectory + "\\Plugin.dll"; // it's extension can be anything ! // you can also load assembly from a base64 string. InvokeAssemblyWithArgumant(PathToPlugin, "MyPluginFunction1", new object[] { 1, 2 }, new object[] { "Sample Arg to constructor" }); |
If you want to call MyPluginFunction2 then you should use the first method which invokes the method directly without any arguments.
1 2 3 4 |
//dll path (Plugin Path) string PathToPlugin = Environment.CurrentDirectory + "\\Plugin.dll"; // it's extension can be anything ! // you can also load assembly from a base64 string. InvokeAssemblyWithoutArgumant(PathToPlugin, "MyPluginFunction2", new object[] { "Sample Arg to constructor" }); |
Important Note: If you have an exception like, object reference not set to an instance it is because the method name is incorrect or you invoke a non-static function within a static function or invoke a static function within a non-static function so please keep in mind the invoker function and target function should have the same state.
This post is also available on Github :
https://github.com/SinaKarvandi/UseAllOfDotNetReflection
This topic also published in Damghan University’s publication. You can find more at https://pubs.rayanfam.com/persian/.
Great post. It helped me to make a sophisticated plugin!