public void TestMoveTo() { var stack = CreateOrderedStack(3); var other = new EvaluationStack(new ReferenceCounter()); stack.MoveTo(other, 0); Assert.AreEqual(3, stack.Count); Assert.AreEqual(0, other.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, stack.ToArray()); stack.MoveTo(other, -1); Assert.AreEqual(0, stack.Count); Assert.AreEqual(3, other.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, other.ToArray()); // Test IEnumerable var enumerable = (IEnumerable)other; var enumerator = enumerable.GetEnumerator(); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, GetEnumerable(enumerator).Cast <Integer>().ToArray()); other.MoveTo(stack, 2); Assert.AreEqual(2, stack.Count); Assert.AreEqual(1, other.Count); CollectionAssert.AreEqual(new Integer[] { 2, 3 }, stack.ToArray()); CollectionAssert.AreEqual(new Integer[] { 1 }, other.ToArray()); }
private bool CheckArraySize(OpCode nextInstruction) { int size; switch (nextInstruction) { case OpCode.PACK: case OpCode.NEWARRAY: case OpCode.NEWSTRUCT: { if (EvaluationStack.Count == 0) { return(false); } size = (int)EvaluationStack.Peek().GetBigInteger(); } break; case OpCode.SETITEM: { if (EvaluationStack.Count < 3) { return(false); } if (!(EvaluationStack.Peek(2) is Map map)) { return(true); } StackItem key = EvaluationStack.Peek(1); if (key is ICollection) { return(false); } if (map.ContainsKey(key)) { return(true); } size = map.Count + 1; } break; case OpCode.APPEND: { if (EvaluationStack.Count < 2) { return(false); } if (!(EvaluationStack.Peek(1) is Array array)) { return(false); } size = array.Count + 1; } break; default: return(true); } return(size <= MaxArraySize); }
private bool CheckArraySize() { const uint MaxArraySize = 1024; if (CurrentContext.InstructionPointer >= CurrentContext.Script.Length) { return(true); } OpCode opcode = CurrentContext.NextInstruction; switch (opcode) { case OpCode.PACK: case OpCode.NEWARRAY: { if (EvaluationStack.Count == 0) { return(false); } int size = (int)EvaluationStack.Peek().GetBigInteger(); if (size > MaxArraySize) { return(false); } return(true); } default: return(true); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'ldind' instruction load an address onto the evaluation stack"); var esType = stack.Pop(); CheckIsAPointer(il, esType); var pointer = esType.ToType(); if (pointer.IsByRef) { var elementType = pointer.GetElementType(); if (elementType.IsValueType) CheckCanBeAssigned(il, type.MakeByRefType(), pointer); else CheckCanBeAssigned(il, type, elementType); } else if (pointer.IsPointer) { var elementType = pointer.GetElementType(); if (elementType.IsValueType) CheckCanBeAssigned(il, type.MakePointerType(), pointer); else CheckCanBeAssigned(il, type, elementType); } else if (!type.IsPrimitive && type != typeof(object)) ThrowError(il, $"Unable to load an instance of type '{Formatter.Format(type)}' from a pointer of type '{Formatter.Format(pointer)}' indirectly"); stack.Push(type); }
static void Run(AssemblyHolder holder, string[] cmdLine) { try { EvaluationStack stack = new EvaluationStack(); stack.Push(new ObjectReferenceValue(cmdLine)); ParameterValues paramVals = stack.Perform_CallMethod(holder.Assembly.EntryPoint,false); Exception exc; IntVisitor.InterpretMethod(holder,holder.EntryPoint,paramVals,out exc,""); if (exc != null) { Console.WriteLine( "-------------------------\n"+ "CIL interpreter catched unhandled exception:\n"+ exc ); } Console.WriteLine("-------------------------\nPress Enter..."); Console.ReadLine(); } catch (ConvertionException) { Console.WriteLine("Conversion to CFG failed !"); } }
public void TestCopyTo() { var stack = CreateOrderedStack(3); var copy = new EvaluationStack(new ReferenceCounter()); Assert.ThrowsException <ArgumentOutOfRangeException>(() => stack.CopyTo(copy, -2)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => stack.CopyTo(copy, 4)); stack.CopyTo(copy, 0); Assert.AreEqual(3, stack.Count); Assert.AreEqual(0, copy.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, stack.ToArray()); stack.CopyTo(copy, -1); Assert.AreEqual(3, stack.Count); Assert.AreEqual(3, copy.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, stack.ToArray()); // Test IEnumerable var enumerable = (IEnumerable)copy; var enumerator = enumerable.GetEnumerator(); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, GetEnumerable(enumerator).Cast <Integer>().ToArray()); copy.CopyTo(stack, 2); Assert.AreEqual(5, stack.Count); Assert.AreEqual(3, copy.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3, 2, 3 }, stack.ToArray()); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, copy.ToArray()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (stack.Count != 0) { throw new InvalidOperationException("The evaluation stack must be empty in order to perform the 'jmp' instruction\r\n" + il.GetILCode()); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'newarr' instruction a length of an array must be loaded onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); stack.Push(type.MakeArrayType()); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var type = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "An object must be put onto the evaluation stack in order to perform the 'unbox_any' instruction"); CheckCanBeAssigned(il, typeof(object), stack.Pop()); stack.Push(type); }
/// <summary> /// Assert result stack /// </summary> /// <param name="stack">Stack</param> /// <param name="result">Result</param> /// <param name="message">Message</param> private void AssertResult(VMUTStackItem[] result, EvaluationStack stack, string message) { AssertAreEqual(stack.Count, result == null ? 0 : result.Length, message + "Stack is different"); for (int x = 0, max = stack.Count; x < max; x++) { AssertAreEqual(ItemToJson(stack.Peek(x)).ToString(Formatting.None), PrepareJsonItem(result[x]).ToString(Formatting.None), message + "Stack item is different"); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'ckfinite' instruction an instance must be loaded onto the evaluation stack"); var peek = stack.Peek(); if (ToCLIType(peek) != CLIType.Float) { ThrowError(il, $"It is only allowed to check if value is finite for floating point values but was '{peek}'"); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => $"In order to perform the instruction 'localloc' size must be loaded onto the evaluation stack"); var type = stack.Pop(); if (ToCLIType(type) != CLIType.NativeInt) { ThrowError(il, $"Unable to perform the instruction 'localloc' on type '{type}'"); } stack.Push(typeof(UIntPtr)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var labels = ((LabelsILInstructionParameter)parameter).Labels; CheckNotEmpty(il, stack, () => "A value must be put onto the evaluation stack in order to perform the 'switch' instruction"); CheckNotStruct(il, stack.Pop()); foreach (var label in labels) { SaveOrCheck(il, stack, label); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => $"In order to perform the instruction '{opCode}' an instance must be loaded onto the evaluation stack"); var type = stack.Pop(); if (!Allowed(type)) { ThrowError(il, $"Unable to perform the instruction '{opCode}' on type '{type}'"); } stack.Push(to); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'neg' operation an instance must be put onto the evaluation stack"); var esType = stack.Pop(); var cliType = ToCLIType(esType); if (cliType != CLIType.Int32 && cliType != CLIType.Int64 && cliType != CLIType.NativeInt && cliType != CLIType.Float && cliType != CLIType.Zero) { ThrowError(il, $"Unable to perform the 'neg' operation on type '{esType}'"); } stack.Push(Canonize(esType)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'ldlen' instruction an array must be loaded onto the evaluation stack"); var esType = stack.Pop(); var array = esType.ToType(); if (!array.IsArray && array != typeof(Array)) { ThrowError(il, string.Format("An array expected but was '{0}'", esType)); } stack.Push(typeof(int)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var constructor = ((ConstructorILInstructionParameter)parameter).Constructor; var parameterTypes = ReflectionExtensions.GetParameterTypes(constructor); for (var i = parameterTypes.Length - 1; i >= 0; --i) { CheckNotEmpty(il, stack, () => $"Expected exactly {parameterTypes.Length} parameters to call the constructor '{Formatter.Format(constructor)}'"); CheckCanBeAssigned(il, parameterTypes[i], stack.Pop()); } stack.Push(constructor.ReflectedType); }
protected virtual long GetPrice() { if (CurrentContext.InstructionPointer >= CurrentContext.Script.Length) { return(0); } OpCode opcode = CurrentContext.NextInstruction; if (opcode <= OpCode.PUSH16) { return(0); } switch (opcode) { case OpCode.NOP: return(0); case OpCode.APPCALL: case OpCode.TAILCALL: return(10); case OpCode.SYSCALL: return(GetPriceForSysCall()); case OpCode.SHA1: case OpCode.SHA256: return(10); case OpCode.HASH160: case OpCode.HASH256: return(20); case OpCode.CHECKSIG: return(100); case OpCode.CHECKMULTISIG: { if (EvaluationStack.Count == 0) { return(1); } int n = (int)EvaluationStack.Peek().GetBigInteger(); if (n < 1) { return(1); } return(100 * n); } default: return(1); } }
private bool CheckItemSize() { const uint MaxItemSize = 1024 * 1024; if (CurrentContext.InstructionPointer >= CurrentContext.Script.Length) { return(true); } OpCode opcode = CurrentContext.NextInstruction; switch (opcode) { case OpCode.PUSHDATA4: { if (CurrentContext.InstructionPointer + 4 >= CurrentContext.Script.Length) { return(false); } uint length = CurrentContext.Script.ToUInt32(CurrentContext.InstructionPointer + 1); if (length > MaxItemSize) { return(false); } return(true); } case OpCode.CAT: { if (EvaluationStack.Count < 2) { return(false); } int length; try { length = EvaluationStack.Peek(0).GetByteArray().Length + EvaluationStack.Peek(1).GetByteArray().Length; } catch (NotSupportedException) { return(false); } if (length > MaxItemSize) { return(false); } return(true); } default: return(true); } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => "In order to perform the 'not' operation an instance must be put onto the evaluation stack"); var esType = stack.Pop(); var cliType = ToCLIType(esType); if (cliType != CLIType.Int32 && cliType != CLIType.Int64 && cliType != CLIType.NativeInt && cliType != CLIType.Zero) { ThrowError(il, string.Format("Unable to perform the 'not' operation on type '{0}'", esType)); } // !zero = -1 -> native int stack.Push(cliType == CLIType.Zero ? typeof(IntPtr) : Canonize(esType)); }
private void StartImportingBasicBlock(BasicBlock basicBlock) { _stack.Clear(); if (basicBlock.EntryStack != null) { EvaluationStack <StackEntry> entryStack = basicBlock.EntryStack; int n = entryStack.Length; for (int i = 0; i < n; i++) { _stack.Push(entryStack[i].Duplicate()); } } }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (parameter is TypeILInstructionParameter) { stack.Push(typeof(RuntimeTypeHandle)); } if (parameter is MethodILInstructionParameter) { stack.Push(typeof(RuntimeMethodHandle)); } if (parameter is FieldILInstructionParameter) { stack.Push(typeof(RuntimeFieldHandle)); } }
EvaluationStack CreateOrderedStack(int count) { var check = new Integer[count]; var stack = new EvaluationStack(new ReferenceCounter()); for (int x = 1; x <= count; x++) { stack.Push(x); check[x - 1] = x; } Assert.AreEqual(count, stack.Count); CollectionAssert.AreEqual(check, stack.ToArray()); return(stack); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { var elementType = ((TypeILInstructionParameter)parameter).Type; CheckNotEmpty(il, stack, () => "In order to perform the 'ldelema' instruction an index must be put onto the evaluation stack"); CheckCanBeAssigned(il, typeof(int), stack.Pop()); CheckNotEmpty(il, stack, () => "In order to perform the 'ldelema' instruction an array must be put onto the evaluation stack"); var esType = stack.Pop(); var array = esType.ToType(); if (!array.IsArray && array != typeof(Array)) { throw new InvalidOperationException(string.Format("An array expected to perform the 'ldelema' instruction but was '{0}'", esType)); } stack.Push(elementType.MakeByRefType()); }
private bool CheckStackSize(OpCode nextInstruction) { int size = 0; if (nextInstruction <= OpCode.PUSH16) { size = 1; } else { switch (nextInstruction) { case OpCode.DEPTH: case OpCode.DUP: case OpCode.OVER: case OpCode.TUCK: { size = 1; break; } case OpCode.UNPACK: { StackItem item = EvaluationStack.Peek(); if (!(item is Neo.VM.Types.Array ar)) { return(false); } size = ar.Count; break; } } } if (size == 0) { return(true); } size += EvaluationStack.Count + AltStack.Count; if (size > MaxStackSize) { return(false); } return(true); }
protected virtual long GetPrice(OpCode nextInstruction) { TR.Enter(); if (nextInstruction <= OpCode.PUSH16) { return(TR.Exit(0)); } switch (nextInstruction) { case OpCode.NOP: return(TR.Exit(0)); case OpCode.APPCALL: case OpCode.TAILCALL: return(TR.Exit(10)); case OpCode.SYSCALL: return(TR.Exit(GetPriceForSysCall())); case OpCode.SHA1: case OpCode.SHA256: return(TR.Exit(10)); case OpCode.HASH160: case OpCode.HASH256: return(TR.Exit(20)); case OpCode.CHECKSIG: return(TR.Exit(100)); case OpCode.CHECKMULTISIG: { if (EvaluationStack.Count == 0) { return(TR.Exit(1)); } int n = (int)EvaluationStack.Peek().GetBigInteger(); if (n < 1) { return(TR.Exit(1)); } return(TR.Exit(100 * n)); } default: return(TR.Exit(1)); } }
private bool CheckStackSize() { const uint MaxStackSize = 2 * 1024; if (CurrentContext.InstructionPointer >= CurrentContext.Script.Length) { return(true); } int size = 0; OpCode opcode = CurrentContext.NextInstruction; if (opcode <= OpCode.PUSH16) { size = 1; } else { switch (opcode) { case OpCode.DEPTH: case OpCode.DUP: case OpCode.OVER: case OpCode.TUCK: size = 1; break; case OpCode.UNPACK: StackItem item = EvaluationStack.Peek(); if (!item.IsArray) { return(false); } size = item.GetArray().Length; break; } } if (size == 0) { return(true); } size += EvaluationStack.Count + AltStack.Count; if (size > MaxStackSize) { return(false); } return(true); }
private bool CheckStackSize(OpCode nextInstruction) { TR.Enter(); int size = 0; if (nextInstruction <= OpCode.PUSH16) { size = 1; } else { switch (nextInstruction) { case OpCode.DEPTH: case OpCode.DUP: case OpCode.OVER: case OpCode.TUCK: case OpCode.NEWMAP: size = 1; break; case OpCode.UNPACK: StackItem item = EvaluationStack.Peek(); if (item is Array array) { size = array.Count; } else { return(TR.Exit(false)); } break; } } if (size == 0) { return(TR.Exit(true)); } size += EvaluationStack.Count + AltStack.Count; if (size > MaxStackSize) { return(TR.Exit(false)); } return(TR.Exit(true)); }
public AnnotatedMethod GetAnnotatedMethod(MethodBase sMethod) { AnnotatedMethod aMethod = this.aMethods[sMethod] as AnnotatedMethod; if (aMethod == null) { ParameterInfo[] parms = sMethod.GetParameters(); EvaluationStack stack = new EvaluationStack(); if (! sMethod.IsStatic) stack.Push(new ReferenceBTValue(BTType.Dynamic)); for (int i = 0; i < parms.Length; i++) stack.Push(new ReferenceBTValue(BTType.Dynamic)); ParameterValues paramVals = stack.Perform_CallMethod(sMethod, false); ReferenceBTValue ret = ReferenceBTValue.NewReferenceBTValue(Annotation.GetReturnType(sMethod), BTType.Dynamic); this.aMethods[sMethod] = aMethod = new AnnotatedMethod(paramVals, ret); } return aMethod; }
public void TestInsertPeek() { var stack = new EvaluationStack(new ReferenceCounter()); stack.Insert(0, 3); stack.Insert(1, 1); stack.Insert(1, 2); Assert.ThrowsException <InvalidOperationException>(() => stack.Insert(4, 2)); Assert.AreEqual(3, stack.Count); CollectionAssert.AreEqual(new Integer[] { 1, 2, 3 }, stack.ToArray()); Assert.AreEqual(3, stack.Peek(0)); Assert.AreEqual(2, stack.Peek(1)); Assert.AreEqual(1, stack.Peek(-1)); Assert.ThrowsException <InvalidOperationException>(() => stack.Peek(-4)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { CheckNotEmpty(il, stack, () => $"Expected two arguments for the operation '{opCode}'"); var right = stack.Pop(); CheckNotEmpty(il, stack, () => $"Expected two arguments for the operation '{opCode}'"); var left = stack.Pop(); if (!IsAllowed(ToCLIType(left), ToCLIType(right))) { ThrowError(il, $"Cannot perform the instruction '{opCode}' on types '{left}' and '{right}'"); } var result = Canonize(GetResultType(Canonize(left), Canonize(right))); if (result != typeof(void)) { stack.Push(result); } PostAction(il, parameter, ref stack); }
private bool CheckStackSize(OpCode nextInstruction) { int size = 0; if (nextInstruction <= OpCode.PUSH16) { size = 1; } else { switch (nextInstruction) { case OpCode.DEPTH: case OpCode.DUP: case OpCode.OVER: case OpCode.TUCK: size = 1; break; case OpCode.UNPACK: StackItem item = EvaluationStack.Peek(); if (!item.IsArray) { return(false); } size = item.GetArray().Length; break; } } if (size == 0) { return(true); } size += EvaluationStack.Count + AltStack.Count; if (size > MaxStackSize) { return(false); } return(true); }
private void ImportFallthrough(BasicBlock next) { EvaluationStack<StackEntry> entryStack = next.EntryStack; if (entryStack != null) { if (entryStack.Length != _stack.Length) throw new InvalidProgramException(); for (int i = 0; i < entryStack.Length; i++) { // TODO: Do we need to allow conversions? if (entryStack[i].Kind != _stack[i].Kind) throw new InvalidProgramException(); if (entryStack[i].Kind == StackValueKind.ValueType) { if (entryStack[i].Type != _stack[i].Type) throw new InvalidProgramException(); } } } else { if (_stack.Length > 0) { entryStack = new EvaluationStack<StackEntry>(_stack.Length); for (int i = 0; i < _stack.Length; i++) { entryStack.Push(NewSpillSlot(_stack[i])); } } next.EntryStack = entryStack; } if (entryStack != null) { for (int i = 0; i < entryStack.Length; i++) { AppendLine(); Append(entryStack[i]); Append(" = "); Append(_stack[i]); AppendSemicolon(); } } MarkBasicBlock(next); }