Example #1
0
        /// <summary>
        /// Runs the first phase analysis.
        /// </summary>
        private void runFirstPhaseAnalysis()
        {
            State = AnalysisState.ForwardAnalysis;
            FirstPhaseInitialMemory = GC.GetTotalMemory(true);

            WatchFirstPhase.Start();

            try
            {
                firstPhaseAnalysis = new Weverca.Analysis.ForwardAnalysis(controlFlowGraph, MemoryModel);

                IsFirstPhaseStarted = true;
                firstPhaseAnalysis.Analyse();
            }
            finally
            {
                WatchFirstPhase.Stop();

                FirstPhaseEndMemory = GC.GetTotalMemory(true);

                if (IsFirstPhaseStarted)
                {
                    programPointGraph = firstPhaseAnalysis.ProgramPointGraph;

                    analysisWarnings = AnalysisWarningHandler.GetWarnings();
                    securityWarnings = AnalysisWarningHandler.GetSecurityWarnings();
                }
            }

            if (IsFirstPhaseStarted)
            {
                IsFirstPhaseFinished = true;
            }
        }
Example #2
0
        /// <summary>
        /// Report a warning for the position of current expression.
        /// </summary>
        /// <param name="flow">Flow controller of program point providing data for evaluation.</param>
        /// <param name="message">Message of the warning.</param>
        /// <param name="cause">Cause of the warning.</param>
        private static void SetWarning(FlowController flow, string message, AnalysisWarningCause cause)
        {
            var warning = new AnalysisWarning(flow.CurrentScript.FullName,
                                              message, flow.CurrentPartial, flow.CurrentProgramPoint, cause);

            AnalysisWarningHandler.SetWarning(flow.OutSet, warning);
        }
Example #3
0
        /// <summary>
        /// Report a warning for the position of current expression.
        /// </summary>
        /// <param name="message">Message of the warning.</param>
        /// <param name="cause">Cause of the warning.</param>
        protected void SetWarning(string message, AnalysisWarningCause cause)
        {
            var warning = new AnalysisWarning(flow.CurrentScript.FullName, message,
                                              flow.CurrentPartial, flow.CurrentProgramPoint, cause);

            AnalysisWarningHandler.SetWarning(OutSet, warning);
        }
Example #4
0
        public static bool ContainsSecurityWarning(FlowOutputSet outset, FlagType cause)
        {
            var warnings = AnalysisWarningHandler.ReadWarnings <AnalysisSecurityWarning>(outset);

            foreach (var value in warnings)
            {
                var infoValue = (InfoValue <AnalysisSecurityWarning>)value;
                if (infoValue.Data.Flag == cause)
                {
                    return(true);
                }
            }

            return(false);
        }
Example #5
0
        /// <summary>
        /// Checks arguments in functions and generates warning if the arguments don't match.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="nativeFunctions">nativeFunctions</param>
        public static void checkArgumentTypes(FlowController flow, List <NativeFunction> nativeFunctions)
        {
            List <List <AnalysisWarning> > warningsList = new List <List <AnalysisWarning> >();
            MemoryEntry argc          = flow.InSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(flow.OutSet.Snapshot);
            int         argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value;

            foreach (var nativeFunction in nativeFunctions)
            {
                if (nativeFunction.MinArgumentCount <= argumentCount && nativeFunction.MaxArgumentCount >= argumentCount)
                {
                    warningsList.Add(new List <AnalysisWarning>());
                    int functionArgumentNumber = 0;
                    for (int i = 0; i < argumentCount; i++)
                    {
                        MemoryEntry arg = flow.InSet.ReadVariable(Argument(i)).ReadMemory(flow.InSet.Snapshot);

                        NativeFunctionArgument functionArgument = nativeFunction.Arguments.ElementAt(functionArgumentNumber);

                        CheckArgumentTypes(flow, arg, functionArgument, i + 1, nativeFunctions.ElementAt(0).Name.ToString(), warningsList.Last());

                        //incremeneting functionArgumentNumber
                        if (nativeFunction.Arguments.ElementAt(functionArgumentNumber).Dots == false)
                        {
                            functionArgumentNumber++;
                        }
                    }
                }
            }
            int index_min = -1;
            int value_min = int.MaxValue;

            for (int i = 0; i < warningsList.Count; i++)
            {
                if (warningsList[i].Count < value_min)
                {
                    value_min = warningsList[i].Count;
                    index_min = i;
                }
            }
            foreach (AnalysisWarning warning in warningsList[index_min])
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, warning);
            }
        }
