예제 #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);
        }
예제 #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);
        }
예제 #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);
        }
예제 #4
0
        private void AddTargetToAssignmentTree(Triple triple, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, int depth)
        {
            Print("FOUND " + triple.From.ObjectKey, depth);
            var foundAssignmentTreeNode = new AssignmentTreeNode(triple, true);

            lastNode.Children.Add(foundAssignmentTreeNode);
            assignmentTree.FoundNodes.Add(foundAssignmentTreeNode);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
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);
        }
예제 #9
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);
        }