Invoke methods using System.Reflection

本文介绍了.NET中利用System.Reflection从程序集调用方法的相关内容。先说明了必要的Using语句,接着阐述开始前需明确要调用的方法信息,之后介绍打开程序集、设置绑定标志,通过循环检查程序集并调用方法,少量代码即可增强应用适应性。

Introduction

.NET provides mechnisms to compile source code and to use the generated assemblies within an application. Using these features you can make applications more adaptive and more flexible.

The follwing article shows how to invoke methods from an assembly using System.Reflection.

Necassary Using statements

Before you start add the following Using statements to your application to ease the use of the namespaces:

using System.Reflection;
using System.Security.Permissions; 

Getting started

At the beginning you have to know which method from which type and from which module you want to call. Inspecting an assembly can be done very easy with System.Reflection too. But now we assume having all the knowlegde about it, because we generated it ourselves like in Run-Time Code Generation Part I.

So we just set the module´s name, the type´s name and the method´s name:

string ModuleName = "TestAssembly.dll";
string TypeName = "TestClass";
string MethodName = "TestMethod";

Open an assembly

Then you can open the assembly and set some Binding Flags, which are necassary for the instanciation of the chosen type.

Assembly myAssembly = Assembly.LoadFrom(ModuleName);

BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

Invoke a method

After that three loops are used to inspect the assembly and get the chosen module/type/method combination. Within the last loop the type is instanciated and the method is called. The method can be called with parameters, but here we choose null for methods with no parameters. There can also be a response from the method, which we put into a general object.

Module [] myModules = myAssembly.GetModules();
foreach (Module Mo in myModules) 
    {
     if (Mo.Name == ModuleName) 
         {
         Type[] myTypes = Mo.GetTypes();
         foreach (Type Ty in myTypes)
             {
            if (Ty.Name == TypeName) 
                {
                MethodInfo[] myMethodInfo = Ty.GetMethods(flags);
                foreach(MethodInfo Mi in myMethodInfo)
                    {
                    if (Mi.Name == MethodName) 
                        {
                        Object obj = Activator.CreateInstance(Ty);
                        Object response = Mi.Invoke(obj, null);
                        }
                    }
                }
            }
        }
    }

Conclusion

With a few lines of code you make your application call any method in any type from any module. In combination with code compilation that is a powerful mechanism to enhance the adaptability of you applications.

About André Janus


I am currently student at the university of Karlsruhe and working on my master thesis at the IT-Management and Web Engineering Research Group within the institute of telematics.

Click here to view André Janus's online profile.

using System; using System.Collections.Generic; using System.Windows.Forms; using System.Text; namespace NetObfuscator { public class MainForm : Form { private TextBox txtInputAssembly; private TextBox txtOutputAssembly; private Button btnBrowseInput; private Button btnBrowseOutput; private Button btnObfuscate; private CheckBox chkRenameMembers; private CheckBox chkEncryptStrings; private CheckBox chkControlFlow; private Label label1; private Label label2; public MainForm() { InitializeComponent(); } private void InitializeComponent() { // 初始化所有控件 this.txtInputAssembly = new TextBox(); this.txtOutputAssembly = new TextBox(); this.btnBrowseInput = new Button(); this.btnBrowseOutput = new Button(); this.btnObfuscate = new Button(); this.chkRenameMembers = new CheckBox(); this.chkEncryptStrings = new CheckBox(); this.chkControlFlow = new CheckBox(); this.label1 = new Label(); this.label2 = new Label(); // 设置窗体属性 this.Text = ".NET混淆工具"; this.ClientSize = new System.Drawing.Size(534, 201); // 设置控件位置和属性 // txtInputAssembly this.txtInputAssembly.Location = new System.Drawing.Point(120, 20); this.txtInputAssembly.Size = new System.Drawing.Size(300, 20); // txtOutputAssembly this.txtOutputAssembly.Location = new System.Drawing.Point(120, 50); this.txtOutputAssembly.Size = new System.Drawing.Size(300, 20); // btnBrowseInput this.btnBrowseInput.Location = new System.Drawing.Point(430, 18); this.btnBrowseInput.Size = new System.Drawing.Size(75, 23); this.btnBrowseInput.Text = "浏览..."; this.btnBrowseInput.Click += new EventHandler(this.btnBrowseInput_Click); // btnBrowseOutput this.btnBrowseOutput.Location = new System.Drawing.Point(430, 48); this.btnBrowseOutput.Size = new System.Drawing.Size(75, 23); this.btnBrowseOutput.Text = "浏览..."; this.btnBrowseOutput.Click += new EventHandler(this.btnBrowseOutput_Click); // btnObfuscate this.btnObfuscate.Location = new System.Drawing.Point(220, 150); this.btnObfuscate.Size = new System.Drawing.Size(100, 30); this.btnObfuscate.Text = "开始混淆"; this.btnObfuscate.Click += new EventHandler(this.btnObfuscate_Click); // chkRenameMembers this.chkRenameMembers.Location = new System.Drawing.Point(120, 80); this.chkRenameMembers.Text = "重命名成员"; this.chkRenameMembers.AutoSize = true; // chkEncryptStrings this.chkEncryptStrings.Location = new System.Drawing.Point(120, 100); this.chkEncryptStrings.Text = "加密字符串"; this.chkEncryptStrings.AutoSize = true; // chkControlFlow this.chkControlFlow.Location = new System.Drawing.Point(120, 120); this.chkControlFlow.Text = "混淆控制流"; this.chkControlFlow.AutoSize = true; // label1 this.label1.Location = new System.Drawing.Point(20, 23); this.label1.Text = "输入程序集:"; this.label1.AutoSize = true; // label2 this.label2.Location = new System.Drawing.Point(20, 53); this.label2.Text = "输出程序集:"; this.label2.AutoSize = true; // 添加控件到窗体 this.Controls.Add(this.txtInputAssembly); this.Controls.Add(this.txtOutputAssembly); this.Controls.Add(this.btnBrowseInput); this.Controls.Add(this.btnBrowseOutput); this.Controls.Add(this.btnObfuscate); this.Controls.Add(this.chkRenameMembers); this.Controls.Add(this.chkEncryptStrings); this.Controls.Add(this.chkControlFlow); this.Controls.Add(this.label1); this.Controls.Add(this.label2); } private void btnBrowseInput_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "NET Assemblies|*.exe;*.dll"; if (openFileDialog.ShowDialog() == DialogResult.OK) { txtInputAssembly.Text = openFileDialog.FileName; } } } private void btnBrowseOutput_Click(object sender, EventArgs e) { using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "NET Assemblies|*.exe;*.dll"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { txtOutputAssembly.Text = saveFileDialog.FileName; } } } private void btnObfuscate_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(txtInputAssembly.Text) || string.IsNullOrEmpty(txtOutputAssembly.Text)) { MessageBox.Show("请选择输入和输出程序集路径"); return; } try { // 检查是否安装了Mono.Cecil if (!IsMonoCecilAvailable()) { MessageBox.Show("请先安装Mono.Cecil NuGet包"); return; } // 读取程序集 var assembly = ReadAssembly(txtInputAssembly.Text); if (assembly == null) { MessageBox.Show("无法读取程序集,请确保已安装Mono.Cecil"); return; } // 应用选择的混淆技术 if (chkRenameMembers.Checked) RenameMembers(assembly); if (chkEncryptStrings.Checked) EncryptStrings(assembly); if (chkControlFlow.Checked) ObfuscateControlFlow(assembly); // 保存混淆后的程序集 WriteAssembly(assembly, txtOutputAssembly.Text); MessageBox.Show("混淆完成!"); } catch (Exception ex) { MessageBox.Show($"混淆过程中出错: {ex.Message}"); } } private bool IsMonoCecilAvailable() { try { // 尝试加载Mono.Cecil类型 var type = Type.GetType("Mono.Cecil.AssemblyDefinition, Mono.Cecil"); return type != null; } catch { return false; } } private object ReadAssembly(string path) { try { // 使用反射调用Mono.Cecil,避免编译时依赖 var assemblyDefinitionType = Type.GetType("Mono.Cecil.AssemblyDefinition, Mono.Cecil"); var readAssemblyMethod = assemblyDefinitionType.GetMethod("ReadAssembly", new[] { typeof(string) }); return readAssemblyMethod.Invoke(null, new object[] { path }); } catch { return null; } } private void WriteAssembly(object assembly, string path) { try { // 使用反射调用Mono.Cecil的Write方法 var writeMethod = assembly.GetType().GetMethod("Write", new[] { typeof(string) }); writeMethod.Invoke(assembly, new object[] { path }); } catch (Exception ex) { MessageBox.Show($"保存程序集时出错: {ex.Message}"); } } private void RenameMembers(object assembly) { try { // 使用反射访问Mono.Cecil对象 var modulesProperty = assembly.GetType().GetProperty("Modules"); var modules = modulesProperty.GetValue(assembly) as IEnumerable<object>; foreach (var module in modules) { var typesProperty = module.GetType().GetProperty("Types"); var types = typesProperty.GetValue(module) as IEnumerable<object>; foreach (var type in types) { // 重命名类型 var isPublicProperty = type.GetType().GetProperty("IsPublic"); var isNestedPublicProperty = type.GetType().GetProperty("IsNestedPublic"); var nameProperty = type.GetType().GetProperty("Name"); bool isPublic = (bool)isPublicProperty.GetValue(type); bool isNestedPublic = (bool)isNestedPublicProperty.GetValue(type); if (!isPublic && !isNestedPublic) nameProperty.SetValue(type, GenerateRandomName()); // 重命名方法 var methodsProperty = type.GetType().GetProperty("Methods"); var methods = methodsProperty.GetValue(type) as IEnumerable<object>; foreach (var method in methods) { var methodIsPublicProperty = method.GetType().GetProperty("IsPublic"); var methodIsFamilyProperty = method.GetType().GetProperty("IsFamily"); var methodIsFamilyOrAssemblyProperty = method.GetType().GetProperty("IsFamilyOrAssembly"); var methodNameProperty = method.GetType().GetProperty("Name"); bool methodIsPublic = (bool)methodIsPublicProperty.GetValue(method); bool methodIsFamily = (bool)methodIsFamilyProperty.GetValue(method); bool methodIsFamilyOrAssembly = (bool)methodIsFamilyOrAssemblyProperty.GetValue(method); if (!methodIsPublic && !methodIsFamily && !methodIsFamilyOrAssembly) methodNameProperty.SetValue(method, GenerateRandomName()); } // 重命名字段 var fieldsProperty = type.GetType().GetProperty("Fields"); var fields = fieldsProperty.GetValue(type) as IEnumerable<object>; foreach (var field in fields) { var fieldIsPublicProperty = field.GetType().GetProperty("IsPublic"); var fieldNameProperty = field.GetType().GetProperty("Name"); bool fieldIsPublic = (bool)fieldIsPublicProperty.GetValue(field); if (!fieldIsPublic) fieldNameProperty.SetValue(field, GenerateRandomName()); } } } } catch (Exception ex) { MessageBox.Show($"重命名成员时出错: {ex.Message}"); } } private void EncryptStrings(object assembly) { try { // 使用反射访问Mono.Cecil对象 var modulesProperty = assembly.GetType().GetProperty("Modules"); var modules = modulesProperty.GetValue(assembly) as IEnumerable<object>; foreach (var module in modules) { var typesProperty = module.GetType().GetProperty("Types"); var types = typesProperty.GetValue(module) as IEnumerable<object>; foreach (var type in types) { var methodsProperty = type.GetType().GetProperty("Methods"); var methods = methodsProperty.GetValue(type) as IEnumerable<object>; foreach (var method in methods) { var hasBodyProperty = method.GetType().GetProperty("HasBody"); bool hasBody = (bool)hasBodyProperty.GetValue(method); if (hasBody) { var bodyProperty = method.GetType().GetProperty("Body"); var body = bodyProperty.GetValue(method); var getILProcessorMethod = body.GetType().GetMethod("GetILProcessor"); var processor = getILProcessorMethod.Invoke(body, null); var instructionsProperty = body.GetType().GetProperty("Instructions"); var instructions = instructionsProperty.GetValue(body) as IList<object>; var opCodesType = Type.GetType("Mono.Cecil.Cil.OpCodes, Mono.Cecil"); var ldstrField = opCodesType.GetField("Ldstr"); var ldstrOpCode = ldstrField.GetValue(null); for (int i = 0; i < instructions.Count; i++) { var opCodeProperty = instructions[i].GetType().GetProperty("OpCode"); var opCode = opCodeProperty.GetValue(instructions[i]); if (opCode.Equals(ldstrOpCode)) { var operandProperty = instructions[i].GetType().GetProperty("Operand"); string originalString = (string)operandProperty.GetValue(instructions[i]); string encryptedString = EncryptString(originalString); // 插入解密方法调用 operandProperty.SetValue(instructions[i], encryptedString); // 创建调用指令 var callOpCodeField = opCodesType.GetField("Call"); var callOpCode = callOpCodeField.GetValue(null); var instructionType = Type.GetType("Mono.Cecil.Cil.Instruction, Mono.Cecil"); var createMethod = instructionType.GetMethod("Create", new[] { Type.GetType("Mono.Cecil.Cil.OpCode, Mono.Cecil"), typeof(System.Reflection.MethodInfo) }); var decryptMethod = typeof(StringDecryptor).GetMethod("Decrypt"); var callInstruction = createMethod.Invoke(null, new object[] { callOpCode, decryptMethod }); var insertAfterMethod = processor.GetType().GetMethod("InsertAfter", new[] { instructionType, instructionType }); insertAfterMethod.Invoke(processor, new object[] { instructions[i], callInstruction }); } } } } } } } catch (Exception ex) { MessageBox.Show($"加密字符串时出错: {ex.Message}"); } } private void ObfuscateControlFlow(object assembly) { try { // 使用反射访问Mono.Cecil对象 var modulesProperty = assembly.GetType().GetProperty("Modules"); var modules = modulesProperty.GetValue(assembly) as IEnumerable<object>; foreach (var module in modules) { var typesProperty = module.GetType().GetProperty("Types"); var types = typesProperty.GetValue(module) as IEnumerable<object>; foreach (var type in types) { var methodsProperty = type.GetType().GetProperty("Methods"); var methods = methodsProperty.GetValue(type) as IEnumerable<object>; foreach (var method in methods) { var hasBodyProperty = method.GetType().GetProperty("HasBody"); bool hasBody = (bool)hasBodyProperty.GetValue(method); if (hasBody) { var bodyProperty = method.GetType().GetProperty("Body"); var body = bodyProperty.GetValue(method); var getILProcessorMethod = body.GetType().GetMethod("GetILProcessor"); var processor = getILProcessorMethod.Invoke(body, null); var instructionsProperty = body.GetType().GetProperty("Instructions"); var instructions = instructionsProperty.GetValue(body) as IList<object>; // 简单的控制流混淆 - 插入无意义的分支 var opCodesType = Type.GetType("Mono.Cecil.Cil.OpCodes, Mono.Cecil"); var br_sField = opCodesType.GetField("Br_S"); var br_sOpCode = br_sField.GetValue(null); var instructionType = Type.GetType("Mono.Cecil.Cil.Instruction, Mono.Cecil"); var createMethod = instructionType.GetMethod("Create", new[] { Type.GetType("Mono.Cecil.Cil.OpCode, Mono.Cecil"), instructionType }); for (int i = 0; i < instructions.Count - 1; i += 3) { var jumpTarget = instructions[i + 2]; var branchInstruction = createMethod.Invoke(null, new object[] { br_sOpCode, jumpTarget }); var insertBeforeMethod = processor.GetType().GetMethod("InsertBefore", new[] { instructionType, instructionType }); insertBeforeMethod.Invoke(processor, new object[] { instructions[i + 1], branchInstruction }); } } } } } } catch (Exception ex) { MessageBox.Show($"混淆控制流时出错: {ex.Message}"); } } private string GenerateRandomName() { // 生成随机名称 const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; var random = new Random(); var length = random.Next(5, 15); var name = new char[length]; for (int i = 0; i < length; i++) { name[i] = chars[random.Next(chars.Length)]; } return new string(name); } private string EncryptString(string input) { // 简单的字符串加密 byte[] inputBytes = Encoding.UTF8.GetBytes(input); for (int i = 0; i < inputBytes.Length; i++) { inputBytes[i] = (byte)(inputBytes[i] ^ 0xAA); } return Convert.ToBase64String(inputBytes); } } // 字符串解密类 public static class StringDecryptor { public static string Decrypt(string encrypted) { byte[] encryptedBytes = Convert.FromBase64String(encrypted); for (int i = 0; i < encryptedBytes.Length; i++) { encryptedBytes[i] = (byte)(encryptedBytes[i] ^ 0xAA); } return Encoding.UTF8.GetString(encryptedBytes); } } } CS1061“MainForm”未包含”Form1_Load”的定义,并且找不到可接受第一个“MainForm”类型参数的可访问扩展方法“Form1_Load”(是否缺少using 指令或程序集引用?) CS0121以下方法或属性之间的调用具有二义性:“MainForm.InitializeComponent()和MainForm.InitializeComponent() CS0111类型“MainForm”已定义了一个名为“InitializeComponent”的具有相同参数类型的成员 CS0260类型“MainForm”的声明上缺少partial修饰符;存在此类型的其他分部声明
09-18
WARNING: Using incubator modules: jdk.incubator.vector WARNING: package sun.security.action not in java.base 25/08/13 23:33:32 WARN Shell: Did not find winutils.exe: java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset. -see https://cwiki.apache.org/confluence/display/HADOOP2/WindowsProblems Using Spark's default log4j profile: org/apache/spark/log4j2-defaults.properties Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::loadLibrary has been called by org.apache.hadoop.util.NativeCodeLoader in an unnamed module (file:/D:/%e4%bb%a3%e7%a0%81/pycharmgongcheng/.venv/Lib/site-packages/pyspark/jars/hadoop-client-api-3.4.1.jar) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled 25/08/13 23:33:33 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Traceback (most recent call last): File "D:\代码\pycharmgongcheng\9527.py", line 8, in <module> sc = SparkContext(conf=conf) File "D:\代码\pycharmgongcheng\.venv\Lib\site-packages\pyspark\core\context.py", line 207, in __init__ self._do_init( ~~~~~~~~~~~~~^ master, ^^^^^^^ ...<10 lines>... memory_profiler_cls, ^^^^^^^^^^^^^^^^^^^^ ) ^ File "D:\代码\pycharmgongcheng\.venv\Lib\site-packages\pyspark\core\context.py", line 300, in _do_init self._jsc = jsc or self._initialize_context(self._conf._jconf) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "D:\代码\pycharmgongcheng\.venv\Lib\site-packages\pyspark\core\context.py", line 429, in _initialize_context return self._jvm.JavaSparkContext(jconf) ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^ File "D:\代码\pycharmgongcheng\.venv\Lib\site-packages\py4j\java_gateway.py", line 1627, in __call__ return_value = get_return_value( answer, self._gateway_client, None, self._fqn) File "D:\代码\pycharmgongcheng\.venv\Lib\site-packages\py4j\protocol.py", line 327, in get_return_value raise Py4JJavaError( "An error occurred while calling {0}{1}{2}.\n". format(target_id, ".", name), value) py4j.protocol.Py4JJavaError: An error occurred while calling None.org.apache.spark.api.java.JavaSparkContext. : java.lang.UnsupportedOperationException: getSubject is not supported at java.base/javax.security.auth.Subject.getSubject(Subject.java:277) at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java:588) at org.apache.spark.util.Utils$.$anonfun$getCurrentUserName$1(Utils.scala:2446) at scala.Option.getOrElse(Option.scala:201) at org.apache.spark.util.Utils$.getCurrentUserName(Utils.scala:2446) at org.apache.spark.SparkContext.<init>(SparkContext.scala:339) at org.apache.spark.api.java.JavaSparkContext.<init>(JavaSparkContext.scala:59) at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483) at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:247) at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:374) at py4j.Gateway.invoke(Gateway.java:238) at py4j.commands.ConstructorCommand.invokeConstructor(ConstructorCommand.java:80) at py4j.commands.ConstructorCommand.execute(ConstructorCommand.java:69) at py4j.ClientServerConnection.waitForCommands(ClientServerConnection.java:184) at py4j.ClientServerConnection.run(ClientServerConnection.java:108) at java.base/java.lang.Thread.run(Thread.java:1447)
08-14
Java是一种具备卓越性能与广泛平台适应性的高级程序设计语言,最初由Sun Microsystems(现属Oracle公司)的James Gosling及其团队于1995年正式发布。该语言在设计上追求简洁性、稳定性、可移植性以及并发处理能力,同时具备动态执行特性。其核心特征与显著优点可归纳如下: **平台无关性**:遵循“一次编写,随处运行”的理念,Java编写的程序能够在多种操作系统与硬件环境中执行,无需针对不同平台进行修改。这一特性主要依赖于Java虚拟机(JVM)的实现,JVM作为程序与底层系统之间的中间层,负责解释并执行编译后的字节码。 **面向对象范式**:Java全面贯彻面向对象的设计原则,提供对封装、继承、多态等机制的完整支持。这种设计方式有助于构建结构清晰、模块独立的代码,提升软件的可维护性与扩展性。 **并发编程支持**:语言层面集成了多线程处理能力,允许开发者构建能够同时执行多项任务的应用程序。这一特性尤其适用于需要高并发处理的场景,例如服务器端软件、网络服务及大规模分布式系统。 **自动内存管理**:通过内置的垃圾回收机制,Java运行时环境能够自动识别并释放不再使用的对象所占用的内存空间。这不仅降低了开发者在内存管理方面的工作负担,也有效减少了因手动管理内存可能引发的内存泄漏问题。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值