public IEnumerable <ValidationResult> Validate(Mono.Cecil.Cil.Instruction instruction, MethodDefinition method) { if (!(instruction.Operand is MemberReference reference)) { return(Enumerable.Empty <ValidationResult>()); } if (reference is MethodReference methodReference) { var validationResults = new List <ValidationResult>(); validationResults.AddRange(this.ValidateReference(method, methodReference.DeclaringType, methodReference.Name)); validationResults.AddRange(this.ValidateReference(method, methodReference.ReturnType)); return(validationResults); } if (reference is FieldReference fieldReference) { var validationResults = new List <ValidationResult>(); validationResults.AddRange(this.ValidateReference(method, fieldReference.DeclaringType, fieldReference.Name)); validationResults.AddRange(this.ValidateReference(method, fieldReference.FieldType)); return(validationResults); } if (reference is TypeReference typeReference) { return(this.ValidateReference(method, typeReference)); } return(Enumerable.Empty <ValidationResult>()); }
private void ReplaceValue(Mono.Cecil.Cil.Instruction instruction, string value, string fieldName) { var previous = instruction.Previous; if (previous.OpCode == Mono.Cecil.Cil.OpCodes.Ldc_I4_0 || previous.OpCode == Mono.Cecil.Cil.OpCodes.Ldc_I4_1) { previous.OpCode = value.AsBool() ? Mono.Cecil.Cil.OpCodes.Ldc_I4_1 : Mono.Cecil.Cil.OpCodes.Ldc_I4_0; return; } if (previous.OpCode == Mono.Cecil.Cil.OpCodes.Ldnull && value != null) { previous.OpCode = Mono.Cecil.Cil.OpCodes.Ldstr; } else if (previous.Operand == null) { return; } var operandType = previous.Operand != null?previous.Operand.GetType() : typeof(string); object replacement = ConvertReplacement(operandType, value); if (replacement != null) { previous.Operand = replacement; } else { LogWarning($"Value to set field {fieldName} is null, check the desired environment variable is set"); } }
/// <summary> /// Creates a CIL instruction that is emitted and patched /// afterward. /// </summary> /// <param name="op">The CIL instruction to emit.</param> /// <param name="patch"> /// An action that patches the instruction. /// </param> public CilOpInstruction( CilInstruction op, Action <CilInstruction, IReadOnlyDictionary <BasicBlockTag, CilInstruction> > patch) { this.Op = op; this.Patch = patch; }
private AnalysisNet.IInstruction ProcessSwitch(Cecil.Cil.Instruction op) { Cecil.Cil.Instruction[] targets = op.Operand as Cecil.Cil.Instruction[]; AnalysisNetBytecode.SwitchInstruction instruction = new AnalysisNetBytecode.SwitchInstruction((uint)op.Offset, targets.Select(t => (uint)t.Offset)); return(instruction); }
private AnalysisNet.IInstruction ProcessCreateArray(Cecil.Cil.Instruction op) { Cecil.ArrayType cciArrayType = Cecil.Rocks.TypeReferenceRocks.MakeArrayType(op.Operand as Cecil.TypeReference); AnalysisNet.Types.ArrayType ourArrayType = typeExtractor.ExtractType(cciArrayType) as AnalysisNet.Types.ArrayType; return(CreateArray((uint)op.Offset, ourArrayType)); }
private AnalysisNet.IInstruction ProcessLoadArrayElement(Cecil.Cil.Instruction op, AnalysisNetBytecode.LoadArrayElementOperation operation) { AnalysisNet.Types.ArrayType arrayType = null; switch (op.OpCode.Code) { /*case Mono.Cecil.Cil.Code.Array_Addr: * case Mono.Cecil.Cil.Code.Array_Create: * case Mono.Cecil.Cil.Code.Array_Create_WithLowerBound: * case Mono.Cecil.Cil.Code.Array_Get: * case Mono.Cecil.Cil.Code.Array_Set: * arrayType = typeExtractor.ExtractType(op.Operand as Cecil.TypeReference) as ArrayType; * break;*/ //case Mono.Cecil.Cil.Code.Ldelem: case Mono.Cecil.Cil.Code.Ldelem_Any: case Mono.Cecil.Cil.Code.Ldelema: arrayType = new AnalysisNet.Types.ArrayType(typeExtractor.ExtractType(op.Operand as Cecil.TypeReference)); break; default: arrayType = new AnalysisNet.Types.ArrayType(OperationHelper.GetOperationType(op.OpCode.Code)); break; } if (arrayType == null) { throw new NotImplementedException(); } AnalysisNetBytecode.LoadArrayElementInstruction instruction = new AnalysisNetBytecode.LoadArrayElementInstruction((uint)op.Offset, operation, arrayType); return(instruction); }
private AnalysisNet.IInstruction ProcessStoreArrayElement(Cecil.Cil.Instruction op) { AnalysisNet.Types.ArrayType arrayType = null; switch (op.OpCode.Code) { //case Mono.Cecil.Cil.Code.Array_Set: // arrayType = typeExtractor.ExtractType(op.Operand as Cecil.TypeReference) as ArrayType; // break; //case Mono.Cecil.Cil.Code.Stelem: case Mono.Cecil.Cil.Code.Stelem_Any: AnalysisNet.Types.IType extractedType = typeExtractor.ExtractType(op.Operand as Cecil.TypeReference); arrayType = new AnalysisNet.Types.ArrayType(extractedType); break; default: arrayType = new AnalysisNet.Types.ArrayType(OperationHelper.GetOperationType(op.OpCode.Code)); break; } if (arrayType == null) { throw new NotImplementedException(); } AnalysisNetBytecode.StoreArrayElementInstruction instruction = new AnalysisNetBytecode.StoreArrayElementInstruction((uint)op.Offset, arrayType); return(instruction); }
private AnalysisNet.IInstruction ProcessConversion(Cecil.Cil.Instruction op) { AnalysisNetBytecode.ConvertOperation operation = OperationHelper.ToConvertOperation(op.OpCode.Code); bool overflow = OperationHelper.PerformsOverflowCheck(op.OpCode.Code); bool unsigned = OperationHelper.OperandsAreUnsigned(op.OpCode.Code); Cecil.TypeReference cciType = op.Operand as Cecil.TypeReference; AnalysisNet.Types.IType ourType = OperationHelper.GetOperationType(op.OpCode.Code); if (operation == AnalysisNetBytecode.ConvertOperation.Box) { ourType = typeExtractor.ExtractType(cciType); } else if (operation == AnalysisNetBytecode.ConvertOperation.Conv) { ourType = OperationHelper.GetOperationType(op.OpCode.Code); } else if (operation == AnalysisNetBytecode.ConvertOperation.Cast) { ourType = typeExtractor.ExtractType(op.Operand as Cecil.TypeReference); } AnalysisNetBytecode.ConvertInstruction instruction = new AnalysisNetBytecode.ConvertInstruction((uint)op.Offset, operation, ourType) { OverflowCheck = overflow, UnsignedOperands = unsigned }; return(instruction); }
private AnalysisNet.IInstruction ProcessMethodCall(Cecil.Cil.Instruction op) { AnalysisNetBytecode.MethodCallOperation operation = OperationHelper.ToMethodCallOperation(op.OpCode.Code); Cecil.MethodReference cciMethod = op.Operand as Cecil.MethodReference; AnalysisNet.Types.IMethodReference ourMethod = typeExtractor.ExtractMethod(cciMethod); AnalysisNet.IInstruction instruction; if (ourMethod.ContainingType is FakeArrayType fakeArrayType) { AnalysisNet.Types.ArrayType arrayType = fakeArrayType.Type; if (ourMethod.Name == "Set") { instruction = ProcessStoreArrayElement(op, arrayType); return(instruction); } else { AnalysisNetBytecode.LoadArrayElementOperation arrayOp = OperationHelper.ToLoadArrayElementOperation(ourMethod.Name); instruction = ProcessLoadArrayElement(op, arrayOp, arrayType); return(instruction); } } instruction = new AnalysisNetBytecode.MethodCallInstruction((uint)op.Offset, operation, ourMethod); return(instruction); }
/// <summary> /// Checks to see if the instruction includes a multidimensional array and /// if so attempts to reconstruct the instruction as a normal (1d) array /// operation (.ctor, getter or setter) and resolve that instead. /// </summary> /// <returns><c>true</c>, if multidimensional array was successfully /// reconstructed as a 1d array instruction and successfully resolved, /// <c>false</c> otherwise.</returns> /// <param name="instruction">An instruction.</param> /// <param name="method">The method which contains the instruction.</param> /// <param name="type">The type which contains the method and instruction.</param> /// <param name="scope">The scope of the instruction (name of assembly).</param> /// <remarks> /// Multidimensional array instructions won't resolve because "there's /// nothing in the metadata to resolve to: those methods are created on the /// fly by the runtime". /// See https://www.mail-archive.com/[email protected]/msg03876.html. /// </remarks> static bool CheckMultidimensionalArray(Mono.Cecil.Cil.Instruction instruction, MethodDefinition method, TypeDefinition type, IMetadataScope scope) { var processor = method.Body.GetILProcessor(); foreach (var pattern in Patterns) { var m = pattern.Key.Match(instruction.Operand.ToString()); if (m.Success) { string full_name = m.Groups[1].Value; logger.Debug("Attemping to reconstruct multidimensional array instruction as '{0}' with opcode '{1}'", full_name, pattern.Value.Code); var asm = cache[scope.Name]; var tmp_type = asm.MainModule.GetType(full_name); if (tmp_type == null) { logger.Debug("{0} not found in {1}", full_name, scope.Name); return(false); } var new_instr = processor.Create(pattern.Value, tmp_type); return(TryResolve(new_instr.Operand, type)); } } return(false); }
public void StartInstruction(Mono.Cecil.Cil.Instruction instr) { if (!m_instructionOffsets.ContainsKey(instr)) { m_instructionOffsets.Add(instr, m_instructionList.Count); } }
private AnalysisNet.IInstruction ProcessUnconditionalBranch(Cecil.Cil.Instruction op) { uint target = (uint)((Cecil.Cil.Instruction)op.Operand).Offset; AnalysisNetBytecode.BranchInstruction instruction = new AnalysisNetBytecode.BranchInstruction((uint)op.Offset, AnalysisNetBytecode.BranchOperation.Branch, target); return(instruction); }
public void Conv_Ovf_U1() { decimal num1 = Convert.ToDecimal(stackCalc.Pop()); stackCalc.Push((byte)num1); _pos = _pos.Next; }
public void Conv_R_Un() { decimal num1 = Convert.ToDecimal(stackCalc.Pop()); stackCalc.Push((float)num1); _pos = _pos.Next; }
public void Conv_Ovf_I8() { decimal num1 = Convert.ToDecimal(stackCalc.Pop()); stackCalc.Push((Int64)num1); _pos = _pos.Next; }
public void Conv_U() { decimal num1 = Convert.ToDecimal(stackCalc.Pop()); stackCalc.Push((UInt32)num1); _pos = _pos.Next; }
public void Conv_R8() { decimal num1 = Convert.ToDecimal(stackCalc.Pop()); stackCalc.Push((double)num1); _pos = _pos.Next; }
public void Brtrue(Mono.Cecil.Cil.Instruction pos) { object obj = stackCalc.Pop(); bool b = false; if (obj != null) { if (obj.GetType().IsClass) { b = true; } else if (obj is bool) { b = (bool)obj; } else { b = Convert.ToDecimal(obj) > 0; } } //decimal b = Convert.ToDecimal(stackCalc.Pop()); //bool b = (bool)stackCalc.Pop(); if (b) { _pos = pos; } else { _pos = _pos.Next; } }
public void Readonly(ThreadContext context, object obj) { Type t = obj.GetType(); throw new NotImplementedException(); _pos = _pos.Next; }
private void TranslatePendingBranches(IDictionary <Model.Bytecode.Instruction, IList <Mono.Cecil.Cil.Instruction> > translated, IList <AnalysisNet.Bytecode.Instruction> pending) { TargetFinder targetFinder = new TargetFinder(translated.Keys); while (pending.Count > 0) { AnalysisNet.Bytecode.Instruction ins = pending.First(); pending.Remove(ins); if (ins is AnalysisNet.Bytecode.BranchInstruction br) { Cecil.Cil.Instruction result = translated[targetFinder.GetTarget(br.Target)].First(); translated[br].First().Operand = result; } else if (ins is AnalysisNet.Bytecode.SwitchInstruction switchIns) { for (int idx = 0; idx < switchIns.Targets.Count; idx++) { string target = switchIns.Targets[idx]; Cecil.Cil.Instruction result = translated[targetFinder.GetTarget(target)].First(); Cecil.Cil.Instruction[] cecilTargets = translated[switchIns].First().Operand as Cecil.Cil.Instruction[]; cecilTargets[idx] = result; } } else { throw new NotImplementedException(); } } }
public void Ldobj(ThreadContext context, object obj) { stackCalc.Push(obj); //Type t = obj.GetType(); //throw new NotImplementedException(); _pos = _pos.Next; }
internal static void LoadFrameOrClearStack(JavaStackMap stackMap, Mono.Cecil.Cil.Instruction inst) { // following any instruction that breaks the normal flow of execution, // we need to load an stack frame already recorded for some following // instruction, if any (e.g. as part of a conditional branch sequence). // if there isn't such a frame, just clear and reset the stack frame. for (;;) { inst = inst.Next; if (inst == null) { break; } if (stackMap.LoadFrame((ushort)inst.Offset, true, null)) { return; } var flowControl = inst.OpCode.FlowControl; if (flowControl == Mono.Cecil.Cil.FlowControl.Branch || flowControl == Mono.Cecil.Cil.FlowControl.Break || flowControl == Mono.Cecil.Cil.FlowControl.Cond_Branch || flowControl == Mono.Cecil.Cil.FlowControl.Return || flowControl == Mono.Cecil.Cil.FlowControl.Throw) { break; } } stackMap.ClearStack(); }
public string GetStackTrance(ILIntepreter intepreper) { StringBuilder sb = new StringBuilder(); ILRuntime.CLR.Method.ILMethod m; StackFrame[] frames = intepreper.Stack.Frames.ToArray(); Mono.Cecil.Cil.Instruction ins = null; if (frames[0].Address != null) { ins = frames[0].Method.Definition.Body.Instructions[frames[0].Address.Value]; sb.AppendLine(ins.ToString()); } for (int i = 0; i < frames.Length; i++) { var f = frames[i]; m = f.Method; string document = ""; if (f.Address != null) { ins = m.Definition.Body.Instructions[f.Address.Value]; var seq = FindSequencePoint(ins); if (seq != null) { document = string.Format("{0}:Line {1}", seq.Document.Url, seq.StartLine); } } sb.AppendFormat("at {0} {1}\r\n", m, document); } return(sb.ToString()); }
private AnalysisNet.IInstruction ProcessStoreLocal(Cecil.Cil.Instruction op) { int localIdx = -1; Cecil.Cil.VariableDefinition variable = null; switch (op.OpCode.Code) { case Mono.Cecil.Cil.Code.Stloc_S: case Mono.Cecil.Cil.Code.Stloc: variable = (Cecil.Cil.VariableDefinition)op.Operand; break; case Mono.Cecil.Cil.Code.Stloc_0: localIdx = 0; break; case Mono.Cecil.Cil.Code.Stloc_1: localIdx = 1; break; case Mono.Cecil.Cil.Code.Stloc_2: localIdx = 2; break; case Mono.Cecil.Cil.Code.Stloc_3: localIdx = 3; break; default: throw new NotImplementedException(); } AnalysisNetTac.Values.IVariable dest; if (variable != null) { dest = locals[variable.Index]; } else { dest = locals[localIdx]; } AnalysisNetBytecode.StoreInstruction instruction = new AnalysisNetBytecode.StoreInstruction((uint)op.Offset, dest); return(instruction); }
public void Ldvirtftn(ThreadContext context, IMethod method) { object _this = stackCalc.Pop(); stackCalc.Push(new RefFunc(method, _this)); _pos = _pos.Next; }
private AnalysisNet.IInstruction ProcessUnaryConditionalBranch(Cecil.Cil.Instruction op) { AnalysisNetBytecode.BranchOperation operation = OperationHelper.ToBranchOperation(op.OpCode.Code); uint target = (uint)((Cecil.Cil.Instruction)op.Operand).Offset; AnalysisNetBytecode.BranchInstruction instruction = new AnalysisNetBytecode.BranchInstruction((uint)op.Offset, operation, target); return(instruction); }
public void Ldelem_R8() { int index = (int)stackCalc.Pop(); Array array = stackCalc.Pop() as Array; stackCalc.Push(array.GetValue(index)); _pos = _pos.Next; }
private AnalysisNet.IInstruction ProcessLoadToken(Cecil.Cil.Instruction op) { Cecil.MemberReference cciToken = op.Operand as Cecil.MemberReference; AnalysisNet.Types.IMetadataReference ourToken = typeExtractor.ExtractToken(cciToken); AnalysisNetBytecode.LoadTokenInstruction instruction = new AnalysisNetBytecode.LoadTokenInstruction((uint)op.Offset, ourToken); return(instruction); }
private AnalysisNet.IInstruction ProcessStoreField(Cecil.Cil.Instruction op) { Cecil.FieldReference cciField = op.Operand as Cecil.FieldReference;//op.Operand as Cci.IFieldReference; AnalysisNet.Types.FieldReference ourField = typeExtractor.ExtractField(cciField, op.OpCode.Code == Cecil.Cil.Code.Stsfld); AnalysisNetBytecode.StoreFieldInstruction instruction = new AnalysisNetBytecode.StoreFieldInstruction((uint)op.Offset, ourField); return(instruction); }
private AnalysisNet.IInstruction ProcessSizeof(Cecil.Cil.Instruction op) { Cecil.TypeReference cciType = op.Operand as Cecil.TypeReference; AnalysisNet.Types.IType ourType = typeExtractor.ExtractType(cciType); AnalysisNetBytecode.SizeofInstruction instruction = new AnalysisNetBytecode.SizeofInstruction((uint)op.Offset, ourType); return(instruction); }
static void WriteLabelList(ITextOutput writer, ILInstruction[] instructions) { writer.Write("("); for(int i = 0; i < instructions.Length; i++) { if(i != 0) writer.Write(", "); WriteOffsetReference(writer, instructions[i]); } writer.Write(")"); }
public InstructionElement(Mono.Cecil.MethodDefinition parentMethod, InstructionElement[] childnodes, Mono.Cecil.Cil.Instruction instruction) { this.Childnodes = childnodes ?? new InstructionElement[0]; this.Instruction = instruction; this.ParentMethod = parentMethod; foreach (InstructionElement c in this.Childnodes) { System.Diagnostics.Trace.Assert(c != null); c.Parent = this; } if (instruction != null) AssignReturnType(); }
public static void WriteOffsetReference(ITextOutput writer, ILInstruction instruction) { writer.WriteReference(/*CecilExtensions.OffsetToString*/(instruction.Offset.ToString()), instruction); }