Example #6
0
        /// <summary>
        /// Clears the inner fields before new computation is performed.
        /// </summary>
        private void clearComputation()
        {
            AnalysisWarningHandler.ResetWarnings();

            IsFirstPhaseStarted  = false;
            IsSecondPhaseStarted = false;

            IsFirstPhaseFinished  = false;
            IsSecondPhaseFinished = false;

            analysisWarnings    = null;
            securityWarnings    = null;
            secondPhaseWarnings = null;

            programPointGraph   = null;
            firstPhaseAnalysis  = null;
            secondPhaseAnalysis = null;

            // Force garbage collecting
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
Example #7
0
        /// <summary>
        /// Models constructor of native object
        /// </summary>
        /// <param name="flow">FlowController</param>
        public void initObject(FlowController flow)
        {
            var nativeClass = NativeObjectAnalyzer.GetInstance(flow.OutSet).GetClass(ObjectName);
            var fields      = nativeClass.Fields;

            var          thisVariable = flow.OutSet.GetVariable(new VariableIdentifier("this"));
            List <Value> inputValues  = new List <Value>();

            foreach (var argument in getArguments(flow))
            {
                inputValues.AddRange(argument.PossibleValues);
            }
            MethodIdentifier methodIdentifier = new MethodIdentifier(ObjectName, Method.Name.Name);

            if (NativeObjectAnalyzer.ReportingFunctions.ContainsKey(methodIdentifier))
            {
                foreach (var flag in NativeObjectAnalyzer.ReportingFunctions[methodIdentifier])
                {
                    if (FlagsHandler.IsDirty(inputValues, flag))
                    {
                        AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisSecurityWarning(NativeAnalyzerUtils.GetCallerScript(flow.OutSet), flow.CurrentPartial, flow.CurrentProgramPoint, flag, methodIdentifier.Name.ToString()));
                        break;
                    }
                }
            }

            foreach (FieldInfo field in fields.Values)
            {
                if (field.IsStatic == false)
                {
                    MemoryEntry fieldValues = NativeAnalyzerUtils.ResolveReturnValue(field.Type, flow);
                    fieldValues = new MemoryEntry(FlagsHandler.CopyFlags(inputValues, fieldValues.PossibleValues));
                    var fieldEntry = thisVariable.ReadField(flow.OutSet.Snapshot, new VariableIdentifier(field.Name.Value));
                    fieldEntry.WriteMemory(flow.OutSet.Snapshot, fieldValues);
                }
            }
        }
Example #8
0
        public static ResultModel Run(string phpCode, AnalysisModel analysisModel)
        {
            string fileName = @"\UserInput\userInput.php";

            SyntaxParser parser = InitializeParser(phpCode, fileName);
            var          cfg    = ControlFlowGraph.ControlFlowGraph.FromSource(parser.Ast, new FileInfo(fileName));

            var result = new ResultModel(phpCode);

            AnalysisWarningHandler.ResetWarnings();
            if (analysisModel.RunVerification)
            {
                result.Output = RunVerification(cfg, fileName, analysisModel.GetMemoryModel());
            }

            if (analysisModel.RunMetrics)
            {
                RunMetrics(parser, analysisModel, result);
            }

            result.LoadWarnings();

            return(result);
        }
Example #9
0
 public void LoadWarnings()
 {
     Warnings         = AnalysisWarningHandler.GetWarnings();
     SecurityWarnings = AnalysisWarningHandler.GetSecurityWarnings();
 }
Example #10
0
 /// <summary>
 /// Generates a warning of the proper type and with the given message
 /// </summary>
 /// <param name="message">Text of warning</param>
 /// <param name="cause">More specific warning type</param>
 public void SetWarning(string message, AnalysisWarningCause cause)
 {
     AnalysisWarningHandler.SetWarning(Context, new AnalysisWarning(Point.OwningScriptFullName, message, Point.Partial, Point, cause));
 }
