首页 > 编程语言 >.NET 使用ILPack组件将程序集保存成dll

.NET 使用ILPack组件将程序集保存成dll

时间:2023-06-13 22:35:05浏览次数:39  
标签:string ILPack Emit dll il var NET method

本文介绍使用ILPack组件将程序集保存成dll

.net core 版本不再支持使用 AssemblyBuilder.Save 的方式将程序集保存成dll

具体讨论 https://github.com/dotnet/runtime/issues/15704

可以使用ILPack组件将程序集保存成dll,以下为官方案例

var assembly = Assembly.GetAssembly(t);
var generator = new Lokad.ILPack.AssemblyGenerator();

// for ad-hoc serialization
var bytes = generator.GenerateAssemblyBytes(assembly);

// direct serialization to disk
generator.GenerateAssembly(assembly, "/path/to/file");

实际应用

在实际应用中可以使用该组件进行对编写的动态代码进行反编译验证逻辑,以下为具体案例

  1. 首先写了一个较为复杂的IL方法
        public static void CreateEscapeQuotesMethod()
        {
            var method = new DynamicMethod("EscapeQuotes", typeof(string), new Type[1] { typeof(string) });
            IL_EscapeQuotes(method.GetILGenerator());
            ILPackVerification.Save(method, IL_EscapeQuotes);
            var methodDelegate = method.CreateDelegate<Func<string, string>>();
            string result = (string)methodDelegate.DynamicInvoke("dafdasf");
            Console.WriteLine(result);
            static void IL_EscapeQuotes(ILGenerator il)
            {
                il.DeclareLocal(typeof(string));
                var lb = il.DefineLabel();
                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldarg_0);//将第一个参数放置到堆栈上
                il.Emit(OpCodes.Ldstr, "\"");
                il.Emit(OpCodes.Ldstr, "\\\"");
                il.Emit(OpCodes.Call, typeof(string).GetMethod(nameof(string.Replace), new Type[2] { typeof(string), typeof(string) }));
                il.Emit(OpCodes.Stloc_0);//将栈顶元素存储到本地变量0中
                il.Emit(OpCodes.Br_S, lb);
                il.MarkLabel(lb);
                il.Emit(OpCodes.Ldloc_0);// 将本地变量表中索引为0的变量加载到堆栈中
                il.Emit(OpCodes.Ret);
            }
        }
  1. 使用ILPack将程序集转存成dll文件
    public class ILPackVerification
    {
        public static ModuleBuilder Builder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ILTest.Dynamic"), AssemblyBuilderAccess.Run).DefineDynamicModule("TestDynamicModule");
        public static void Save(DynamicMethod method, Action<ILGenerator> setIL)
        {
            var type = Builder.DefineType("ILPackVerificationClass", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed);
            var newMethod = type.DefineMethod(method.Name, method.Attributes, method.ReturnType, method.GetParameters().Select(v => v.ParameterType).ToArray());
            setIL(newMethod.GetILGenerator());
            Console.WriteLine("方法:" + method.Name + "开始保存...");

            Save(type.CreateType());
        }

        public static void Save(Type type)
        {
            var assembly = Assembly.GetAssembly(type);
            Console.WriteLine("类:" + type.Name + "开始保存...");

            Save(assembly);
        }

        public static void Save(Assembly dynamicAssembly)
        {
            var generator = new Lokad.ILPack.AssemblyGenerator();

            generator.GenerateAssembly(dynamicAssembly, "/dils.dll");
            Console.WriteLine("DLL输出成功!");
        }
    }
  1. 生成dll

  2. 使用ILSpay工具查看反编译之后的代码

总结

通过以上方式能够将动态程序集保存成dll文件,再通过反编译工具查看代码的逻辑,此方式可以用来验证IL代码是否编写正确(其中一种方法)。

源码地址

https://github.com/Impartsoft/ILLesson

标签:string,ILPack,Emit,dll,il,var,NET,method
From: https://www.cnblogs.com/Iannnnnnnnnnnnn/p/17478869.html

