VMP 简单源码分析(.net)

news2024/12/23 0:43:22

虚拟机

获取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 NETCOREAPP
			invokeFlags = BindingFlags.DoNotWrapExceptions;
#else
			invokeFlags = BindingFlags.Default;
#endif

			var 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码
在这里插入图片描述
在这里插入图片描述
检测虚拟机
在这里插入图片描述
停掉调试线程
在这里插入图片描述
基于各种硬件特征生成标识符
判断软件是否在授权的硬件上运行
在这里插入图片描述

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

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

相关文章

如何利用工作流自定义一个AI智能体

选择平台 目前已经有不少大模型平台都提供自定义智能体的功能&#xff0c;比如 百度的文心 https://agents.baidu.com/ 阿里的百炼平台 https://bailian.console.aliyun.com/。 今天再来介绍一个平台扣子&#xff08;https://www.coze.cn/&#xff09;&#xff0c;扣子是…

贡献思维,CF1644E. Expand the Path

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1644E - Codeforces 二、解题报告 1、思路分析 很容易想明白被…

探秘WebSQL:轻松构建前端数据库

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 探秘WebSQL&#xff1a;轻松构建前端数据库 前言WebSQL简介WebSQL的基本操作WebSQL的实际应用WebSQL的局限性和替代方案 前言 在Web的世界里&#xff0c;我们总是追求更好的用户体验和更快的响应速度…

Conda安装rasterio报错

Conda安装rasterio报错 文章目录 Conda安装rasterio报错问题解决参考 问题 在conda环境中安装rasterio包之后&#xff0c;本来可以正常运行的&#xff0c;但是之后又重新安装了一个gdal&#xff0c;导致原来的引用rasterio的包的程序不可正常运行了 conda install rasterio c…

Gartner发布应对动荡、复杂和模糊世界的威胁形势指南:当前需要应对的12种不稳定性、不确定性、复杂和模糊的安全威胁

当今世界是动荡&#xff08;Volatile&#xff09;、复杂&#xff08;Complex&#xff09;和模糊&#xff08;Ambiguous&#xff09;的&#xff0c;随着组织追求数字化转型以及犯罪分子不断发展技术&#xff0c;由此产生的安全威胁也是波动性、不确定性、复杂性和模糊性的&#…

超实用|新能源汽车充电小程序开发,一键充电很简单!

随着城市化的加速&#xff0c;新能源汽车用户越来越多。由于电池容量和充电时间的限制&#xff0c;新能源汽车用户通常需要在城市各处寻找充电站&#xff0c;充电过程不仅需要耗费时间&#xff0c;而且对于新能源汽车用户而言&#xff0c;充电站的位置分布是否合理、充电设施的…

2024-5-7——摘樱桃 II

2024-5-7 题目来源我的题解方法一 记忆化搜索方法二 动态规划方法三 动态规划空间优化 题目来源 力扣每日一题&#xff1b;题序&#xff1a;1463 我的题解 题解参考灵神的解析 方法一 记忆化搜索 因为两个机器人是同时进行&#xff0c;理论上到达某一行的时间是相同的&…

机器人系统ros2内部接口介绍

内部 ROS 接口是公共 C API &#xff0c;供创建客户端库或添加新的底层中间件的开发人员使用&#xff0c;但不适合典型 ROS 用户使用。 ROS客户端库提供大多数 ROS 用户熟悉的面向用户的API&#xff0c;并且可能采用多种编程语言。 内部API架构概述 内部接口主要有两个&#x…

5V升9V2A升压恒压WT3231

5V升9V2A升压恒压WT3231 WT3231&#xff0c;一款性能卓越的DC-DC转换器&#xff0c;采用了集成10A、26mΩ功率的MOSFET电源开关转换器。它能够输出高达12V的电压&#xff0c;稳定可靠。这款产品以固定的600KHz运行&#xff0c;因此可以使用小型的外部感应器和电容器&#xff0…

Java 框架安全:Struts2 漏洞序列测试.

什么是 Struts2 框架 Struts 2 是一个用于创建企业级 Java 应用程序的开源框架。它是一个 MVC&#xff08;模型-视图-控制器&#xff09;框架&#xff0c;用于开发基于 Java EE&#xff08;Java Platform, Enterprise Edition&#xff09;的 Web 应用程序。Struts 2 主要解决…

flask网站开发计划

我想写一个flask开发网站的合集文章&#xff0c;该网站主要是采集网络上的文章&#xff08;不同站点&#xff0c;用Python识别出正文内容&#xff09;&#xff0c;然后做成长图形式&#xff0c;发布到flask站点&#xff0c;并提供“下载”按钮&#xff0c;点击下载按钮&#xf…

企业年中宣传的几个核心点

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 过了五一小长假&#xff0c;就来到了夏天&#xff0c;在生机勃勃的春天里&#xff0c;我们定好了全年的宣传计划&#xff0c;包括要举行哪些活动&#xff0c;参加哪些展会&#xff0c;一…

算法开篇==时间复杂度和空间复杂度

一、算法的时间复杂度 1.1 定义 衡量算法执行时间随着输入数据量增加而增加的速度。它通常用大O符号&#xff08;O&#xff09;表示&#xff0c;形式如O(n), O(), O()等&#xff0c;其中n代表输入数据的规模。 1.2 渐进分析 时间复杂度关注的是当输入数据量趋向于无穷大时&a…

LSS(Lift, Splat, Shoot)算法解析

1.简介 LSS(Lift, Splat, Shoot) 是一个比较经典的自下而上的构建BEV特征的3D目标检测算法&#xff0c;通过将图像特征反投影到3D空间生成伪视锥点云&#xff0c;通过Efficientnet算法提取云点的深度特征和图像特征并对深度信息进行估计&#xff0c;最终将点云特征转换到BEV空…

JETBRAINS IDES 分享一个2099通用试用码!IDEA 2024 版 ,支持一键升级

文章目录 废话不多说上教程&#xff1a;&#xff08;动画教程 图文教程&#xff09;一、动画教程激活 与 升级&#xff08;至最新版本&#xff09; 二、图文教程 &#xff08;推荐&#xff09;Stage 1.下载安装 toolbox-app&#xff08;全家桶管理工具&#xff09;Stage 2 : 下…

盲盒小程序怎么做?盲盒创业

盲盒作为当下的新兴行业&#xff0c;从出现就备受年轻消费者的追捧&#xff0c;成为了我国发展前景巨大的行业之一。盲盒市场不仅吸引了众多消费者&#xff0c;同时也吸引了更多的创业者&#xff0c;成为了一大创业新模式。 盲盒小程序是一种线上盲盒销售模式&#xff0c;以社…

赋能企业数字化转型 - 易点易动固定资产系统与飞书实现协同管理

在当前瞬息万变的商业环境下,企业如何借助信息化手段提升管理效率,已经成为摆在各行各业面前的紧迫课题。作为企业数字化转型的重要一环,固定资产管理的信息化建设更是不容忽视。 易点易动作为国内领先的企业资产管理服务商,凭借其全方位的固定资产管理解决方案,助力众多企业实…

Baidu Comate:你的智能编码助手,编程效率倍增的秘密武器

Baidu Comate智能编码助手 Baidu Comate 智能编码助手简单介绍安装使用查看Comate插件功能智能代码提示使用飞浆和百度智能小程序进行智能问答使用AutoWork插件实现二次函数图像的生成引用Comate知识库存在的问题结束语 Baidu Comate 智能编码助手简单介绍 Baidu Comate&#x…

信创 | 2023年中国信创产业深度研究报告(完整版)

信创产业研究报告 免责声明&#xff1a;本文资料来源于“第一新声”&#xff0c;版权归原作者所有。如涉及作品版权问题&#xff0c;请与我们联系&#xff0c;我们将在第一时间协商版权问题或删除内容&#xff01; 获取文中相关的PPT资料&#xff0c;请关注文末公众号“程序员…

创意自我介绍视频制作软件有哪些?

创意自我介绍视频制作软件 在制作创意自我介绍视频时&#xff0c;有许多软件可供选择。以下是一些推荐的软件&#xff1a; 乐秀视频剪辑&#xff1a;这是一个被8亿用户选择的视频剪辑、视频制作与Vlog剪辑工具。它提供了丰富的视频编辑功能&#xff0c;帮助用户制作出高质量的…