Example #11
0
        /// <summary>
        /// Models a called method.
        /// </summary>
        /// <param name="flow"></param>
        public void Analyze(FlowController flow)
        {
            if (NativeAnalyzerUtils.checkArgumentsCount(flow, Method))
            {
                NativeAnalyzerUtils.checkArgumentTypes(flow, Method);
            }
            MethodIdentifier methodIdentifier = new MethodIdentifier(ObjectName, Method.Name.Name);
            var nativeClass = NativeObjectAnalyzer.GetInstance(flow.OutSet).GetClass(ObjectName);
            var fields      = nativeClass.Fields;

            var functionResult = NativeAnalyzerUtils.ResolveReturnValue(Method.ReturnType, flow);
            var arguments      = getArguments(flow);

            var          thisVariable = flow.OutSet.GetVariable(new VariableIdentifier("this"));
            List <Value> inputValues  = new List <Value>();
            bool         isStaticCall = false;

            if (thisVariable.ReadMemory(flow.OutSet.Snapshot).PossibleValues.Count() == 1 && thisVariable.ReadMemory(flow.OutSet.Snapshot).PossibleValues.First() is UndefinedValue)
            {
                isStaticCall = true;
                var fieldsEntries = new List <MemoryEntry>();

                foreach (FieldInfo field in fields.Values)
                {
                    var fieldEntry = thisVariable.ReadField(flow.OutSet.Snapshot, new VariableIdentifier(field.Name.Value));
                    fieldsEntries.Add(fieldEntry.ReadMemory(flow.OutSet.Snapshot));
                    inputValues.AddRange(fieldEntry.ReadMemory(flow.OutSet.Snapshot).PossibleValues);
                }

                fieldsEntries.AddRange(arguments);

                foreach (FieldInfo field in fields.Values)
                {
                    var         fieldEntry     = thisVariable.ReadField(flow.OutSet.Snapshot, new VariableIdentifier(field.Name.Value));
                    MemoryEntry newfieldValues = NativeAnalyzerUtils.ResolveReturnValue(field.Type, flow);
                    newfieldValues = new MemoryEntry(FlagsHandler.CopyFlags(inputValues, newfieldValues.PossibleValues));
                    HashSet <Value> newValues = new HashSet <Value>((fieldEntry.ReadMemory(flow.OutSet.Snapshot)).PossibleValues);
                    foreach (var newValue in newfieldValues.PossibleValues)
                    {
                        newValues.Add(newValue);
                    }
                    thisVariable.ReadField(flow.OutSet.Snapshot, new VariableIdentifier(field.Name.Value)).WriteMemory(flow.OutSet.Snapshot, new MemoryEntry(newValues));
                }
            }

            foreach (var argument in arguments)
            {
                inputValues.AddRange(argument.PossibleValues);
            }

            if (NativeObjectAnalyzer.ReportingFunctions.ContainsKey(methodIdentifier))
            {
                foreach (var flag in NativeObjectAnalyzer.ReportingFunctions[methodIdentifier])
                {
                    if (FlagsHandler.IsDirty(inputValues, flag))
                    {
                        AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisSecurityWarning(NativeAnalyzerUtils.GetCallerScript(flow.OutSet), flow.CurrentPartial, flow.CurrentProgramPoint, flag, methodIdentifier.Name.ToString()));
                        break;
                    }
                }
            }

            if (isStaticCall == true)
            {
                thisVariable.WriteMemory(flow.OutSet.Snapshot, new MemoryEntry(FlagsHandler.CopyFlags(inputValues, thisVariable.ReadMemory(flow.OutSet.Snapshot).PossibleValues)));
            }

            functionResult = new MemoryEntry(FlagsHandler.CopyFlags(inputValues, functionResult.PossibleValues));
            if (NativeObjectAnalyzer.CleaningFunctions.ContainsKey(methodIdentifier))
            {
                foreach (var flag in NativeObjectAnalyzer.CleaningFunctions[methodIdentifier])
                {
                    functionResult = new MemoryEntry(FlagsHandler.Clean(functionResult.PossibleValues, flag));
                }
            }
            flow.OutSet.GetLocalControlVariable(SnapshotBase.ReturnValue).WriteMemory(flow.OutSet.Snapshot, functionResult);

            var assigned_aliases = NativeAnalyzerUtils.ResolveAliasArguments(flow, inputValues, (new NativeFunction[1] {
                Method
            }).ToList());
        }
