VMP 简单源码分析(.net)

2024-05-07 12:36
文章标签 分析 简单 源码 net vmp

本文主要是介绍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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/967370

相关文章

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

使用easy connect之后,maven无法使用,原来需要配置-Djava.net.preferIPv4Stack=true问题

《使用easyconnect之后,maven无法使用,原来需要配置-Djava.net.preferIPv4Stack=true问题》:本文主要介绍使用easyconnect之后,maven无法... 目录使用easGWowCy connect之后,maven无法使用,原来需要配置-DJava.net.pr

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel