c#安全-nativeAOT

news2025/1/16 22:02:31

文章目录

    • 前记
    • AOT测试
    • 反序列化
    • Emit

前记

JIT\AOT

JIT编译器(Just-in-Time Complier),AOT编译器(Ahead-of-Time Complier)。

在这里插入图片描述

AOT测试

首先编译一段普通代码

using System;
using System.Runtime.InteropServices;
namespace coleak
{
    class winfun
    {
        [DllImport("User32.dll")]
        public static extern int MessageBox(IntPtr h, string m, string c, uint type);
        [DllImport("kernel32.dll", EntryPoint = "Beep")]
        public static extern bool mymethod(uint frequency, uint duration);
    }
        class Program
    {
            static void Main(string[] args)
            {
            winfun winfun = new winfun();
            winfun.MessageBox((IntPtr)0, "yueyy", "coleak",(uint) 0);
            Random random = new Random();
            for (int i = 0; i < 10000; i++)
            {
                winfun.mymethod((uint)random.Next(10000), 100);
            }
            Console.ReadLine();
            }
    }
}

和csc直接编译相比,AOT发布确实可以防止dnspy出源码,但不能解决反汇编,该加壳还是得加壳

优点

不依赖.net框架环境也可以运行
不会被直接反编译而导致代码泄露

缺点

不能Assembly.Load进行动态加载
不支持32位程序

示例如下

using System;
using System.Reflection;
namespace LoadExe
{
    class Program
    {
        static void Main(string[] args)
{
    string base64string = @"";
    byte[] Buffer = Convert.FromBase64String(base64string);
    Assembly assembly = Assembly.Load(Buffer);
    Type type = assembly.GetType("DemoExe.Test");
    MethodInfo method = type.GetMethod("TestMethod");
    Object obj = assembly.CreateInstance(method.Name);
    method.Invoke(obj, null);
}
    }
}
Unhandled Exception: System.PlatformNotSupportedException: Operation is not supported on this platform.
   at Internal.Reflection.Execution.AssemblyBinderImplementation.Bind(ReadOnlySpan`1, ReadOnlySpan`1, AssemblyBindResult&, Exception&) + 0x39
   at System.Reflection.Runtime.Assemblies.RuntimeAssemblyInfo.GetRuntimeAssemblyFromByteArray(ReadOnlySpan`1, ReadOnlySpan`1) + 0x58
   at System.Reflection.Assembly.Load(Byte[], Byte[]) + 0xbe
   at LoadExe.Program.Main(String[] args) + 0x25
   at nativeAOT!<BaseAddress>+0x114a40

但是部分反射api仍然有效

using System;
using System.Reflection;
namespace LoadExe
{
    class Program
    {
        public static void Main()
        {
            Console.Write("Name of type: ");
            string typeName = "LoadExe.Program";
            string methodName = "SayHello";
            Type.GetType(typeName).GetMethod(methodName).Invoke(null, null);
            Console.ReadKey();
        }

        public static void SayHello()
        {
            Console.WriteLine("Hello!");
        }
    }
}

具体规则如下

1.APIs that don’t work and will not work

  • APIs that require dynamic code generation: Reflection.Emit, Assembly.Load and friends
  • Obvious program introspection APIs: APIs on Type and Assembly not mentioned above, MethodBase, MethodInfo, ConstructorInfo, FieldInfo, PropertyInfo, EventInfo. These APIs will throw at runtime.
  • APIs building on top of reflection APIs. Too many to enumerate.

2.Reflection-free mode supports a limited set of reflection APIs that keep their expected semantics.

  • typeof(SomeType) will return a System.Type that can be compared with results of other typeof expressions or results of Object.GetType() calls. The patterns commonly used in perf optimizations of generic code (e.g. typeof(T) == typeof(byte)) will work fine, and so will obj.GetType() == typeof(SomeType).
  • Following APIs on System.Type work: TypeHandle, UnderlyingSystemType, BaseType, IsByRefLike, IsValueType, GetTypeCode, GetHashCode, GetElementType, GetInterfaces, HasElementType, IsArray, IsByRef, IsPointer, IsPrimitive, IsAssignableFrom, IsAssignableTo, IsInstanceOfType.
  • Activator.CreateInstance() will work. The compiler statically analyzes and expands this to efficient code at compile time. No reflection is involved at runtime.
  • Assembly.GetExecutingAssembly() will return a System.Reflection.Assembly that can be compared with other runtime Assembly instances. This is mostly to make it possible to use the NativeLibrary.SetDllImportResolver API.

反序列化

JSON格式

using System;
using System.Runtime.Serialization.Json;//添加的引用
namespace ConsoleApp1
{
    public class Book
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public float Price { get; set; }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            //序列化json
            Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
            DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(Book));
            using (MemoryStream stream = new MemoryStream())
            {
                formatter.WriteObject(stream, book);
                string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
                Console.WriteLine(result);
            }
            Console.WriteLine();

            //反序列化json
            string oriStr = "{\"ID\":102,\"Name\":\"C# wpf程序设计\",\"Price\":100}";
            DataContractJsonSerializer formatter1 = new DataContractJsonSerializer(typeof(Book));
            using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(oriStr)))
            {
                Book outBook = formatter1.ReadObject(stream) as Book;
                Console.WriteLine(outBook.ID);
                Console.WriteLine(outBook.Name);
                Console.WriteLine(outBook.Price);
            }
            Console.ReadLine();
        }
    }
}