Example #12
0
        /// <summary>
        /// Checks number of arguments in called function.
        /// </summary>
        /// <param name="flow">FlowControllers</param>
        /// <param name="nativeFunctions">NativeFunctions</param>
        /// <returns>true if the arguments count matches, false otherwise</returns>
        static public bool checkArgumentsCount(FlowController flow, List <NativeFunction> nativeFunctions)
        {
            //check number of arduments
            MemoryEntry argc          = flow.InSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(flow.OutSet.Snapshot);
            int         argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value;

            //argument count hassnt been comupted yet
            if (nativeFunctions.ElementAt(0).MinArgumentCount == -1)
            {
                foreach (var nativeFuntion in nativeFunctions)
                {
                    nativeFuntion.MinArgumentCount = 0;
                    nativeFuntion.MaxArgumentCount = 0;
                    foreach (var nativeFunctionArgument in nativeFuntion.Arguments)
                    {
                        if (nativeFunctionArgument.Dots)
                        {
                            nativeFuntion.MaxArgumentCount = 1000000000;
                        }
                        else if (nativeFunctionArgument.Optional)
                        {
                            nativeFuntion.MaxArgumentCount++;
                        }
                        else
                        {
                            nativeFuntion.MinArgumentCount++;
                            nativeFuntion.MaxArgumentCount++;
                        }
                    }
                    //Console.WriteLine("Name: {0},Min: {1}, Max: {2}", nativeFuntion.Name,nativeFuntion.MinArgumentCount, nativeFuntion.MaxArgumentCount);
                }
            }


            string numberOfArgumentMessage = "";

            bool argumentCountMatches = false;

            foreach (var nativeFunction in nativeFunctions)
            {
                if (nativeFunction.MinArgumentCount <= argumentCount && nativeFunction.MaxArgumentCount >= argumentCount)
                {
                    argumentCountMatches = true;
                }

                if (numberOfArgumentMessage != "")
                {
                    numberOfArgumentMessage += " or";
                }

                if (nativeFunction.MaxArgumentCount >= 1000000000)
                {
                    if (nativeFunction.MinArgumentCount == 1)
                    {
                        numberOfArgumentMessage += " at least " + nativeFunction.MinArgumentCount + " parameter";
                    }
                    else
                    {
                        numberOfArgumentMessage += " at least " + nativeFunction.MinArgumentCount + " parameters";
                    }
                }
                else
                {
                    if (nativeFunction.MaxArgumentCount == nativeFunction.MinArgumentCount)
                    {
                        if (nativeFunction.MinArgumentCount == 1)
                        {
                            numberOfArgumentMessage += " " + nativeFunction.MinArgumentCount + " parameter";
                        }
                        else
                        {
                            numberOfArgumentMessage += " " + nativeFunction.MinArgumentCount + " parameters";
                        }
                    }
                    else
                    {
                        numberOfArgumentMessage += " " + nativeFunction.MinArgumentCount + "-" + nativeFunction.MaxArgumentCount + " parameters";
                    }
                }
            }

            if (argumentCountMatches == false)
            {
                string s = "";
                if (argumentCount != 1)
                {
                    s = "s";
                }
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(NativeAnalyzerUtils.GetCallerScript(flow.OutSet), "Function " + nativeFunctions.ElementAt(0).Name.ToString() + " expects" + numberOfArgumentMessage + ", " + argumentCount + " parameter" + s + " given.", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.WRONG_NUMBER_OF_ARGUMENTS));
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #13
0
 public static int NumWarnings(FlowOutputSet outset)
 {
     return(AnalysisWarningHandler.ReadWarnings <AnalysisWarning>(outset).Count());
 }
Example #14
0
        /// <summary>
        /// Is called after each include/require/include_once/require_once expression (can be resolved according to flow.CurrentPartial)
        /// </summary>
        /// <param name="flow">Flow controller where include extensions can be stored</param>
        /// <param name="includeFile">File argument of include statement</param>
        public override void Include(FlowController flow, MemoryEntry includeFile)
        {
            if (FlagsHandler.IsDirty(includeFile.PossibleValues, FlagType.FilePathDirty))
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisSecurityWarning(flow.CurrentScript.FullName, flow.CurrentPartial, flow.CurrentProgramPoint, FlagType.FilePathDirty, ""));
            }

            bool isAlwaysConcrete = true;
            //extend current program point as Include
            List <string> files = FunctionResolver.GetFunctionNames(includeFile, flow, out isAlwaysConcrete);

            if (isAlwaysConcrete == false)
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Couldn't resolve all possible includes", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.COULDNT_RESOLVE_ALL_INCLUDES));
            }


            IncludingEx includeExpression = flow.CurrentPartial as IncludingEx;

            foreach (var branchKey in flow.ExtensionKeys)
            {
                if (!files.Remove(branchKey as string))
                {
                    //this include is now not resolved as possible include branch
                    flow.RemoveExtension(branchKey);
                }
            }

            int numberOfWarnings = 0;
            var includedFiles    = flow.OutSet.GetControlVariable(new VariableName(".includedFiles")).ReadMemory(flow.OutSet.Snapshot);

            foreach (var file in files)
            {
                var fileInfo = findFile(flow, file);

                if (fileInfo == null)
                {
                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "The file " + file + " to be included not found", flow.CurrentProgramPoint.Partial, flow.CurrentProgramPoint, AnalysisWarningCause.FILE_TO_BE_INCLUDED_NOT_FOUND));
                    numberOfWarnings++;
                    continue;
                }

                string fileName = fileInfo.FullName;

                // Handling include_once, require_once
                var varIncluded = flow.OutSet.GetControlVariable(new VariableName(fileName));
                if (includeExpression.InclusionType == InclusionTypes.IncludeOnce || includeExpression.InclusionType == InclusionTypes.RequireOnce)
                {
                    var includedInfo = varIncluded.ReadMemory(flow.OutSet.Snapshot);
                    if (includedInfo != null)
                    {
                        var includeType = (includeExpression.InclusionType == InclusionTypes.IncludeOnce) ? "include_once" : "require_once";
                        if (includedInfo.PossibleValues.Count() > 1)
                        {
                            //TODO: report or not?
                            //AnalysisWarningHandler.SetWarning (flow.OutSet, new AnalysisWarning (flow.CurrentScript.FullName, includeType + " is called more times in some program paths with the file " + fileName, flow.CurrentProgramPoint.Partial, flow.CurrentProgramPoint, AnalysisWarningCause.INCLUDE_REQUIRE_ONCE_CALLED_MORE_TIMES_WITH_SAME_FILE));
                            // TODO: include the file or not??
                            continue;
                        }
                        else
                        {
                            if (!(includedInfo.PossibleValues.First() is UndefinedValue))
                            {
                                //TODO: report or not?
                                //AnalysisWarningHandler.SetWarning (flow.OutSet, new AnalysisWarning (flow.CurrentScript.FullName, includeType + " is called more times with the file " + fileName, flow.CurrentProgramPoint.Partial, flow.CurrentProgramPoint, AnalysisWarningCause.INCLUDE_REQUIRE_ONCE_CALLED_MORE_TIMES_WITH_SAME_FILE));
                                continue;
                            }
                        }
                    }
                }


                // Avoid recursive includes
                // the file was never included
                int numberOfIncludes = -1;
                // TODO: optimization - avoid iterating all included files
                //  - make .includedFiles associative array with names of functions as indexes
                foreach (InfoValue <NumberOfCalls <string> > includeInfo in includedFiles.PossibleValues.Where(a => (a is InfoValue <NumberOfCalls <string> >)))
                {
                    if (includeInfo.Data.Callee == fileName)
                    {
                        numberOfIncludes = Math.Max(numberOfIncludes, includeInfo.Data.TimesCalled);
                    }
                }
                if (numberOfIncludes >= 0)
                {
                    if (numberOfIncludes > 2 || sharedFiles.Contains(fileName))
                    {
                        if (sharedFiles.Contains(fileName))
                        {
                            //set graph sharing for this function
                            if (!sharedProgramPoints.ContainsKey(fileName))
                            {
                                try
                                {
                                    //create single graph instance
                                    sharedProgramPoints[fileName] = ProgramPointGraph.FromSource(ControlFlowGraph.ControlFlowGraph.FromFile(fileInfo));
                                }
                                catch (ControlFlowGraph.ControlFlowException)
                                {
                                    numberOfWarnings++;
                                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Control flow graph creation error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.CFG_EXCEPTION_IN_INCLUDE_OR_EVAL));
                                }
                                catch (Parsers.ParserException)
                                {
                                    numberOfWarnings++;
                                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Parser error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.PARSER_EXCEPTION_IN_INCLUDE_OR_EVAL));
                                }
                            }

                            //get shared instance of program point graph
                            flow.AddExtension(fileName, sharedProgramPoints[fileName], ExtensionType.ParallelInclude);
                            continue;
                        }
                        else
                        {
                            sharedFiles.Add(fileName);
                        }
                    }
                }

                try
                {
                    // Write information about inclusion of the file
                    varIncluded.WriteMemory(flow.OutSet.Snapshot, new MemoryEntry(flow.OutSet.Snapshot.CreateBool(true)));

                    //Create graph for every include - NOTE: we can share pp graphs
                    var cfg     = ControlFlowGraph.ControlFlowGraph.FromFile(fileInfo);
                    var ppGraph = ProgramPointGraph.FromSource(cfg);
                    flow.AddExtension(fileName, ppGraph, ExtensionType.ParallelInclude);
                }
                catch (ControlFlowGraph.ControlFlowException)
                {
                    numberOfWarnings++;
                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Control flow graph creation error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.CFG_EXCEPTION_IN_INCLUDE_OR_EVAL));
                }
                catch (Parsers.ParserException)
                {
                    numberOfWarnings++;
                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Parser error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.PARSER_EXCEPTION_IN_INCLUDE_OR_EVAL));
                }
            }

            if (numberOfWarnings > 0 && (includeExpression.InclusionType == InclusionTypes.Require || includeExpression.InclusionType == InclusionTypes.RequireOnce))
            {
                if (numberOfWarnings == files.Count && isAlwaysConcrete == true)
                {
                    fatalError(flow, true);
                }
                else
                {
                    fatalError(flow, false);
                }
            }
        }
