Esempio n. 1
0
        public IList <AssignmentTree> PerformBacktrackingSearch(string startingObjectKey,
                                                                ISourceDetector nameSourceDetector,
                                                                List <GoToInstancePattern> permittedToGoInstancePatterns,
                                                                List <string> searchBaseConstructorPatterns)
        {
            _goToInstancePatterns          = permittedToGoInstancePatterns;
            _searchBaseConstructorPatterns = searchBaseConstructorPatterns;

            var assignmentTrees = new List <AssignmentTree>();

            CreateStartTraceSection(startingObjectKey);

            var startingKeys = _tripleStore.GetTo(startingObjectKey);

            foreach (var start in startingKeys)
            {
                Print(startingObjectKey, 0);

                var exploreTreeNode = new ExploreTreeNode()
                {
                    FullSignature = start.ToString()
                };
                var rootNode       = new AssignmentTreeNode(start);
                var assignmentTree = new AssignmentTree();
                assignmentTree.RootNode = rootNode;
                var counter = new BacktrackCounter();

                _instructionKeyStack = new Stack <string>();
                BacktrackingSearch(start, start, nameSourceDetector, counter, assignmentTree, rootNode, false, exploreTreeNode, 0);

                assignmentTrees.Add(assignmentTree);
            }

            return(assignmentTrees);
        }
Esempio n. 2
0
        private BacktrackResult GoToInstance(Triple startTriple,
                                             Triple triple,
                                             ISourceDetector nameSourceDetector,
                                             AssignmentTree assignmentTree,
                                             AssignmentTreeNode lastNode,
                                             BacktrackCounter counter,
                                             bool inReturnScope,
                                             ExploreTreeNode exploreTreeNode,
                                             int depth)
        {
            var branchResult = BacktrackingSearchFromInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);

            if (branchResult != BacktrackResult.BranchFailure)
            {
                return(branchResult);
            }

            branchResult = BacktrackingSearchFromInstanceProperty(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
            if (branchResult != BacktrackResult.BranchFailure)
            {
                return(branchResult);
            }

            return(BacktrackResult.BranchFailure);
        }
Esempio n. 3
0
        private BacktrackResult GoToBaseConstructor(Triple startTriple,
                                                    Triple triple,
                                                    ISourceDetector nameSourceDetector,
                                                    AssignmentTree assignmentTree,
                                                    AssignmentTreeNode lastNode,
                                                    BacktrackCounter counter,
                                                    bool inReturnScope,
                                                    ExploreTreeNode exploreTreeNode,
                                                    int depth)
        {
            var baseClass      = triple.To.InheritsFromConcreteClass;
            var baseClassCtors = _tripleStore.GetAllTriples().Where(x => x.To.ObjectKey.IndexOf(baseClass) > -1 &&
                                                                    x.To.ObjectKey.IndexOf(".ctor") > -1);

            foreach (var baseClassCtorTriple in baseClassCtors)
            {
                if (baseClassCtorTriple.To.InstanceOwnerKey.Equals(triple.To.MemberName))
                {
                    var childExploreTreeNode = CreateExploreTreeNode(baseClassCtorTriple, "ViaBaseConstructor", exploreTreeNode);
                    var branchResult         = BacktrackingSearchMatches(startTriple, triple, new List <Triple>()
                    {
                        baseClassCtorTriple
                    }, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, childExploreTreeNode, depth);
                    if (branchResult != BacktrackResult.BranchFailure)
                    {
                        return(branchResult);
                    }
                }
            }

            return(BacktrackResult.BranchFailure);
        }