Emit

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {

        static void Main(string[] args)
        {

            CreateAssembly();
            Console.ReadKey();
        }

        public static void CreateAssembly()
        {
            StringBuilder asmFileNameBldr = new StringBuilder();
            //定义一个程序集的名称
            var asmName = new AssemblyName("MyAssembly");
            //首先就需要定义一个程序集
            AssemblyBuilder defAssembly = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndCollect);
            //定义一个构建类DefineDynamicModule
            ModuleBuilder defModuleBuilder = defAssembly.DefineDynamicModule("MyModule");

            //定义一个类
            TypeBuilder typeBuilder = defModuleBuilder.DefineType("MyModule.MyClass", TypeAttributes.Public);

            //定义一个方法
            var defMethodBuilder = typeBuilder.DefineMethod("MyMethod",
                MethodAttributes.Public,
                null,//返回类型
                null//参数类型
                );
            Console.WriteLine($"程序集信息:{typeBuilder.Assembly.FullName}");
            Console.WriteLine($"命名空间:{typeBuilder.Namespace} , 类型:{typeBuilder.Name}");
            //获取IL生成器
            var il = defMethodBuilder.GetILGenerator();
            //定义一个字符串
            il.Emit(OpCodes.Ldstr, "coleak");
            //调用一个函数
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            //返回到方法开始(返回)
            il.Emit(OpCodes.Ret);
            //创建类型
            Type dynamicType = typeBuilder.CreateType();
            object ass = Activator.CreateInstance(dynamicType);
            dynamicType.GetMethod("MyMethod").Invoke(ass, null);
        }
    }
}

.NET Framework 中,有 RunAndSave 、Save 等枚举,可用于保存构建的程序集,但是在 .NET Core 中,是没有这些枚举的,也就是说,Emit 构建的程序集只能在内存中,是无法保存成 .dll 文件的

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

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

相关文章

Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(三)

八、ui窗体创建要点 .h文件定义(popwindowf.h)&#xff0c; TEST_TYPE_WINDOW宏是要创建的窗口样式。 #pragma once #include <gtk/gtk.h> G_BEGIN_DECLS #define TEST_TYPE_WINDOW (test_window_get_type()) G_DECLARE_FINAL_TYPE (TestWindow, test_window, TEST, WI…

专业140+总分420+河海大学863信号与系统考研经验电子信息通信与信息技术,真题,大纲,参考书。

今年的成绩出来倍感欣慰&#xff0c;决定考研的时候并没有想到自己可以考出420的分数&#xff0c;通过自己一年来的努力&#xff0c;成功上岸&#xff0c;期中专业课863信号与系统140接近满分&#xff08;非常感谢信息通信Jenny老师的专业课辅导和平时悉心答疑&#xff0c;不厌…

Zoho Mail企业邮箱商业扩展第3部分:计算财务状况

在Zoho Mail商业扩展系列的压轴篇章中&#xff0c;王雪琳利用Zoho Mail的集成功能成功地完成了各项工作&#xff0c;并顺利地建立了自己的营销代理机构。让我们快速回顾一下她的成功之路。 一、使用Zoho Mail成功方法概述 首先她通过Zoho Mail为其电子邮件地址设置了自定义域…

入门指南|Chat GPT 的兴起:它如何改变数字营销格局?

随着数字营销的不断发展&#xff0c;支持数字营销的技术也在不断发展。OpenAI 的 ChatGPT 是一项备受关注的突破性工具。凭借其先进的自然语言处理能力&#xff0c;ChatGPT 已被证明是全球营销人员的宝贵资产。在这份入门指南中&#xff0c;我们将探讨Chat GPT对数字营销专家及…

文心一言 VS 讯飞星火 VS chatgpt (198)-- 算法导论14.3 6题

六、用go语言&#xff0c;说明如何来维护一个支持操作MIN-GAP的一些数的动态集Q&#xff0c;使得该操作能给出Q中两个最接近的数之间的差值。例如&#xff0c;Q(1&#xff0c;5&#xff0c;9&#xff0c;15&#xff0c;18&#xff0c;22)&#xff0c;则MIN-GAP返回18-153&#…

发文新思路!双流卷积!CWT-DSCNN-MSA基于时序特征、cwt小波时频图的双流卷积融合注意力机制的故障识别程序!直接运行!

适用平台&#xff1a;Matlab2023版本及以上 本程序参考中文EI期刊《电力自动化设备》2023年12月29号网络首发文献&#xff1a;《基于格拉姆角场与并行CNN的并网逆变器开关管健康诊断》,此外&#xff0c;在此基础上进一步对模型进行多重改进&#xff0c;每个人都可以构造属于自…

幻兽帕鲁服务器创建私服教程(新版教程更简单)