Example #15
0
        /// <summary>
        /// Process throw statement according to current flow
        /// </summary>
        /// <param name="flow">Flow controller which provides API usefull for throw resolvings</param>
        /// <param name="outSet">Flow output set</param>
        /// <param name="throwStmt">Processed throw statement</param>
        /// <param name="throwedValue">Value that was supplied into throw statement</param>
        /// <returns>
        /// All possible ThrowInfo branches
        /// </returns>
        public override IEnumerable <ThrowInfo> Throw(FlowController flow, FlowOutputSet outSet, ThrowStmt throwStmt, MemoryEntry throwedValue)
        {
            var catchBlocks = outSet.GetControlVariable(new VariableName(".catchBlocks"));
            var stack       = new List <HashSet <CatchBlockDescription> >();

            foreach (var value in catchBlocks.ReadMemory(outSet.Snapshot).PossibleValues)
            {
                if (stack.Count == 0)
                {
                    for (int i = 0; i < (value as InfoValue <TryBlockStack>).Data.blocks.Count; i++)
                    {
                        stack.Add(new HashSet <CatchBlockDescription>());
                    }
                }
                for (int i = 0; i < (value as InfoValue <TryBlockStack>).Data.blocks.Count; i++)
                {
                    foreach (var block in (value as InfoValue <TryBlockStack>).Data.blocks[i])
                    {
                        stack[i].Add(block);
                    }
                }
            }

            Dictionary <CatchBlockDescription, List <Value> > result = new Dictionary <CatchBlockDescription, List <Value> >();
            int numberOfWarnings = 0;

            foreach (Value value in throwedValue.PossibleValues)
            {
                bool foundMatch = false;
                if (value is ObjectValue)
                {
                    TypeValue type          = outSet.ObjectType(value as ObjectValue);
                    var       exceptionName = new QualifiedName(new Name("Exception"));
                    if (type.Declaration.BaseClasses.Where(a => a.Equals(exceptionName)).Count() == 0 && !type.QualifiedName.Equals(exceptionName))
                    {
                        AnalysisWarningHandler.SetWarning(outSet, new AnalysisWarning(flow.CurrentScript.FullName, "Only objects derived from Exception can be thrown", throwStmt, flow.CurrentProgramPoint, AnalysisWarningCause.ONLY_OBJECT_CAM_BE_THROWN));
                        foundMatch = false;
                    }
                    else
                    {
                        for (int i = stack.Count - 1; i >= 0; i--)
                        {
                            foreach (var block in stack[i])
                            {
                                if (type.QualifiedName == block.CatchedType.QualifiedName)
                                {
                                    var key = block;
                                    if (!result.ContainsKey(key))
                                    {
                                        result[key] = new List <Value>();
                                    }
                                    result[key].Add(value);
                                    foundMatch = true;
                                }
                                else
                                {
                                    for (int j = type.Declaration.BaseClasses.Count - 1; j >= 0; j--)
                                    {
                                        if (type.Declaration.BaseClasses[j] == block.CatchedType.QualifiedName)
                                        {
                                            var key = block;
                                            if (!result.ContainsKey(key))
                                            {
                                                result[key] = new List <Value>();
                                            }
                                            result[key].Add(value);
                                            foundMatch = true;
                                            break;
                                        }
                                    }
                                }
                                if (foundMatch)
                                {
                                    break;
                                }
                            }
                            if (foundMatch)
                            {
                                break;
                            }
                        }
                    }
                }
                else if (value is AnyObjectValue || value is AnyValue)
                {
                    for (int i = stack.Count - 1; i >= 0; i--)
                    {
                        foreach (var block in stack[i])
                        {
                            var key = block;

                            if (!result.ContainsKey(key))
                            {
                                result[key] = new List <Value>();
                            }
                            result[key].Add(value);
                            foundMatch = true;
                        }
                    }
                }
                else
                {
                    AnalysisWarningHandler.SetWarning(outSet, new AnalysisWarning(flow.CurrentScript.FullName, "Only objects can be thrown", throwStmt, flow.CurrentProgramPoint, AnalysisWarningCause.ONLY_OBJECT_CAM_BE_THROWN));
                    numberOfWarnings++;
                    foundMatch = false;
                }
                if (!foundMatch)
                {
                    var key = new CatchBlockDescription(flow.ProgramEnd, new GenericQualifiedName(new QualifiedName(new Name(""))), new VariableIdentifier(""));
                    if (!result.ContainsKey(key))
                    {
                        result[key] = new List <Value>();
                    }
                    result[key].Add(value);
                }
            }

            List <ThrowInfo> res = new List <ThrowInfo>();

            foreach (var entry in result)
            {
                res.Add(new ThrowInfo(entry.Key, new MemoryEntry(entry.Value)));
            }

            if (numberOfWarnings >= throwedValue.Count)
            {
                fatalError(flow, true);
            }
            else if (numberOfWarnings > 0)
            {
                fatalError(flow, false);
            }

            return(res);
        }