Esempio n. 4
0
        private void DoCrossAssemblyWalk(MethodGraph methodGraph, string companyAssembliesPattern, ModuleDefinition module, string moduleMessagee)
        {
            var publicMethods = DecompilerService.GetPublicMethods(companyAssembliesPattern, module)
                                .Where(x => !IsBlackListed(x))
                                .OrderBy(x => x.DeclaringType.Name)
                                .ThenBy(x => x.Name)
                                .ToList();

            int methodCount           = publicMethods.Count;
            var publicMethodsAnalyzed = new HashSet <string>();

            _methodNodeLookup.Clear();

            int methodCounter = 0;

            foreach (var publicMethod in publicMethods)
            {
                methodCounter++;
                _logOutput.LogAnalysis("Method " + methodCounter + " of " + methodCount + " : " + moduleMessagee + " -> " + publicMethod.Name);
                if ((publicMethod.IsGetter || publicMethod.IsSetter) && !IsNoteworthyProperty(publicMethod))
                {
                    continue;
                }

                var signature = SignatureKeyService.GetFullMethodSignature(publicMethod);
                if (_methodIndexer.HasMethod(signature))
                {
                    var unfilteredRootNodes = _methodIndexer.GetMethods(signature);
                    var rootNodes           = unfilteredRootNodes.Where(x => x.HasImplementation() &&
                                                                        (
                                                                            // if it is a public implementation of a different assembly, then'll we'll filter it out here (and analyze it that assembly)
                                                                            (x.ConcreteMethod.IsPublic && x.ConcreteMethod.Module.Name.Equals(module.Name))
                                                                            // if it is a private implementation then analyze it now as we'll miss it when we analyze the public methods of the other assembly
                                                                            || !x.ConcreteMethod.DeclaringType.IsPublic
                                                                        )
                                                                        )
                                              .ToList();

                    foreach (var rootMethod in rootNodes)
                    {
                        if (!AlreadyProcessed(rootMethod.GetMethodDefinition()))
                        {
                            var publicMethodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, rootMethod);
                            var callTreeNode     = new ExploreTreeNode()
                            {
                                FullSignature = signature
                            };
                            CrossAssemblyWalk(methodGraph, publicMethodNode, rootMethod, 1, callTreeNode);
                            CacheNode(rootMethod.GetMethodDefinition(), publicMethodNode);
                            methodGraph.AddMethodNode(publicMethodNode);
                        }
                    }
                }
            }
        }
Esempio n. 5
0
        private ExploreTreeNode CreateExploreTreeNode(Triple triple, string searchType, ExploreTreeNode exploreTreeNode)
        {
            var childExploreTreeNode = new ExploreTreeNode()
            {
                FullSignature = string.Format("{0}:{1}", searchType, triple.From.InstructionKey)
            };

            exploreTreeNode.AddChild(childExploreTreeNode);

            return(childExploreTreeNode);
        }