幻兽帕鲁官方服务器不稳定&#xff1f;自己搭建幻兽帕鲁服务器&#xff0c;低延迟、稳定不卡&#xff0c;目前阿里云和腾讯云均推出幻兽帕鲁专用服务器&#xff0c;腾讯云直接提供幻兽帕鲁镜像系统&#xff0c;阿里云通过计算巢服务&#xff0c;均可以一键部署&#xff0c;鼠标…

二维差分---三维差分算法笔记

文章目录 一.二维差分构造差分二维数组二维差分算法状态dp求b[i][j]数组的二维前缀和图解 二.三维前缀和与差分三维前缀和图解:三维差分核心公式图解:模板题 一.二维差分 给定一个原二维数组a[i][j],若要给a[i][j]中以(x1,y1)和(x2,y2)为对角线的子矩阵中每个数都加上一个常数…

金融信贷风控评分卡模型

评分卡模型概念 评分模型是根据借款人的历史数据&#xff0c;选取不同维度的数据类型&#xff0c;通过计算而得出的对借款人信用情况打分的模型。不同等级的信用分数代表了借款人信用情况的好坏&#xff0c;以此来分析借款人按时还款的可能性。 评分卡模型分类 A卡&#xff…

【linux系统体验】-archlinux折腾日记

archlinux 一、系统安装二、系统配置及美化2.1 中文输入法2.2 安装virtualbox增强工具2.3 终端美化 三、问题总结3.1 终端中文乱码 一、系统安装 安装步骤人们已经总结了很多很全: Arch Linux图文安装教程 大体步骤&#xff1a; 磁盘分区安装 Linux内核配置系统&#xff08;…

过渡效果的艺术:CSS transition 让网页交互更平滑(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

JavaWeb:调出Maven面板

问题描述 情况说明&#xff1a;IDEA中找不到Maven面板&#xff0c;Maven面板如下图所示&#xff1a; 解决方案 选择 View > Appearance > Tool Window Bars&#xff1a; 然后就会出现Maven面板了。

5G技术对物联网的影响

随着数字化转型的加速&#xff0c;5G技术作为通信领域的一次重大革新&#xff0c;正在对物联网&#xff08;IoT&#xff09;产生深远的影响。对于刚入行的朋友们来说&#xff0c;理解5G技术及其对物联网应用的意义&#xff0c;是把握行业发展趋势的关键。 让我们简单了解什么是…

力扣hot100 -- 双指针

目录 &#x1f382;移动零 &#x1f319;盛最多水的容器 &#x1f33c;三数之和 &#x1f33c;接雨水 前缀和 辅助数组 双指针 单调栈 &#x1f382;移动零 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 关于swap #include <iostream> #include <vec…

FastJson、Jackson使用AOP切面进行日志打印异常

FastJson、Jackson使用AOP切面进行日志打印异常 一、概述 1、问题详情 使用FastJson、Jackson进行日志打印时分别包如下错误&#xff1a; 源码&#xff1a; //fastjon log.info("\nRequest Info :{} \n"&#xff0c; JSON.toJSONString(requestInfo)); //jackson …

ubuntu22.04安装部署03: 设置root密码

一、前言 ubuntu22.04 安装完成以后&#xff0c;默认root用户是没有设置密码的&#xff0c;需要手动设置。具体的设置过程如下文内容所示&#xff1a; 相关文件&#xff1a; 《ubuntu22.04装部署01&#xff1a;禁用内核更新》 《ubuntu22.04装部署02&#xff1a;禁用显卡更…

剑指offer——二维数组中的查找(杨氏矩阵)

目录 1. 题目描述2. 常见错误思路3. 分析3.1 特例分析3.2 规律总结 4. 完整代码 1. 题目描述 在一个二维数组中&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个函数&#xff0c;输入这样的一个二维数组和一个整数&…

黄金交易策略(Nerve Nnife):大K线对技术指标的影响

我们使用heiken ashi smoothed来做敏感指标&#xff08;大趋势借助其转向趋势预判&#xff0c;但不是马上转变&#xff09;&#xff0c;has默认使用6根k线的移动平均值来做计算的。若在6根k线规范内有一个突变的行情&#xff08;k线很长&#xff09;&#xff0c;那么整个行情的…

基于鲲鹏服务器的LNMP配置

基于鲲鹏服务器的LNMP配置 系统 Centos8 # cat /etc/redhat-release CentOS Linux release 8.0.1905 (Core) 卸载已经存在的旧版本的安装包 # rpm -qa | grep php #查看已经安装的PHP旧版本# rpm -qa | grep php | xargs rpm -e #卸载已经安装的旧版&#xff0c;如果提示有…

CSP-202112-1-序列查询

CSP-202112-1-序列查询 提示&#xff1a;若存在区间[i,j) 满足&#xff1a;f(i)f(i1)…f(j-1)&#xff0c;使用乘法运算 f(i)x(j-i)代替将 f()到 f(j- 1)逐个相加,或可大幅提高算法效率。 一定要看提示&#xff01;单纯的模拟时间会超限&#xff01;算法也是根据提示设计的。 …