Example #16
0
        /// <summary>
        /// Execute the static analysis and print results
        /// </summary>
        /// <param name="filenames">List of file name patterns from command line</param>
        /// <param name="memoryModel">The memory model used for analysis</param>
        private static void RunStaticAnalysis(string[] filenames, MemoryModels.MemoryModelFactory memoryModel, bool displayTaintFlows)
        {
            var console = new ConsoleOutput();

            console.CommentLine("Using " + memoryModel.ToString());
            console.CommentLine("");
            foreach (var argument in filenames)
            {
                var filesInfo = Analyzer.GetFileNames(argument);
                if (filesInfo == null)
                {
                    Console.WriteLine("Path \"{0}\" cannot be recognized", argument);
                    Console.WriteLine();
                    continue;
                }
                else if (filesInfo.Length <= 0)
                {
                    Console.WriteLine("Path pattern \"{0}\" does not match any file", argument);
                    Console.WriteLine();
                    continue;
                }

                foreach (var fileInfo in filesInfo)
                {
                    // This is for time consumption analyzing only
                    // Analyze twice - because of omitting .NET initialization we get better analysis time
                    //Analyzer.Run(fileInfo, memoryModel);

#if TEST
                    // Process analysis
                    // First phase
                    var watch   = System.Diagnostics.Stopwatch.StartNew();
                    var ppGraph = Analyzer.Run(fileInfo, memoryModel);
                    watch.Stop();

                    // Second phase
                    var watch2    = System.Diagnostics.Stopwatch.StartNew();
                    var nextPhase = new TaintForwardAnalysis(ppGraph);
                    nextPhase.Analyse();
                    watch2.Stop();

                    // Build output

                    console.CommentLine(string.Format("File path: {0}\n", fileInfo.FullName));

                    var graphWalker = new GraphWalking.CallGraphPrinter(ppGraph);
                    console.CommentLine(string.Format("Analysis completed in: {0}ms\n", watch.ElapsedMilliseconds));

                    //graphWalker.Run(console);

                    console.Warnings(AnalysisWarningHandler.GetWarnings(), AnalysisWarningHandler.GetSecurityWarnings());

                    console.CommentLine(string.Format("Analysis completed in: {0}ms\n", watch.ElapsedMilliseconds));
                    console.CommentLine(string.Format("The number of nodes in the application is: {0}\n", numProgramPoints(new HashSet <ProgramPointGraph>(), new Dictionary <string, HashSet <int> >(), ppGraph)));


                    //printIncludes(console, ppGraph);


                    //console.CommentLine(string.Format("Analysis in the second phase completed in: {0}ms\n", watch2.ElapsedMilliseconds));
                    //console.WarningsTaint(nextPhase.analysisTaintWarnings);

                    if (ppGraph.End.OutSet != null)
                    {
                        console.CommentLine(string.Format("The number of memory locations is: {0}\n", ppGraph.End.OutSnapshot.NumMemoryLocations()));
                        int[] statistics = ppGraph.End.OutSnapshot.GetStatistics().GetStatisticsValues();
                        console.CommentLine(string.Format("The number of memory entry assigns is: {0}\n", statistics[(int)Statistic.MemoryEntryAssigns]));
                        console.CommentLine(string.Format("The number of value reads is: {0}\n", statistics[(int)Statistic.ValueReads]));
                        console.CommentLine(string.Format("The number of memory entry merges is: {0}\n", statistics[(int)Statistic.MemoryEntryMerges]));
                        console.CommentLine(string.Format("The number of index reads is: {0}\n", statistics[(int)Statistic.IndexReads]));
                        console.CommentLine(string.Format("The number of value reads is: {0}\n", statistics[(int)Statistic.ValueReads]));
                    }
                    else
                    {
                        console.CommentLine(string.Format("Snapshot statistics are not available, because end point was not reached"));
                    }
#else
                    console.CommentLine(string.Format("File path: {0}\n", fileInfo.FullName));
                    TaintForwardAnalysis         nextPhase = null;
                    System.Diagnostics.Stopwatch watch     = null;

                    try
                    {
                        watch = System.Diagnostics.Stopwatch.StartNew();
                        var ppGraph = Analyzer.Run(fileInfo, memoryModel);
                        watch.Stop();

                        if (ppGraph.End.OutSet != null)
                        {
                            //console.ProgramPointInfo("End point", ppGraph.End);
                        }
                        else
                        {
                            //console.Error("End point was not reached");
                        }
                        console.CommentLine(string.Format("First phase of the analysis completed in: {0} seconds\n", watch.ElapsedMilliseconds / 1000));

                        nextPhase = new TaintForwardAnalysis(ppGraph);
                        nextPhase.Analyse();
                    }
                    catch (OutOfMemoryException)
                    {
                        watch.Stop();
                        console.Error(string.Format("The analyser ran out of memory after {0} seconds, terminating the analysis.\n", watch.ElapsedMilliseconds / 1000));
                    }
                    catch (Exception e)
                    {
                        console.Error("Analyser crashed (" + e.Message + ").");
                    }
                    finally
                    {
                        console.Warnings(AnalysisWarningHandler.GetWarnings(), nextPhase != null ? nextPhase.analysisTaintWarnings : new List <AnalysisTaintWarning>(), displayTaintFlows);
                    }
#endif
                }
                //Console.ReadKey();
                Console.WriteLine();
            }
        }
