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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开源投票系统源码及搭建 在线投票活动创建系统的设计与开发

在当今数字化时代&#xff0c;在线投票活动已成为各类组织、企业和个人不可或缺的一部分。无论是选举、问卷调查、产品评选还是其他需要收集公众意见的场景&#xff0c;一个高效、稳定且易于使用的在线投票系统都至关重要。 分享一款基于开源投票系统源码的在线投票活动创建系…

设计模式Java实现-建造者模式

楔子 小七在2019年的时候&#xff0c;就想写一个关于设计模式的专栏&#xff0c;但是最终却半途而废了。粗略一想&#xff0c;如果做完一件事要100分钟&#xff0c;小七用3分钟热情做的事&#xff0c;最少也能完成10件事情了。所以这一次&#xff0c;一定要把他做完&#xff0…

ICode国际青少年编程竞赛- Python-1级训练场-综合训练1

ICode国际青少年编程竞赛- Python-1级训练场-综合训练1 1、 Spaceship.turnLeft() for i in range(2):Spaceship.turnLeft()Spaceship.step(3) Dev.step(-1) Spaceship.step(4) Spaceship.turnLeft() Spaceship.step(3)2、 Spaceship.step() Spaceship.turnLeft() Spaceship.…

学QT的第一天~

#include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { //窗口相关设置// this->resize(427,330); this->setFixedSize(427,330); //设置图标 this->setWindowIcon(QIcon("C:\\Users\\Admin\\Desktop\\pictrue\\dahz.jpg&q…

【面试经典 150 | 分治】建立四叉树

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;递归 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

C语言写的LLM训练

特斯拉前 AI 总监、OpenAI 创始团队成员 Andrej Karpathy 用 C 代码完成了 GPT-2 大模型训练过程&#xff1a;karpathy/llm.c: LLM training in simple, raw C/CUDA (github.com) 下载源码 git clone --recursive https://github.com/karpathy/llm.c.git下载模型 从HF-Mirro…

JavaScript中的RegExp和Cookie

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 &#x1f506;RegExp &#x1f3b2; 1 什么是正则表达式 &#x1f3b2;2 创建…

组件化开发根组件

目录 一、组件化开发介绍 二、根组件 一、组件化开发介绍 组件化&#xff1a;一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为。 好处&#xff1a;便于维护&#xff0c;利于复用&#xff0c;提升开发效率。 二、根组件 组件分类&#xff…

MindSponge分子动力学模拟——安装与使用

技术背景 昇思MindSpore是由华为主导的一个&#xff0c;面向全场景构建最佳昇腾匹配、支持多处理器架构的开放AI框架。MindSpore不仅仅是软件层面的工具&#xff0c;更重要的是可以协同华为自研的昇腾Ascend平台&#xff0c;做到软硬件一体的行业解决方案。基于MindSpore的高通…

Gin 框架的使用

1、Gin 快速开发 1.1、环境准备 1.1.1、导入 gin 依赖 这里就叫 gin 依赖了&#xff0c;在 Goland 命令行中输入下面的命令&#xff1a; go get -u github.com/gin-gonic/gin 1.1.2、设置代理 如果下载失败&#xff0c;最好设置一下代理&#xff0c;在 cmd 命令行中输入下…

react【实用教程】 搭建开发环境(2024版)Vite+React (官方推荐)

以项目名 reactDemo为例 1. 下载脚手架 在目标文件夹中打开命令行 npm create vite2. 安装项目依赖 cd reactDemo npm i若安装失败&#xff0c;则修改下载源重试 npm config set registry https://registry.npmmirror.com3. 启动项目 npm run dev4. 预览项目 浏览器访问 http…

亚马逊FBA头程多少钱一公斤?FBA头程怎么收费?

在亚马逊的电商生态中&#xff0c;FBA服务已经成为许多卖家提升客户满意度和销售效率的重要工具&#xff0c;然而&#xff0c;对于使用FBA服务的卖家来说&#xff0c;选择一家合适的物流合作伙伴并了解其FBA头程的收费标准和计费方式同样至关重要&#xff0c;亚马逊FBA头程多少…

Elsevier——投稿系统遇到bug时的解决方法

重要&#xff1a;找期刊客服&#xff01;&#xff01;&#xff01; 一、方法&#xff1a; 1. 点击进入与官方客服的对话 2. 按要求输入个人信息 3. 输入遇到的问题 比如&#xff1a; 主题&#xff1a;The Current Status is jammed. 详细描述&#xff1a;The Current State o…

XSS-Labs 靶场通过解析(上)

前言 XSS-Labs靶场是一个专门用于学习和练习跨站脚本攻击&#xff08;XSS&#xff09;技术的在线平台。它提供了一系列的实验场景和演示&#xff0c;帮助安全研究人员、开发人员和安全爱好者深入了解XSS攻击的原理和防御方法。 XSS-Labs靶场的主要特点和功能包括&#xff1a;…

数据结构:线性表(详解)

线性表 线性表的知识框架&#xff1a; 线性表的定义&#xff1a; 线性表是具有相同数据类型的n(n > 0)个数据元素的有限序列&#xff0c;当n 0时线性表为一个空表。 若用L命名为线性表&#xff0c;则数据集合为L {a1,a2,…,an}&#xff0c;其中a1称为表头元素&#xff0c…

【方法】如何创建RAR格式压缩文件?

为了方便存储或者传输文件&#xff0c;我们经常会把文件打包成不同格式的压缩包&#xff0c;那如果想创建的是RAR格式的压缩包&#xff0c;要如何做呢&#xff1f; RAR是WinRAR软件独有的压缩格式&#xff0c;所以我们可以通过WinRAR软件来创建RAR格式压缩包。下面分享两种创建…

02_SpringBoot程序快速启动

目录 打包命令启动启动成功测试结果 打包 点击package打包命令&#xff0c;会生成target目录&#xff0c;目录下会有生成的jar包 命令启动 打开cmd命令窗口&#xff0c;进入子项目的target目录下,输入命令后&#xff0c;回车… java -jar .\note-boot-core-1.0-SNAPSHOT.j…

一起深度学习

CIFAR-10 卷积神经网络 下载数据集构建网络运行测试 下载数据集 batchsz 32cifar_train datasets.CIFAR10(data,trainTrue,transformtorchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()]),downloadTrue)cifar_train …

电脑录屏什么软件好?网友力荐的3款软件!

随着电脑的使用越来越广泛&#xff0c;电脑录屏软件也成为了人们日常生活中经常需要使用到的工具。无论是录制游戏画面、教程演示还是远程教育&#xff0c;一款优秀的电脑录屏软件都能为用户提供极大的帮助&#xff0c;可是电脑录屏什么软件好呢&#xff1f;本文将为大家介绍3款…

图形存储与处理在AI去衣技术中的关键角色

引言&#xff1a; 随着人工智能技术的不断进步&#xff0c;AI去衣技术作为一种颇具争议的应用&#xff0c;已经引起了广泛的关注。该技术依托于深度学习、计算机视觉等领域的先进成果&#xff0c;通过分析图像内容实现对人物衣物的识别和去除。在这一过程中&#xff0c;图形存储…