当前位置: 首页 > news >正文

VMP 简单源码分析(.net)

虚拟机

获取CPU的型号
在这里插入图片描述

实现了一个指令集解释器,每个操作码对应一个特定的处理函数,用于执行相应的指令操作。在执行字节码时,解释器会根据操作码查找并调用相应的处理函数来执行指令。
在这里插入图片描述
截获异常 先由虚拟机处理 处理不了再抛出异常

		private void Unwind(){_stack.Clear();_finallyStack.Clear();while (_tryStack.Count != 0){var catchBlocks = _tryStack.Peek().CatchBlocks();int startIndex = (_filterBlock == null) ? 0 : catchBlocks.IndexOf(_filterBlock) + 1;_filterBlock = null;for (var i = startIndex; i < catchBlocks.Count; i++){var current = catchBlocks[i];switch (current.Type()){case 0:var type = _exception.GetType();var type2 = GetType(current.Filter());if (type == type2 || type.IsSubclassOf(type2)){_tryStack.Pop();_stack.Push(new ObjectVariant(_exception));_pos = current.Handler();return;}break;case 1:_filterBlock = current;_stack.Push(new ObjectVariant(_exception));_pos = current.Filter();return;}}_tryStack.Pop();for (var i = catchBlocks.Count; i > 0; i--){var current = catchBlocks[i - 1];if (current.Type() == 2 || current.Type() == 4)_finallyStack.Push(current.Handler());}if (_finallyStack.Count != 0){_pos = _finallyStack.Pop();return;}}throw _exception;}

检查运算数据的类型
在这里插入图片描述
根据数据判断 实现无符号运算 以及运算溢出等的处理
同理的还有异或 减法等

		private BaseVariant Add(BaseVariant v1, BaseVariant v2, bool ovf, bool un){var type = CalcTypeCode(v1, v2);switch (type){case TypeCode.Int32:{int value;if (un){var value1 = v1.ToUInt32();var value2 = v2.ToUInt32();value = ovf ? (int)checked(value1 + value2) : (int)(value1 + value2);}else{var value1 = v1.ToInt32();var value2 = v2.ToInt32();value = ovf ? checked(value1 + value2) : (value1 + value2);}return new IntVariant(value);}case TypeCode.Int64:{long value;if (un){var value1 = v1.ToUInt64();var value2 = v2.ToUInt64();value = ovf ? (long)checked(value1 + value2) : (long)(value1 + value2);}else{var value1 = v1.ToInt64();var value2 = v2.ToInt64();value = ovf ? checked(value1 + value2) : (value1 + value2);}return new LongVariant(value);}case TypeCode.Single:{var value1 = (un ? v1.ToUnsigned() : v1).ToSingle();var value2 = (un ? v2.ToUnsigned() : v2).ToSingle();return new SingleVariant(ovf ? checked(value1 + value2) : (value1 + value2));}case TypeCode.Double:{var value1 = (un ? v1.ToUnsigned() : v1).ToDouble();var value2 = (un ? v2.ToUnsigned() : v2).ToDouble();return new DoubleVariant(ovf ? checked(value1 + value2) : (value1 + value2));}case TypeCode.UInt32:{int value;if (un){var value1 = v1.ToUInt32();var value2 = v2.ToUInt32();value = ovf ? (int)checked(value1 + value2) : (int)(value1 + value2);}else{var value1 = v1.ToInt32();var value2 = v2.ToInt32();value = ovf ? checked(value1 + value2) : (value1 + value2);}PointerVariant v = v1.CalcTypeCode() == type ? (PointerVariant)v1 : (PointerVariant)v2;unsafe{return new PointerVariant(Pointer.Box(new IntPtr(value).ToPointer(), v.Type()), v.Type());}}case TypeCode.UInt64:{long value;if (un){var value1 = v1.ToUInt64();var value2 = v2.ToUInt64();value = ovf ? (long)checked(value1 + value2) : (long)(value1 + value2);}else{var value1 = v1.ToInt64();var value2 = v2.ToInt64();value = ovf ? checked(value1 + value2) : (value1 + value2);}PointerVariant v = v1.CalcTypeCode() == type ? (PointerVariant)v1 : (PointerVariant)v2;unsafe{return new PointerVariant(Pointer.Box(new IntPtr(value).ToPointer(), v.Type()), v.Type());}}}throw new InvalidOperationException();}

