mirror of
https://github.com/Obfuscator-Collections/VMProtect.git
synced 2026-09-01 14:04:43 +03:00
first commit
Version 3.x.x
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace UnitTestProject
|
||||
{
|
||||
public abstract class MsilToVmTestCompiler
|
||||
{
|
||||
public enum LongEnum : long { Eval1 = 1, Evalm1 = -1 }
|
||||
public enum ULongEnum : ulong { Evalm1 = 0xFFFFFFFFFFFFFFFF }
|
||||
public enum ByteEnum : byte {}
|
||||
public enum SByteEnum : sbyte { }
|
||||
public enum IntEnum /*: int*/ { }
|
||||
public enum UIntEnum : uint { }
|
||||
public enum ShortEnum : short { }
|
||||
public enum UShortEnum : ushort { }
|
||||
|
||||
public static byte[] GetIlBytes(DynamicMethod dynamicMethod)
|
||||
{
|
||||
// ReSharper disable once PossibleNullReferenceException
|
||||
var resolver = typeof(DynamicMethod).GetField("m_resolver", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(dynamicMethod);
|
||||
if (resolver == null) throw new ArgumentException("The dynamic method's IL has not been finalized.");
|
||||
// ReSharper disable once PossibleNullReferenceException
|
||||
return (byte[])resolver.GetType().GetField("m_code", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(resolver);
|
||||
}
|
||||
|
||||
public abstract Stream CreateVmStream(Type rt, ParameterInfo[] pi, Type[] locals, byte[] ilBytes);
|
||||
|
||||
public enum InvokeTestCombineError
|
||||
{
|
||||
NoError,
|
||||
NoErrorByStdEx, // текущий стандарт ECMA-335 оставляет некоторые сценарии как "неопределенное поведение", но их можно определить
|
||||
VmOtherExceptionExpected,
|
||||
VmOtherTypeExpected,
|
||||
VmOtherValueExpected,
|
||||
Cnt
|
||||
};
|
||||
// dyn/vm обязаны что-то возвратить, либо выбросить исключение
|
||||
// (в тестах не должно быть методов, возвращающих void, null или исключение в качестве retVal)
|
||||
[HandleProcessCorruptedStateExceptions]
|
||||
public InvokeTestCombineError InvokeTestCombine(DynamicMethod dyn, object[] parameters, out object dynRet, out object vmRet, out string err)
|
||||
{
|
||||
Type exceptionType = null;
|
||||
err = "";
|
||||
try
|
||||
{
|
||||
dynRet = dyn.Invoke(null, parameters);
|
||||
Assert.IsNotNull(dynRet);
|
||||
Assert.IsInstanceOfType(dynRet, dyn.ReturnType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Assert.IsInstanceOfType(e, typeof(TargetInvocationException));
|
||||
Assert.IsNotNull(e.InnerException);
|
||||
exceptionType = e.InnerException.GetType();
|
||||
dynRet = e.InnerException;
|
||||
}
|
||||
var vmStream = CreateVmStream(dyn.ReturnType, dyn.GetBaseDefinition().GetParameters(),
|
||||
//FIXME dyn.GetMethodBody().LocalVariables.Select(o => o.LocalType).ToArray(),
|
||||
new Type[] {},
|
||||
GetIlBytes(dyn));
|
||||
try
|
||||
{
|
||||
vmRet = Invoke(parameters, vmStream);
|
||||
if(exceptionType != null)
|
||||
{
|
||||
err = $"VmOtherExceptionExpected: {exceptionType.FullName}, actual: {vmRet}";
|
||||
return InvokeTestCombineError.VmOtherExceptionExpected;
|
||||
}
|
||||
if (vmRet == null || vmRet.GetType() != dyn.ReturnType)
|
||||
{
|
||||
err = $"VmOtherTypeExpected: {dyn.ReturnType.FullName}, actual: {((vmRet != null) ? vmRet.GetType().FullName : "null")}";
|
||||
return InvokeTestCombineError.VmOtherTypeExpected;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
vmRet = e;
|
||||
if (e.GetType() != exceptionType)
|
||||
{
|
||||
err = $"VmOtherExceptionExpected: {((exceptionType != null) ? exceptionType.FullName : dynRet)}, actual: {e.GetType().FullName}";
|
||||
return InvokeTestCombineError.VmOtherExceptionExpected;
|
||||
}
|
||||
return InvokeTestCombineError.NoError;
|
||||
}
|
||||
if (dynRet.Equals(vmRet))
|
||||
{
|
||||
return InvokeTestCombineError.NoError;
|
||||
}
|
||||
err = $"VmOtherValueExpected: {dynRet}, actual: {vmRet}";
|
||||
return InvokeTestCombineError.VmOtherValueExpected;
|
||||
}
|
||||
|
||||
public abstract object Invoke(object[] parameters, Stream vmStream);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user