相关文章

  • 使用NSTimer和CGAffineTransformMakeRotation实现旋转动画
     使用NSTimer和CGAffineTransformMakeRotation实现旋转动画 首先定义需要用到的变量   floatangle;   NSTimer*timer; #pragmamark------------------->旋转图片<--------------------(void)_doRotateImage{//演员初始化UIImageView*ivImage=[[UII......
  • 卷积神经网络(LeNet)
    目录1.卷积神经网络(LeNet)1.1LeNet1.卷积神经网络(LeNet)\(LeNet\)最早的卷积神经网络之一(\(1989\)年提出)。用于银行支票上手写数字识别(\(1998\)年杨立坤教授提出)。1.1LeNet\(LeNet\)\((LeNet-5)\)由两部分组成:卷积编码器:由\(2\)个卷积层。全连接层密集块:由\(......
  • 关于Qt **QNetworkAccessManager**、**QNetworkReply**、**QNetworkRequest**实现ftp
    实现的ftp下载需要反馈下载进度,但是代码得到的bytesTotal始终为-1,直到下载完成那一刻,才变成文件大小。于是分析qt5base的network部分代码:network/access/qnetworkaccessftpbackend.cpp文件中,有如下片段:voidQNetworkAccessFtpBackend::ftpRawCommandReply(intcode,constQStr......
  • .NET指定图片地址下载并转换Base64字符串
    需求描述    需要调用第三方图片上传接口上传图片,对方图片格式只能接收Base64字符串。所以我们需要将系统服务器的图片通过Url下载下来,然后转换成Base64字符串。接下来我们将使用HttpClient类库下载图片并将其转换为Base64格式的字符串。代码示例///<summary>......
  • Kubernetes 1.27 快速安装指南
    环境说明硬件环境虚拟机硬件规格:4CPU8G内存127G硬盘空间虚拟机数量:3台虚拟机操作系统:Ubuntu20.04虚拟化平台:hyper-v三台虚拟机的命名为node1node2node3其中node1为master承载控制平面,其余两台机器node2node3作为worknode三台虚拟机的ip地址分别为19......
  • Kubernetes中Deployment、ReplicaSet、Pod、Service的概念及关系
    Kubernetes中Deployment、ReplicaSet、Pod、Service的概念及关系Pod:k8s管理的最小单位,包括一个或多个容器,是提供实际业务服务的组件。ReplicaSet:是Pod的管理控制组件,监控Pod的健康状况,保障Pod按照用户的期望去运行。rs是ReplicationController组件的升级版,增加了标签选择器的范......
  • .Net7基础类型的优化和循环克隆优化
    前言.Net7里面对于基础类型的优化,是必不可少的。因为这些基础类型基本上都会经常用到,本篇除了基础类型的优化介绍之外,还有一个循环克隆的优化特性,也一并看下。概括1.基础类型优化基础类型的优化不会有些不会涉及ASM,主要是记忆。一:double.Parse和float.Parse,把某数值转换成d......
  • .NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方
    此实现不是Windows平台FIPS验证的加密算法的一部分。”)的问题,如下图所示:对于上面的问题,只需要修改下注册表即可处理,方法如下:1、以管理员方式启动命令行工具后输入regedit,回车打开注册器;。2、打开注册表后,进入路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Co......
  • RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2 新增解压缩工具类ZipHelper
    在项目对文件进行解压缩是非常常用的功能,对文件进行压缩存储或传输可以节省流量与空间。压缩文件的格式与方法都比较多,比较常用的国际标准是zip格式。压缩与解压缩的方法也很多,在.NET2.0开始,在System.IO.Compression中微软已经给我们提供了解压缩的方法GZipStream。对于GZipSt......
  • RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2-新增记录SQL执行过程
    有时我们需要记录整个系统运行的SQL以作分析,特别是在上线前这对我们做内部测试也非常有帮助,当然记录SQL的方法有很多,也可以使用三方的组件。3.2版本我们在框架底层新增了记录框架运行的所有SQl过程保存到用户指定的地方以便分析查看,只需要在配置文件把配置项”LogSQL”设置为Tr......