VMP 简单源码分析(.net)

虚拟机

获取CPU的型号

实现了一个指令集解释器,每个操作码对应一个特定的处理函数,用于执行相应的指令操作。在执行字节码时,解释器会根据操作码查找并调用相应的处理函数来执行指令。

截获异常 先由虚拟机处理 处理不了再抛出异常

javascript 复制代码
		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;
		}

检查运算数据的类型

根据数据判断 实现无符号运算 以及运算溢出等的处理

同理的还有异或 减法等

javascript 复制代码
		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();
		}

获取目标程序框架

设置调用方法

支持实例方法、静态方法、虚拟方法和过滤方法

javascript 复制代码
		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;
		}

字符串管理

构造字典

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

javascript 复制代码
		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码

检测虚拟机

停掉调试线程

基于各种硬件特征生成标识符

判断软件是否在授权的硬件上运行

相关推荐
百事牛科技7 小时前
WinRAR注释功能:给压缩包留个便签
windows·winrar
小蒋观天下7 小时前
两轮车检测AI摄像头——2026行业竞争格局、商业模式与核心痛点
大数据·人工智能·安全·计算机视觉·ai大模型
sukalot8 小时前
Windows 驱动实例分析系列:libwdi 驱动分析 - examples 篇(一)
windows·驱动开发
小蒋观天下9 小时前
两轮车检测AI摄像头——2026-2030年未来市场规模、增长逻辑与行业天花板
大数据·人工智能·安全·计算机视觉·ai大模型
加载力科技9 小时前
硬盘咔咔响是坏盘信号!赶在数据丢失前克隆换盘:不重装系统、不丢文件
windows·嵌入式硬件·系统安全·策略模式·命令模式·硬盘
yu_zhidun10 小时前
企业管理者看:员工上网行为管理软件,别再只靠网关“赌安全”
大数据·人工智能·安全·域智盾
2601_9623649711 小时前
电脑人脸解锁的安全基石,聊聊 Windows Hello 硬件规范
windows·安全·电脑
重明链迹实验室12 小时前
重明链迹丨每周区块链安全要闻(0921-0927)
安全·web3·区块链
AOXU_Consulting14 小时前
医用吊塔:手术室和 ICU 天花板上那根“臂“是做什么的
安全·健康医疗
程序员JerrySUN14 小时前
Jetson边缘嵌入式实战课程第四讲:用 Yocto 定制 Jetson 系统,从开发走向产品化
arm开发·人工智能·安全·计算机视觉·目标跟踪