C# 反射之动态生成dll/exe

news2025/1/10 2:30:35
这个可能应该属于反射的高级使用范围了,平常在项目中使用的人估计也不是很多。

由于使用反射的话会降低性能,比如之前用到的GetValueSetValue等之类,但是使用这种方式会大大提高效率,在这里我只想说,都直接写IL指令了,效率再低的话说不过去了。。。

在之前的文章中有写过一个将已经编译好的exe文件嵌入到资源文件中,然后在打开程序的时候释放出来且运行,嗯,还是一种比较简单的实现方式,这里也可以利用反射来实现这个功能,这种方式就不需要预先写好exe程序了,可以直接生成保存到本地或者在内存中运行。

其实我对IL也不熟悉,以下关于IL代码部分也是半写半猜,emmmmm,反正我也是先写c#代码然后翻译成IL的。。。

实现功能:

- 使用反射动态生成dll/exe文件

开发环境:

开发工具: Visual Studio 2013

.NET Framework版本:4.5

实现代码:

  private void EmitIL()
        {
            AssemblyName assemblyName = new AssemblyName("Emit");
            assemblyName.Version = new Version("1.0.0");
            //定义一个可以执行和保存的程序集
            //此处可以理解为向解决方案中添加了一个EmitTest的项目
            var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

            //定义模块
            //关于模块的概念可参考:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.module
            var defModuleBuilder = defAssembly.DefineDynamicModule("EmitModule", "Emit.dll");

            //定义一个公共类
            var defClassBuilder = defModuleBuilder.DefineType("EmitClass", TypeAttributes.Public);

            //在类中定义一个公共方法
            //实现两个整数相加
            var defMethodBuilder = defClassBuilder.DefineMethod("EmitMethod",
              MethodAttributes.Public,
              typeof(Int32),//返回类型
              new Type[2] { typeof(Int32), typeof(Int32) }//参数类型
              );

            //获取IL生成器
            var il = defMethodBuilder.GetILGenerator();
            #region 方法的内容
            // 这里的代码如果不知道怎么写,可以直接写c#代码,然后使用ILDASM或者其他软件反编译成IL代码,参考着写就行

            //定义变量,x+y会产生一个变量,所以我认为这里需要先定义一下,否则会报错。
            var xy = il.DeclareLocal(typeof(int));
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Stloc_0);
            il.Emit(OpCodes.Br_S, xy);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ret);

            #endregion


            //创建类的 System.Type 对象
            //如Type type = typeof(Form2);
            Type type = defClassBuilder.CreateType();

            //实例化
            object Instance = Activator.CreateInstance(type);

            //调用方法
            //object obj = type.GetMethod("EmitMethod").Invoke(Instance, new object[2] { 1, 3 });
             object obj = type.InvokeMember("EmitMethod", BindingFlags.InvokeMethod, null, Instance, new object[2] { 1, 3 });
            MessageBox.Show(obj.ToString());

            //保存程序集
            defAssembly.Save("Emit.dll");
        }
 private void btn_emit_Click(object sender, EventArgs e)
        {
            EmitIL();
        }

实现效果:

****

以上代码最后将程序集保存到本地了,这里可以反编译看到生成的dll的代码如下:

由简入繁,拿来即用

更多精彩,请持续关注公众号:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt学习之旅 I

构建一个跨平台的应用(Create A Cross-Platform Application) 目录 构建一个跨平台的应用(Create A Cross-Platform Application) 设计模式 开始构建 Qt是跨平台的C框架,这里,我们将会构建一个简单的C跨平台项目来熟悉QT是如何实现简单的跨平台的。 …

HTB-MarkUp(XXE漏洞、SSH id_rsa密钥)

前言 各位师傅大家好,我是qmx_07,今天给大家讲解MarkUp靶机 渗透过程 信息搜集 服务器开放了22SSH端口、80HTTP端口 和 443HTTPS端口 弱口令登录后台 抓取http 数据包,进行加载 账号密码字典 账号: admin密码: password 利用XXE漏洞 捕…

超分辨率技术之插值算法

🌞欢迎莅临我的个人主页👈🏻这里是我专注于深度学习领域、用心分享知识精粹与智慧火花的独特角落!🍉 🌈如果大家喜欢文章,欢迎:关注🍷点赞👍🏻评论…

天融信把桌面explorer.exe删了,导致开机之后无windows桌面,只能看到鼠标解决方法

win10开机进入桌面,发现桌面无了,但是可以ctrlaltdelete调出任务管理器 用管理员权限打开cmd,输入: sfc /scanfilec:\windowslexplorer.exe 在运行C:\windows\Explorer.exe;可以进入桌面,但是隔离几秒钟…

链式二叉树的基本操作(C语言版)

目录 1.二叉树的定义 2.创建二叉树 3.递归遍历二叉树 1)前序遍历 2)中序遍历 3)后序遍历 4.层序遍历 5.计算节点个数 6.计算叶子节点个数 7.计算第K层节点个数 8.计算树的最大深度 9.查找值为x的节点 10.二叉树的销毁 从二叉树…

物体识别之微特征识别任务综述

“深度人工智能”是成都深度智谷科技旗下的人工智能教育机构订阅号,主要分享人工智能的基础知识、技术发展、学习经验等。此外,订阅号还为大家提供了人工智能的培训学习服务和人工智能证书的报考服务,欢迎大家前来咨询,实现自己的…

一模--解题--71-80

文章目录 9.资源管理71、 [单选] 一个项目连续错过交付日期,项目团队评估完该情况后,项目经理意识到团队绩效差的原因在于团队成员对于自己的职责缺乏清晰认识。项目经理首先应该关注哪一项? 13.干系人管理72、 [单选] 项目团队刚刚完成一个新…

element-plus的面包屑组件el-breadcrumb

面包屑组件主要用来显示当页面路径,以及快速返回之前的页面。 涉及2个组件 el-breadcrumb 和el-breadcrumb-item, el-breadcrumb的spearator指定item的分隔符 el-breadcrumb-item的to和replace属性和vue-router的一致,需要结合vue_router一起使用 用法…

WSL安装Redis

前言 本来一直是在虚拟机的Ubuntu开发 但是 搞着搞着内存不足 导致我某些数据损坏了 然后目前迁移到Wsl开发 运行WSL的相较于虚拟机你不需要很多的性能开销! 我只是代码开发和git交互,如果是搞逆向还是虚拟机。 记录一下redis 安装卸载 免得以后又忘了…

【中等】机试-滑动窗口(双指针)-例:无重复字符的最长子串

※高频、重点 字节(飞书)、百度等大厂测开高频面试题:最长不重复子串 . - 力扣(LeetCode)字节飞书面经里的高频题,没做出来,需要好好复习。 重点考察-滑动窗口这个概念,自学记录一…

攻击者如何在日常网络资源中隐藏恶意软件

近二十年来,安全 Web 网关 (SWG) 一直在监控网络流量,以检测恶意软件、阻止恶意网站并保护企业免受基于 Web 的威胁。 然而,攻击者已经找到了许多绕过这些防御措施的方法,SquareX的安全研究人员对此进行了记录。 最危险的策略之…

【Linux】调试和Git及进度条实现

这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川 💖文章专栏:Linux入门到进阶 🌏代码仓库: 写在开头 现在您看到的是我的结论或想法,但在这背后凝结了大量的思考、经验和讨论 目录 1.…

LinkedHashMap 如何实现排序

目录 一、LinkedHashMap二、排序实现三、代码片段分析 一、LinkedHashMap LinkedHashMap 是 Java 中的一个集合类,它是 HashMap 的一个子类,继承了 HashMap 的所有特性,并且在此基础上增加了一个双向链表来维护元素的插入顺序或者访问顺序。L…

java的内存分配和回收机制

Java 与 C之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。 概述 垃圾收集(GC)需要完成的三件事情: 哪些内存需要回收?什么时候回收?如何回收&am…

CloudXR 套件扩展 XR 工作流

NVIDIA为开发者提供了一个先进的平台,开发者可以在该平台上使用全新NVIDIA CloudXR 套件来创建可扩展、品牌化的定制扩展现实(XR)产品。 NVIDIA CloudXR 套件基于全新架构而打造,是扩展XR生态的重要工具。它为开发者、专业人士和…

高级 API 性能:着色器

着色器通过使您能够控制渲染过程的各个方面,在图形编程中发挥着关键作用。它们在 GPU 上运行,负责操作顶点、像素和其他数据。 常规着色器计算着色器像素渲染顶点着色器几何体、域和外壳着色器 常规着色器 这些提示适用于所有类型的着色器。 推荐 避…

[产品管理-10]:NPDP新产品开发 - 8 - 波士顿矩阵(当下与未来)在产品市场战略方面的应用

目录 一、波士顿矩阵 理论基础 产品类型划分 分析步骤 重要性 注意事项 二、波士顿矩阵的应用实例 示例背景 数据收集与准备 绘制波士顿矩阵 产品线分类 制定战略对策 一、波士顿矩阵:现在 VS 未来 波士顿矩阵理论,又称市场增长率-相对市场份…

读构建可扩展分布式系统:方法与实践04应用服务

1. 应用服务 1.1. 任何系统的核心都在于实现应用需求的特定业务逻辑 1.2. 服务是可扩展软件系统的核心 1.2.1. 它们将契约定义为一个API,向客户端声明它们的能力 1.3. 应用服务器高度依赖于编程语言,但通常都会提供多线程编程模型,允许服…

Ubuntu系统使用Docker部署Jupyter Notebook并实现笔记云同步

文章目录 前言1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 前言 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook,并结合cpol…

Netty(零散记录)

Netty: 1、Netty三种IO 2、Netty和Reactor的 1、Netty对Reactor的支持 Netty的线程模型时基于Reactor模型实现的,Netty对Reactor三种模式都有非常好的支持,并做了一定的改善,一般情况下,在服务端会采用主从架构模型…