Esempio n. 6
0
        private void ContinueDownFullTree(MethodGraph methodGraph, MethodNode parentMethodNode, MethodObject parentMethod, int depth, ExploreTreeNode callTreeNode)
        {
            foreach (var calledMethod in parentMethod.MethodsCalled)
            {
                CheckForResourceCall(methodGraph, calledMethod, parentMethod, parentMethodNode);
                var calledMethodSignature = SignatureKeyService.GetFullMethodSignature(calledMethod.MethodCalled);
                var treeNode = new ExploreTreeNode()
                {
                    FullSignature = calledMethodSignature
                };
                callTreeNode.AddChild(treeNode);

                bool   isGenericAndIndexed = false;
                string genericSignature    = null;
                var    methodIsIndexed     = _methodIndexer.HasMethod(calledMethodSignature);
                if (!methodIsIndexed)
                {
                    genericSignature = SignatureKeyService.GetGenericMethodSignature(calledMethod.MethodCalled);
                    if (!string.IsNullOrEmpty(genericSignature))
                    {
                        isGenericAndIndexed = _methodIndexer.HasMethod(genericSignature);
                    }
                }

                if (methodIsIndexed || isGenericAndIndexed)
                {
                    List <MethodObject> matchingMethodNodes = null;
                    if (methodIsIndexed)
                    {
                        matchingMethodNodes = _methodIndexer.GetMethods(calledMethodSignature);
                    }
                    else if (isGenericAndIndexed)
                    {
                        matchingMethodNodes = _methodIndexer.GetMethods(genericSignature);
                    }

                    foreach (var calledMethodNode in matchingMethodNodes)
                    {
                        var cachedRootNode = GetCachedRootNode(calledMethodNode.GetMethodDefinition());

                        if (cachedRootNode != null) // this is a call to an already analyzed method, we copy over the calls and resource accesses already calculated for this node
                        {
                            cachedRootNode.CopyCallsToNode(parentMethodNode);
                        }
                        else // this is not a call to a previously analyzed method, so we continue down the call tree
                        {
                            PublicInnerAssemblyWalk(methodGraph, parentMethodNode, calledMethodNode, depth + 1, treeNode);
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        private BacktrackResult BacktrackingSearchFromInstructionKeyStack(Triple startTriple,
                                                                          Triple triple,
                                                                          ISourceDetector nameSourceDetector,
                                                                          AssignmentTree assignmentTree,
                                                                          AssignmentTreeNode lastNode,
                                                                          BacktrackCounter counter,
                                                                          bool inReturnScope,
                                                                          ExploreTreeNode exploreTreeNode,
                                                                          int depth)
        {
            var result = BacktrackResult.BranchFailure;

            if (_instructionKeyStack.Count == 0)
            {
                // TODO log error
                Print("Tried to pop empty stack " + triple, depth);
                return(BacktrackResult.Stop);
            }

            var instructionKey = _instructionKeyStack.Pop();

            Print("Pop from instruction stack " + instructionKey, depth);
            var matchingTriples = _tripleStore.GetToViaInstructionKey(instructionKey);

            List <Triple> targetTriples = null;

            if (triple.From.ObjectKey.EndsWith("return"))
            {
                targetTriples = matchingTriples;
            }
            else
            {
                var targetPosition = triple.From.ObjectKey.Substring(triple.From.ObjectKey.IndexOf(">>") + 2);
                targetTriples = matchingTriples.Where(x => x.To.ObjectKey.EndsWith(targetPosition)).ToList();
            }

            if (targetTriples.Any())
            {
                var branchResult = BacktrackingSearchMatches(startTriple, triple, targetTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth);
                if (branchResult == BacktrackResult.Success)
                {
                    result = BacktrackResult.Success;
                }
                else if (branchResult == BacktrackResult.Stop)
                {
                    return(branchResult);
                }
            }

            return(result);
        }
Esempio n. 8
0
        private BacktrackResult BacktrackingSearchFromInstanceProperty(Triple startTriple,
                                                                       Triple triple,
                                                                       ISourceDetector nameSourceDetector,
                                                                       AssignmentTree assignmentTree,
                                                                       AssignmentTreeNode lastNode,
                                                                       BacktrackCounter counter,
                                                                       bool inReturnScope,
                                                                       ExploreTreeNode exploreTreeNode,
                                                                       int depth)
        {
            Print("Check for instance property assignments", depth);
            var result = BacktrackResult.BranchFailure;

            var instanceMemberAssignments = _tripleStore.GetToViaInstanceOwnerKey(triple.To.InstanceOwnerKey);

            if (instanceMemberAssignments.Any())
            {
                if (instanceMemberAssignments.Count() > 1 && instanceMemberAssignments.Any(x => x.ParentAssembly.Equals(triple.ParentAssembly)))
                {
                    instanceMemberAssignments = instanceMemberAssignments.Where(x => x.ParentAssembly.Equals(triple.ParentAssembly)).ToList();
                }

                foreach (var instanceAssignment in instanceMemberAssignments)
                {
                    if (instanceAssignment.To.ObjectKey.Equals(startTriple.To.ObjectKey))
                    {
                        continue;
                    }

                    var childExploreTreeNode = CreateExploreTreeNode(instanceAssignment, "InstanceMemberAssignment", exploreTreeNode);
                    var assignmentNode       = new AssignmentTreeNode(instanceAssignment);
                    assignmentNode.IsRegressionToInstance = true;
                    Print("Gone to instance property assignment " + instanceAssignment, depth);
                    var branchResult = BacktrackingSearch(startTriple, instanceAssignment, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth);
                    if (branchResult == BacktrackResult.Success)
                    {
                        lastNode.Children.Add(assignmentNode);
                        result = BacktrackResult.Success;
                    }
                    else if (branchResult == BacktrackResult.Stop)
                    {
                        return(branchResult);
                    }
                }
            }

            return(result);
        }
Esempio n. 9
0
        private bool IsRecursiveLoop(ExploreTreeNode callTreeNode)
        {
            ExploreTreeNode parent = callTreeNode.Parent;

            while (parent != null)
            {
                if (parent.FullSignature.Equals(callTreeNode.FullSignature))
                {
                    return(true);
                }

                parent = parent.Parent;
            }

            return(false);
        }
Esempio n. 10
0
        private BacktrackResult BacktrackingSearchFromInstance(Triple startTriple,
                                                               Triple triple,
                                                               ISourceDetector nameSourceDetector,
                                                               AssignmentTree assignmentTree,
                                                               AssignmentTreeNode lastNode,
                                                               BacktrackCounter counter,
                                                               bool inReturnScope,
                                                               ExploreTreeNode exploreTreeNode,
                                                               int depth)
        {
            Print("Check for instance assignments", depth);
            var result = BacktrackResult.BranchFailure;

            if (triple.To.InstanceOwnerKey == null)
            {
                return(result);
            }

            List <Triple> instanceAssignments = _tripleStore.GetTo(triple.To.InstanceOwnerKey);

            Print(instanceAssignments.Count + " Instance Assignments", depth);

            if (instanceAssignments.Any())
            {
                int instanceCounter = 0;
                foreach (var instanceAssignment in instanceAssignments)
                {
                    instanceCounter++;
                    var childExploreTreeNode = CreateExploreTreeNode(instanceAssignment, "InstanceAssignment", exploreTreeNode);
                    var assignmentNode       = new AssignmentTreeNode(instanceAssignment);
                    assignmentNode.IsRegressionToInstance = true;
                    Print("Gone to instance assignment " + instanceCounter + ": " + instanceAssignment, depth);
                    var branchResult = BacktrackingSearch(startTriple, instanceAssignment, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth);
                    if (branchResult == BacktrackResult.Success)
                    {
                        lastNode.Children.Add(assignmentNode);
                        result = BacktrackResult.Success;
                    }
                    else if (branchResult == BacktrackResult.Stop)
                    {
                        return(branchResult);
                    }
                }
            }

            return(result);
        }
Esempio n. 11
0
        private BacktrackResult BacktrackingSearchMatches(Triple startTriple,
                                                          Triple triple,
                                                          List <Triple> targetMatchingTriples,
                                                          ISourceDetector nameSourceDetector,
                                                          AssignmentTree assignmentTree,
                                                          AssignmentTreeNode lastNode,
                                                          BacktrackCounter counter,
                                                          bool inReturnScope,
                                                          bool printObjectKey,
                                                          ExploreTreeNode exploreTreeNode,
                                                          int depth)
        {
            var result = BacktrackResult.BranchFailure;

            int matchCounter = 0;

            foreach (var backTriple in targetMatchingTriples)
            {
                matchCounter++;
                ExploreTreeNode childExploreTreeNode = null;

                if (printObjectKey)
                {
                    childExploreTreeNode = CreateExploreTreeNode(backTriple, "ObjectKey", exploreTreeNode);
                    Print(matchCounter + " matched object key " + backTriple, depth);
                }
                else
                {
                    childExploreTreeNode = CreateExploreTreeNode(backTriple, "InstructionKey", exploreTreeNode);
                    Print(matchCounter + " MATCH INSTRUCTION KEY " + triple.From.InstructionKey, depth);
                }

                var assignmentNode = new AssignmentTreeNode(backTriple);
                var branchResult   = BacktrackingSearch(startTriple, backTriple, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth);
                if (branchResult == BacktrackResult.Success)
                {
                    lastNode.Children.Add(assignmentNode);
                    result = BacktrackResult.Success;
                }
                else if (branchResult == BacktrackResult.Stop)
                {
                    return(branchResult);
                }
            }

            return(result);
        }
Esempio n. 12
0
        private void PublicInnerAssemblyWalk(MethodGraph methodGraph, MethodNode rootMethod, MethodObject currentMethod, int depth, ExploreTreeNode callTreeNode)
        {
            if (IsRecursiveLoop(callTreeNode))
            {
                return;
            }

            if (!currentMethod.HasImplementation())
            {
                // Perhaps log it somewhere in debug mode
                //File.AppendAllText("No_Implementation.txt", currentMethod.GetMethodDefinition().FullName);
                return;
            }

            var isCrossAssemblyCall       = IsCrossAssemblyCall(rootMethod, currentMethod, depth);
            var isPublicInnerAssemblyCall = IsPublicInnerAssemblyCall(rootMethod, currentMethod, depth);
            var currentMethodNode         = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, currentMethod);

            if (isCrossAssemblyCall)
            {
                // if it is a simple property access then we don't care. Only add it if the access is interesting
                if (IsNoteworthyMethodCall(currentMethod))
                {
                    rootMethod.CrossAssemblyCalls.Add(currentMethodNode);
                }
            }
            else if (isPublicInnerAssemblyCall)
            {
                // if it is a simple property access then we don't care. Only add it if the access is interesting
                if (IsNoteworthyMethodCall(currentMethod))
                {
                    rootMethod.PublicInnerAssemblyCalls.Add(currentMethodNode);
                }
            }

            // continue down the call tree unless the called method is of another assembly or is public
            // the call tree originating at a method of another assembly will be generated when that assembly is analyzed
            // the call tree originating at a public method of this assembly will be generated when that public method is walked
            if (!isCrossAssemblyCall && !isPublicInnerAssemblyCall)
            {
                ContinueDownPublicInnerAssemblyTree(methodGraph, rootMethod, currentMethod, depth, callTreeNode);
            }
        }
Esempio n. 13
0
        private BacktrackResult BacktrackingSearch(Triple startTriple,
                                                   Triple triple,
                                                   ISourceDetector nameSourceDetector,
                                                   BacktrackCounter counter,
                                                   AssignmentTree assignmentTree,
                                                   AssignmentTreeNode lastNode,
                                                   bool inReturnScope,
                                                   ExploreTreeNode exploreTreeNode,
                                                   int depth)
        {
            depth++;
            counter.Count++;
            Print("BACKTRACKED TO " + triple, depth);

            if (IsRecursiveLoop(exploreTreeNode))
            {
                Print("RECURSIVE LOOP", depth);
                return(BacktrackResult.BranchFailure);
            }

            if (counter.Count > 150)
            {
                Print("Limit Reached", depth);
                return(BacktrackResult.Stop);
            }

            if (IsAssignedByMethod(triple))
            {
                var canStepInto = _tripleStore.Back(triple).Any();
                var methodRef   = (MethodReference)triple.From.Instruction.Operand;
                if (methodRef.HasParameters && canStepInto)
                {
                    PushInstructionKeyToStack(triple, depth);
                    inReturnScope = true;
                }
            }

            if (nameSourceDetector.IsNameSource(triple))
            {
                AddTargetToAssignmentTree(triple, assignmentTree, lastNode, depth);
                return(BacktrackResult.Success);
            }

            if (IsReturnScopeArgument(triple, ref inReturnScope))
            {
                var branchResult = BacktrackingSearchFromInstructionKeyStack(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                if (branchResult != BacktrackResult.BranchFailure)
                {
                    return(branchResult);
                }
            }
            else if (ShouldGoToBaseConstructor(triple))
            {
                var branchResult = GoToBaseConstructor(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                if (branchResult != BacktrackResult.BranchFailure)
                {
                    return(branchResult);
                }
            }
            else if (ShouldOnlyGoToInstance(triple))
            {
                var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                if (branchResult != BacktrackResult.BranchFailure)
                {
                    return(branchResult);
                }
            }
            else
            {
                if (FromIsRelevantObjectInitializerConstructor(triple))
                {
                    Print("Is Relevant Object Initializer Constructor" + triple, depth);
                    var objectInitializerMemberTriples = _tripleStore.GetToViaContructorInstructionKey(triple.From.InstructionKey);
                    if (objectInitializerMemberTriples.Any())
                    {
                        Print("Found " + objectInitializerMemberTriples.Count + " Object Initializer Members " + triple, depth);
                        var branchResult = BacktrackingSearchMatches(startTriple, triple, objectInitializerMemberTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth);
                        if (branchResult != BacktrackResult.BranchFailure)
                        {
                            return(branchResult);
                        }
                    }
                }

                var goneToInstance = false;
                if (ShouldGoToInstanceFirst(triple))
                {
                    goneToInstance = true;
                    var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                    if (branchResult != BacktrackResult.BranchFailure)
                    {
                        return(branchResult);
                    }
                }

                Print("Check for direct triple to -> from match" + triple, depth);
                var backTriples = _tripleStore.Back(triple);
                if (backTriples.Any())
                {
                    var branchResult = BacktrackingSearchMatches(startTriple, triple, backTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth);
                    if (branchResult != BacktrackResult.BranchFailure)
                    {
                        return(branchResult);
                    }
                }

                if (triple.From.ObjectType == ObjectType.Method)
                {
                    Print("Step over method to argument " + triple, depth);
                    PushInstructionKeyToStack(triple, depth);
                    var branchResult = BacktrackingSearchFromInstructionKeyStack(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                    if (branchResult != BacktrackResult.BranchFailure)
                    {
                        return(branchResult);
                    }
                }

                if (CanGoToInstance(triple) && !goneToInstance)
                {
                    var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth);
                    if (branchResult != BacktrackResult.BranchFailure)
                    {
                        return(branchResult);
                    }
                }
            }

            Print("DEADEND", depth);

            return(BacktrackResult.BranchFailure);
        }