Example #17
0
        private static void RunStaticAnalysis(string[] filenames, MemoryModels.MemoryModelFactory memoryModel)
        {
            var bigWatch = System.Diagnostics.Stopwatch.StartNew();
            var console  = new ConsoleOutput();

            foreach (var argument in filenames)
            {
                var filesInfo = Analyzer.GetFileNames(argument);
                if (filesInfo == null)
                {
                    fileOutput.WriteLine("Path \"{0}\" cannot be recognized", argument);
                    fileOutput.WriteLine();
                    continue;
                }

                else if (filesInfo.Length <= 0)
                {
                    fileOutput.WriteLine("Path pattern \"{0}\" does not match any file", argument);
                    fileOutput.WriteLine();
                }

                foreach (var fileInfo in filesInfo)
                {
                    console.CommentLine(string.Format("File path: {0}\n", fileInfo.FullName));

                    //try
                    {
                        var watch   = System.Diagnostics.Stopwatch.StartNew();
                        var ppGraph = Analyzer.Run(fileInfo, memoryModel);
                        watch.Stop();

                        GC.Collect();
                        GC.WaitForPendingFinalizers();

                        var watch2    = System.Diagnostics.Stopwatch.StartNew();
                        var nextPhase = new TaintForwardAnalysis(ppGraph);
                        nextPhase.analysisTaintWarnings = new List <AnalysisTaintWarning>();
                        if (SECOND_PHASE)
                        {
                            nextPhase.Analyse();
                        }
                        watch2.Stop();


                        fileOutput.WriteLine("Analysis warnings:");
                        var firstPhaseWarnings = AnalysisWarningHandler.GetWarnings();
                        //PrintWarnings(new List<AnalysisWarning>());
                        PrintWarnings(firstPhaseWarnings);
                        var firstPhaseSecurityWarnings = new List <AnalysisSecurityWarning>();
                        if (!SECOND_PHASE)
                        {
                            firstPhaseSecurityWarnings = AnalysisWarningHandler.GetSecurityWarnings();
                            PrintSecurityWarnings(firstPhaseSecurityWarnings);
                        }


                        //fileOutput.WriteLine("Security warnings with taint flow:");
                        if (SECOND_PHASE)
                        {
                            PrintTaintWarnings(nextPhase.analysisTaintWarnings);
                        }

                        fileOutput.WriteLine("Variables:");
                        var processedPPGraphs = new HashSet <ProgramPointGraph>();
                        var processedPPoints  = new HashSet <ProgramPointBase>();
                        writeAll(ppGraph, ref processedPPGraphs, ref processedPPoints);

                        bigWatch.Stop();

                        fileOutput.WriteLine("Overview:");

                        fileOutput.WriteLine("Total number of warnings: " + (firstPhaseWarnings.Count + firstPhaseSecurityWarnings.Count + nextPhase.analysisTaintWarnings.Count));
                        fileOutput.WriteLine("Number of warnings in the first phase: " + firstPhaseWarnings.Count);
                        fileOutput.WriteLine("Number of warnings in the second phase: " + nextPhase.analysisTaintWarnings.Count);
                        fileOutput.WriteLine("Weverca analyzer time consumption: " + bigWatch.ElapsedMilliseconds);
                        fileOutput.WriteLine("First phase time consumption: " + watch.ElapsedMilliseconds);
                        fileOutput.WriteLine("Second phase time consumption: " + watch2.ElapsedMilliseconds);
                        var programLines = new Dictionary <string, HashSet <int> > ();
                        fileOutput.WriteLine("The number of nodes in the application is: " + Program.numProgramPoints(new HashSet <ProgramPointGraph>(), programLines, ppGraph));
                        var programLinesNum = 0;
                        foreach (var script in programLines.Values)
                        {
                            programLinesNum += script.Count;
                        }
                        fileOutput.WriteLine("The number of processed lines of code is: " + programLinesNum);
                    }

                    /*
                     * catch (Exception e)
                     * {
                     *  fileOutput.WriteLine("error");
                     *  //console.Error(e.Message);
                     *  fileOutput.WriteLine (e.Message);
                     * }*/
                }
            }
        }