获取目标程序框架
设置调用方法
支持实例方法、静态方法、虚拟方法和过滤方法

		private BaseVariant Call(MethodBase method, bool virt){BindingFlags invokeFlags;
#if NETCOREAPPinvokeFlags = BindingFlags.DoNotWrapExceptions;
#elseinvokeFlags = BindingFlags.Default;
#endifvar info = method as MethodInfo;var parameters = method.GetParameters();var refs = new Dictionary<int, BaseVariant>();var args = new object[parameters.Length];BaseVariant v;for (var i = parameters.Length - 1; i >= 0; i--){v = Pop();if (v.IsReference())refs[i] = v;args[i] = Convert(v, parameters[i].ParameterType).Value();}v = method.IsStatic ? null : Pop();object obj = v?.Value() ?? null;if (virt && obj == null)throw new NullReferenceException();object res = null;if (method.IsConstructor && method.DeclaringType.IsValueType){obj = Activator.CreateInstance(method.DeclaringType, invokeFlags, null, args, null);if (v != null && v.IsReference())v.SetValue(Convert(obj, method.DeclaringType).Value());}else if (!IsFilteredMethod(method, obj, ref res, args)){if (!virt && method.IsVirtual && !method.IsFinal){DynamicMethod dynamicMethod;var paramValues = new object[parameters.Length + 1];paramValues[0] = obj;for (var i = 0; i < parameters.Length; i++){paramValues[i + 1] = args[i];}lock (_dynamicMethodCache){if (!_dynamicMethodCache.TryGetValue(method, out dynamicMethod)){var paramTypes = new Type[paramValues.Length];paramTypes[0] = method.DeclaringType;for (var i = 0; i < parameters.Length; i++){paramTypes[i + 1] = parameters[i].ParameterType;}dynamicMethod = new DynamicMethod("", info != null && info.ReturnType != typeof(void) ? info.ReturnType : null, paramTypes, typeof(VirtualMachine).Module, true);var gen = dynamicMethod.GetILGenerator();gen.Emit(v.IsReference() ? System.Reflection.Emit.OpCodes.Ldarga : System.Reflection.Emit.OpCodes.Ldarg, 0);for (var i = 1; i < paramTypes.Length; i++){gen.Emit(refs.ContainsKey(i - 1) ? System.Reflection.Emit.OpCodes.Ldarga : System.Reflection.Emit.OpCodes.Ldarg, i);}gen.Emit(System.Reflection.Emit.OpCodes.Call, info);gen.Emit(System.Reflection.Emit.OpCodes.Ret);_dynamicMethodCache[method] = dynamicMethod;}}res = dynamicMethod.Invoke(null, invokeFlags, null, paramValues, null);foreach (var r in refs){r.Value.SetValue(paramValues[r.Key + 1]);}refs.Clear();}else{res = method.Invoke(obj, invokeFlags, null, args, null);}}foreach (var r in refs){r.Value.SetValue(args[r.Key]);}return (info != null && info.ReturnType != typeof(void)) ? Convert(res, info.ReturnType) : null;}

字符串管理

构造字典
在字典中得到字符串偏移 经过解密后返回字符串

		public string DecryptString(uint stringId){uint pos;if (_entries.TryGetValue(stringId, out pos)){var entry = new byte[16];Marshal.Copy(new IntPtr(_instance + pos), entry, 0, 16);entry = _cipher.Decrypt(entry);var size = BitConverter.ToInt32(entry, 8);var stringData = new byte[size];Marshal.Copy(new IntPtr(_instance + BitConverter.ToUInt32(entry, 4)), stringData, 0, size);for (var c = 0; c < size; c++){stringData[c] = (byte)(stringData[c] ^ BitRotate.Left(_key, c) + c);}return Encoding.Unicode.GetString(stringData);}return null;}

检测

校验文件 不同位置的CRC码
在这里插入图片描述
在这里插入图片描述
检测虚拟机
在这里插入图片描述
停掉调试线程
在这里插入图片描述
基于各种硬件特征生成标识符
判断软件是否在授权的硬件上运行
在这里插入图片描述

相关文章:

VMP 简单源码分析(.net)

虚拟机 获取CPU的型号 实现了一个指令集解释器&#xff0c;每个操作码对应一个特定的处理函数&#xff0c;用于执行相应的指令操作。在执行字节码时&#xff0c;解释器会根据操作码查找并调用相应的处理函数来执行指令。 截获异常 先由虚拟机处理 处理不了再抛出异常 priva…...

数据结构与算法学习笔记-二叉树的顺序存储表示法和实现(C语言)

目录 前言 1.数组和结构体相关的一些知识 1.数组 2.结构体数组 2.二叉树的顺序存储表示法和实现 1.定义 2.初始化 3.先序遍历二叉树 4.中序遍历二叉树 5.后序遍历二叉树 6.完整代码 前言 二叉树的非递归的表示和实现。 1.数组和结构体相关的一些知识 1.数组 在C语…...

如何在Windows和Linux中杀死Python进程

在开发和运行Python脚本的过程中&#xff0c;有时我们需要强制结束正在运行的Python进程。这可能是因为脚本运行出现了不可预见的错误&#xff0c;或者我们需要停止一个长时间执行的任务。无论原因如何&#xff0c;了解如何在不同操作系统中正确、安全地终止Python进程都是一项…...

零基础怎么快速进行单细胞分析?

近一段时间正在努力学习单细胞相关的理论知识&#xff0c;发现单细胞测序和普通的真核细胞的转录组非常相似。两者之间的最大的区别在于&#xff0c;一个测的是单个细胞的表达&#xff0c;一个测的是一堆细胞的表达之和。所以从这里就可以理解&#xff0c;为什么网上很多教程都…...

力扣数据库题库学习(5.10日)--1965. 丢失信息的雇员

1965. 丢失信息的雇员 问题链接&#x1f437; 思路分析 先看问题的描述 编写解决方案&#xff0c;找到所有 丢失信息 的雇员 id。当满足下面一个条件时&#xff0c;就被认为是雇员的信息丢失&#xff1a;雇员的 姓名 丢失了&#xff0c;或者雇员的 薪水信息 丢失了返回这些…...

漫威争锋Marvel Rivals怎么搜索 锁区怎么搜 游戏搜不到怎么办

即将问世的《漫威争锋》&#xff08;Marvel Rivals&#xff09;作为一款万众期待的PvP射击游戏新星&#xff0c;荣耀携手漫威官方网站共同推出。定档5月11日清晨9时&#xff0c;封闭Alpha测试阶段将正式揭开序幕&#xff0c;持续时间长达十天之久。在此首轮测试窗口&#xff0c…...

SpringBoot实现统一返回值+全局异常处理

在这里首先感谢的就是程序员老罗&#xff0c;从他的项目里面学到了这些东西。 首先就是去创建一个SpringBoot项目&#xff0c;这里我就不多做赘述了 封装一个统一返回对象 package com.example.demo.vo;public class ResponseVO<T> {private String status;private In…...

windows连接CentOS数据库或Tomcat报错,IP通的,端口正常监听

错误信息 数据库错误&#xff1a; ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x (10060) Tomcat访问错误&#xff1a; 响应时间过长 ERR_CONNECTION_TIMED_OUT 基础排查工作 【以下以3306端口为例&#xff0c;对于8080端口来说操作是一样的&#xff0c;只需…...

超详细的胎教级Stable Diffusion使用教程(一)

这套课程分为五节课&#xff0c;会系统性的介绍sd的全部功能和实操案例&#xff0c;让你打下坚实牢靠的基础 一、为什么要学Stable Diffusion&#xff0c;它究竟有多强大&#xff1f; 二、三分钟教你装好Stable Diffusion 三、小白快速上手Stable Diffusion 四、Stable dif…...

流媒体服务器(20)—— mediasoup 之媒体流score评分计算(一)

目录 前言 正文 《流媒体服务器》专栏总览丨蓄力计划_开源流媒体服务器对比-CSDN博客 前言 mediasoup 有一套评估媒体传输通道优劣的机制,主要是通过 score 评分来判断的。今天就先介绍一下这个机制的大体逻辑,后面的文章再详细介绍具体计算的算法。 正文 mediasoup 的…...

用keras识别狗狗

一、需求场景 从照片从识别出狗狗 from keras.applications.resnet50 import ResNet50 from keras.preprocessing import image from keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np# 加载预训练的ResNet50模型 model ResNet5…...

Sass语法介绍-变量介绍

02 【Sass语法介绍-变量】 sass有两种语法格式Sass(早期的缩进格式&#xff1a;Indented Sass)和SCSS(Sassy CSS) 目前最常用的是SCSS&#xff0c;任何css文件将后缀改为scss&#xff0c;都可以直接使用Sassy CSS语法编写。 所有有效的 CSS 也同样都是有效的 SCSS。 Sass语…...

可调恒流电子负载的基础认识

可调恒流电子负载是模拟真实负载的电子设备&#xff0c;它可以模拟各种不同类型和功率的负载。这种设备的主要功能是接收电源输入&#xff0c;然后以恒定的电流输出&#xff0c;以便对电源或电池进行测试和校准。 首先&#xff0c;我们需要了解什么是恒流&#xff0c;恒流是指在…...

开源模型应用落地-模型记忆增强-概念篇(一)

一、前言 语言模型的记忆是基于其训练数据。具体而言,对于较长的文本,模型可能会遗忘较早的信息,因为它的记忆是有限的,并且更容易受到最近出现的内容的影响。模型无法跨越其固定的上下文窗口,而是根据当前上下文生成回应。 提升模型记忆能力有多种方法,比如改进模型的结…...

SAPUI5基础知识1 - 概览,库,支持工具,自学教程

1. SAPUI5 概览 1.1 SAPUI5 SAPUI5是一种用于构建企业级Web应用程序的开发框架。它是由SAP开发的&#xff0c;基于HTML5、CSS3和JavaScript技术。 SAPUI5提供了一套丰富的UI控件和工具&#xff0c;使开发人员能够快速构建现代化、可扩展和可定制的应用程序。 它还提供了数据…...

常见的获取dom元素的方法

获取 DOM 元素是前端开发中非常常见的操作。以下是几种常用的方法来获取 DOM 元素&#xff0c;以及它们的适用场景和示例&#xff1a; 1. getElementById 用于获取具有指定 id 属性的元素。 示例 let element document.getElementById(myId); 2. getElementsByClassName …...

走进CHEN MEI HUA的设计哲学:书写东方女性力量与态度的时尚篇章

在时尚的舞台中央&#xff0c;品牌不止是商品&#xff0c;更是故事的讲述者、文化的传承者。CHEN MEI HUA&#xff0c;一个源自中国上海的高端女装品牌&#xff0c;以其独特的设计理念及文化内核&#xff0c;成为了时尚界一颗耀眼的明珠。今天&#xff0c;让我们一起走进CMH的世…...

ESrally单机向量检索性能测试全流程

ESrally单机向量检索性能测试全流程 测试方案的尝试 准备测试 ES 的向量检索性能,Vespa 方案由于下载依赖库存在网络问题无法执行成功,终止;开源工具 ann-benchamrk 是一个用于评估近似最近邻(ANN)搜索库的性能测试工具,这个本是最佳选择,但是也由于需要 pip 安装几十…...

小红书释放被封手机号 无限注册

前几年抖音也可以释放被封手机号 那时候都不重视 导致现在被封手机号想释放 基本不可能的 或者就是最少几百块 有专业的人帮你通过某些信息差释放 本教程是拆解 小红书被封手机号怎么释放&#xff0c;从今年开始&#xff0c;被封的手机号无法注销了 所以很困扰 那么本教程来…...

Docker快速启动清单

以下容器均使用 Docker version 24.0.2 版本测试使用&#xff0c;这里需要注意一下&#xff0c;高版本的Docker不支持镜像V1版本&#xff0c;不知道怎么操作才可以让它支持&#xff0c;所以推荐使用低版本 如果觉得不直观&#xff0c;或者觉得有点乱&#xff0c;可以访问以下网…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...