Exemplo n.º 1
0
        public static Instruction GetPriorInstruction(MethodReference callingMethod, MethodReference method, Instruction instruction)
        {
            try
            {
                var rootNode        = new InstructionTreeNode();
                var lastInstruction = GetParameterInstructionTree(callingMethod, method, instruction, rootNode);

                if (lastInstruction == null)
                {
                }

                // if the last instruction is ldarg.0 then return the instruction after that which will be the owner field or method
                if (lastInstruction.OpCode.Code == Mono.Cecil.Cil.Code.Ldarg_0)
                {
                    return(lastInstruction.Next);
                }

                // if the last instruction is the target instruction, then return the previous one
                // this can happen with compiled generated classes
                if (lastInstruction.Offset == instruction.Offset)
                {
                    return(lastInstruction.Previous);
                }

                return(lastInstruction);
                //return GetPreviousInstruction(lastInstruction);
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
Exemplo n.º 2
0
 private InstructionTreeNode GetInstructionTree(MethodDefinition parentMethod, Instruction instruction, MethodReference calledMethod)
 {
     try
     {
         var rootNode = new InstructionTreeNode();
         MethodArgumentInstructionParser.GetParameterInstructionTree(parentMethod, calledMethod, instruction, rootNode);
         return(rootNode);
     }
     catch (Exception ex)
     {
         _logOutput.LogAnalysis("ERROR " + parentMethod.FullName + " instruction" + instruction.ToString() + " Error-> " + ex);
         return(null);
     }
 }
Exemplo n.º 3
0
        public static Instruction GetParameterInstructionTreeForFuncConstructor(MethodReference callingMethod, MethodReference funcMethod, Instruction instruction, InstructionTreeNode parentNode)
        {
            if (parentNode.Instruction == null)
            {
                parentNode.Instruction = instruction;
            }

            int parameterCount = GetParameterCount(funcMethod);

            for (int i = 0; i < parameterCount; i++)
            {
                instruction = GetPreviousInstruction(instruction);
                var childNode = new InstructionTreeNode();
                childNode.Instruction = instruction;
                parentNode.ChildInstructions.Add(childNode);
            }

            return(instruction);
        }
Exemplo n.º 4
0
        private List <Triple> TraverseTree(MethodDefinition parentMethod,
                                           InstructionTreeNode parentNode,
                                           string instanceOwnerKey,
                                           bool isObjectInitializerMember,
                                           string constructorInstructionKey = null)
        {
            var triples = new List <Triple>();

            var toArgumentCounter = parentNode.ChildInstructions.Count;

            foreach (var argumentInstruction in parentNode.ChildInstructions)
            {
                var fromObjectType       = InstructionKeyService.GetFromObjectType(argumentInstruction.Instruction);
                var fromInstanceOwnerKey = InstructionKeyService.GetFromInstanceOwnerKey(argumentInstruction.Instruction, fromObjectType, parentMethod);

                var triple = BuildTriple(parentNode.Instruction, instanceOwnerKey, argumentInstruction.Instruction, fromInstanceOwnerKey, parentMethod, toArgumentCounter);
                if (triple == null)
                {
                    continue;
                }

                if (isObjectInitializerMember)
                {
                    triple.SetsObjectInitializerMember = true;
                    triple.ConstructorInstructionKey   = constructorInstructionKey;
                }

                triples.Add(triple);
                toArgumentCounter--;

                if (argumentInstruction.ChildInstructions.Any())
                {
                    var subTriples = TraverseTree(parentMethod, argumentInstruction, triple.From.InstanceOwnerKey, false);
                    triples.AddRange(subTriples);
                }
            }

            return(triples);
        }
Exemplo n.º 5
0
        private void FindFieldsAndMethods(MethodDefinition method, MethodObject methodNode, bool allowRecursion)
        {
            if (!method.HasBody)
            {
                return;
            }

            List <Instruction> instructions = null;
            var isAsync = IsAsync(method);

            if (isAsync.Item1)
            {
                instructions = GetInstructionsOfAsyncMethod(isAsync.Item2);
            }
            else
            {
                instructions = method.Body.Instructions.ToList();
            }

            foreach (var instruction in instructions)
            {
                try
                {
                    if (instruction.OpCode.Code == Mono.Cecil.Cil.Code.Call ||
                        instruction.OpCode.Code == Mono.Cecil.Cil.Code.Calli ||
                        instruction.OpCode.Code == Mono.Cecil.Cil.Code.Callvirt ||
                        instruction.OpCode.Code == Mono.Cecil.Cil.Code.Newobj)
                    {
                        var methodRef = (MethodReference)instruction.Operand;
                        MethodDefinition methodDef = null;
                        var resolved = ResolveService.TryResolve(methodRef, out methodDef);
                        if (!resolved)
                        {
                            // log error
                            continue;
                        }

                        if (DelegateIndexer.IsDelegateInvocation(methodRef))
                        {
                            var concreteMethods = _delegateIndexer.GetAssignedMethods(method, methodRef);
                            foreach (var concreteMethod in concreteMethods)
                            {
                                var delegateCall = new MethodCall();
                                delegateCall.Instruction  = concreteMethod.MethodAssignmentInstruction;
                                delegateCall.MethodCalled = concreteMethod.AssignedMethod;
                                delegateCall.OwnerMethod  = method;
                                methodNode.MethodsCalled.Add(delegateCall);
                            }
                        }
                        else if (IsLazilyEvaluated(instruction, methodDef))
                        {
                            var nestedMethods = ExtractNestedMethods(methodDef.DeclaringType);
                            foreach (var nestedMethod in nestedMethods)
                            {
                                if (allowRecursion)
                                {
                                    FindFieldsAndMethods(nestedMethod, methodNode, false);
                                }
                            }
                        }
                        else if (!methodRef.FullName.Equals("System.Void System.Object::.ctor()"))
                        {
                            bool funcMethodCallsFound = false;

                            // try to detect funcs
                            if (methodRef.Parameters.Any())
                            {
                                var rootNode = new InstructionTreeNode();
                                MethodArgumentInstructionParser.GetParameterInstructionTree(method, methodRef, instruction, rootNode);

                                foreach (var loadFunctionNode in rootNode.GetDescendants().Where(x => x.Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Ldftn))
                                {
                                    // except for delegates!
                                    var funcCall = new MethodCall();
                                    funcCall.Instruction  = loadFunctionNode.Instruction;
                                    funcCall.MethodCalled = loadFunctionNode.Instruction.Operand as MethodReference;
                                    funcCall.OwnerMethod  = method;
                                    methodNode.MethodsCalled.Add(funcCall);

                                    funcMethodCallsFound = true;
                                }
                            }

                            bool isCompilerServicesRelated = false;
                            if (isAsync.Item1 && (methodRef.DeclaringType.FullName.StartsWith("System.Runtime.CompilerServices") || methodRef.DeclaringType.FullName.StartsWith("System.Threading.Tasks")))
                            {
                                isCompilerServicesRelated = true;
                            }

                            // if not a func and not an async related CompilerServices call then go ahead and register the call
                            if (!funcMethodCallsFound && !isCompilerServicesRelated)
                            {
                                var methodCall = new MethodCall();
                                methodCall.Instruction  = instruction;
                                methodCall.MethodCalled = methodRef;
                                methodCall.OwnerMethod  = method;
                                methodNode.MethodsCalled.Add(methodCall);
                            }
                        }
                    }
                    else if (instruction.OpCode.OperandType == OperandType.InlineField)
                    {
                        var field = (FieldReference)instruction.Operand;
                        if ((instruction.OpCode.Name.StartsWith("ldfld") || instruction.OpCode.Name.StartsWith("ldsfld")) && field.Name.IndexOf("BackingField") == -1)
                        {
                            methodNode.FieldsRead.Add(field);
                        }
                    }
                    else if (instruction.OpCode.Code == Mono.Cecil.Cil.Code.Ldftn)
                    {
                        var methodRef = (MethodReference)instruction.Operand;
                        MethodDefinition functionDefinition = null;
                        var resolved = ResolveService.TryResolve(methodRef, out functionDefinition);
                        if (!resolved)
                        {
                            // log error
                            continue;
                        }

                        if (allowRecursion)
                        {
                            FindFieldsAndMethods(functionDefinition, methodNode, false);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // log it
                }
            }
        }
Exemplo n.º 6
0
        private static Instruction GetParameterInstructionTreeForNormalMethod(MethodReference parentMethodRef, MethodReference method, Instruction instruction, InstructionTreeNode parentNode)
        {
            MethodDefinition parentMethod            = parentMethodRef.Resolve();
            Instruction      targetMethodInstruction = instruction;
            MethodDefinition targetMethodDef         = null;
            var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out targetMethodDef);

            if (!resolved)
            {
                throw new ILParseException("Could not resolve " + ((MethodReference)instruction.Operand).FullName);
            }

            var parameterCount = method.Parameters.Count;

            if (parentNode.Instruction == null)
            {
                parentNode.Instruction = instruction;
            }

            for (int i = 0; i < parameterCount; i++)
            {
                if (instruction.Previous == null)
                {
                    throw new ILParseException("Unexpectedly reached the end of the instructions while analysing " + parentMethodRef.FullName);
                }

                instruction = GetPreviousInstruction(instruction);

                if (ShouldSkip(instruction))
                {
                    instruction = GetPreviousInstruction(instruction);
                }

                var childNode = new InstructionTreeNode();
                childNode.Instruction = instruction;
                parentNode.ChildInstructions.Add(childNode);

                if (instruction.OpCode.OperandType == OperandType.InlineMethod)
                {
                    var instructionMethodDef = ResolveMethod(instruction);
                    if (instructionMethodDef.Parameters.Any())
                    {
                        var lastInstructionOfParameters = GetParameterInstructionTree(parentMethodRef, instructionMethodDef, instruction, childNode);
                        instruction = lastInstructionOfParameters;
                        //if (AreInstructionsChained(instruction, lastInstructionOfParameters.Previous))
                        //    instruction = lastInstructionOfParameters.Previous; // move to chained instruction so later call jumps chained instructions
                    }
                }

                instruction = JumpPastAnyOwnerInstructions(instruction, parentMethod);
            }

            instruction = JumpAnyJumpableInstructionsOfTargetMethod(targetMethodInstruction, instruction, targetMethodDef, parentMethod);

            //if(TargetMethodHasJumpablePreviousInstruction(targetMethodInstruction, instruction, targetMethodDef, parentMethod))
            //    instruction = GetPreviousInstruction(instruction);
            //if (HasThis(callingMethod, methodDef) && instruction.OpCode.Code != Mono.Cecil.Cil.Code.Ldarg_0)
            //    instruction = GetPreviousInstruction(instruction);

            return(instruction);
        }
Exemplo n.º 7
0
 public static Instruction GetParameterInstructionTree(MethodReference callingMethod, MethodReference method, Instruction instruction, InstructionTreeNode parentNode)
 {
     if (method.Name.Equals(".ctor") &&
         (method.DeclaringType.Name.IndexOf("Func`") > -1 ||
          method.FullName.IndexOf("System.Object,System.IntPtr") > -1))
     {
         return(GetParameterInstructionTreeForFuncConstructor(callingMethod, method, instruction, parentNode));
     }
     else
     {
         return(GetParameterInstructionTreeForNormalMethod(callingMethod, method, instruction, parentNode));
     }
 }