Example #18
0
        /// <inheritdoc />
        public override void Eval(FlowController flow, MemoryEntry code)
        {
            var flags = FlagsHandler.GetFlags(code.PossibleValues);

            if (flags.isDirty(FlagType.FilePathDirty) || flags.isDirty(FlagType.SQLDirty) || flags.isDirty(FlagType.FilePathDirty))
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisSecurityWarning(flow.CurrentScript.FullName, "Eval shoudn't contain anything from user input", flow.CurrentPartial, flow.CurrentProgramPoint, FlagType.HTMLDirty));
            }

            double evalDepth = 0;
            var    maxValue  = new MaxValueVisitor(flow.OutSet);

            evalDepth = maxValue.Evaluate(flow.OutSet.GetControlVariable(FunctionResolver.evalDepth).ReadMemory(flow.OutSet.Snapshot));
            if (evalDepth > 3)
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, @"Eval cannot be called in ""eval recursion"" more than 3 times", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.TOO_DEEP_EVAL_RECURSION));
                return;
            }


            StringConverter converter = new StringConverter();

            converter.SetContext(flow);

            bool isAllwasConcrete = true;
            var  codes            = new HashSet <string>();

            foreach (StringValue possibleFile in converter.Evaluate(code, out isAllwasConcrete))
            {
                codes.Add(string.Format("<? {0}; ?>", possibleFile.Value));
            }

            if (isAllwasConcrete == false)
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Couldn't resolve all possible evals", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.COULDNT_RESOLVE_ALL_EVALS));
            }

            foreach (var branchKey in flow.ExtensionKeys)
            {
                if (branchKey is string)
                {
                    if (!codes.Remove(branchKey as string))
                    {
                        //this eval is now not resolved as possible eval branch
                        flow.RemoveExtension(branchKey);
                    }
                }
            }
            int numberOfWarnings = 0;

            foreach (var sourceCode in codes)
            {
                try
                {
                    var cfg     = ControlFlowGraph.ControlFlowGraph.FromSource(sourceCode, flow.CurrentScript.FullName);
                    var ppGraph = ProgramPointGraph.FromSource(cfg);
                    flow.AddExtension(sourceCode, ppGraph, ExtensionType.ParallelEval);
                }
                catch (ControlFlowGraph.ControlFlowException)
                {
                    numberOfWarnings++;
                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Control flow graph creation error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.CFG_EXCEPTION_IN_INCLUDE_OR_EVAL));
                }
                catch (Parsers.ParserException)
                {
                    numberOfWarnings++;
                    AnalysisWarningHandler.SetWarning(flow.OutSet, new AnalysisWarning(flow.CurrentScript.FullName, "Parser error", flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.PARSER_EXCEPTION_IN_INCLUDE_OR_EVAL));
                }
            }

            if (numberOfWarnings > 0)
            {
                if (numberOfWarnings == codes.Count && isAllwasConcrete == true)
                {
                    fatalError(flow, true);
                }
                else
                {
                    fatalError(flow, false);
                }
            }
        }