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