Beispiel #1
0
 /// <inheritdoc />
 public override MemoryEntry ReadAnyValueIndex(AnyValue value, MemberIdentifier index)
 {
     // TODO: Copy info
     if (value is AnyStringValue)
     {
         // Element of string is one charachter but since PHP has no character type,
         // it returns string with one character. The character do not need to be initialized
         SetWarning("Possibly uninitialized string offset");
         return(new MemoryEntry(Context.AnyStringValue));
     }
     else if ((value is AnyNumericValue) || (value is AnyBooleanValue) || (value is AnyResourceValue))
     {
         SetWarning("Trying to get element of scalar value",
                    AnalysisWarningCause.ELEMENT_OF_NON_ARRAY_VARIABLE);
         return(new MemoryEntry(Context.UndefinedValue));
     }
     else if (value is AnyObjectValue)
     {
         // TODO: This must be error
         SetWarning("Cannot use object as array");
         return(new MemoryEntry(Context.AnyValue));
     }
     else
     {
         // This is case of AnyArrayValue, AnyValue and possibly others.
         // If value is AnyValue, it can be any object too, so it can cause an error.
         Value newValue = Context.AnyValue;
         newValue = FlagsHandler.CopyFlags(value, newValue);
         return(new MemoryEntry(newValue));
     }
 }
Beispiel #2
0
        /// <summary>
        /// Convert values to string representation and concatenate them.
        /// </summary>
        /// <param name="leftOperand">The left operand of concatenation.</param>
        /// <param name="rightOperand">The right operand of concatenation.</param>
        /// <returns>Concatenated string of both operands.</returns>
        public Value EvaluateConcatenation(Value leftOperand, Value rightOperand)
        {
            // Gets type of left operand and convert to string
            leftOperand.Accept(this);

            var leftString = result;

            // Gets type of right operand and convert to string
            rightOperand.Accept(this);

            // Get all flags from both operands if they are tainted
            var flags    = FlagsHandler.GetFlagsFromValues(leftOperand, rightOperand);
            var flagInfo = new Flags(flags);

            // Check whether it is concrete or abstract value
            Value taintedResult;

            if ((leftString != null) && (result != null))
            {
                taintedResult = OutSet.CreateString(string.Concat(leftString.Value, result.Value));
            }
            else
            {
                taintedResult = OutSet.AnyStringValue;
            }

            return(taintedResult.SetInfo(flagInfo));
        }
Beispiel #3
0
        /// <summary>
        /// For arguments passed by reference: it assignes new values, and copies flags form inputValues.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="inputValues">Input values into analyzed function</param>
        /// <param name="nativeFunctions">Info about analyzed function</param>
        /// <returns>List of assigned values into aliases</returns>
        public static List <Value> ResolveAliasArguments(FlowController flow, List <Value> inputValues, List <NativeFunction> nativeFunctions)
        {
            List <Value> result        = new List <Value>();
            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)
                {
                    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);
                        if (functionArgument.ByReference == true)
                        {
                            MemoryEntry res = NativeAnalyzerUtils.ResolveReturnValue(functionArgument.Type, flow);
                            res = new MemoryEntry(FlagsHandler.CopyFlags(inputValues, res.PossibleValues));
                            flow.OutSet.GetVariable(Argument(i)).WriteMemory(flow.OutSet.Snapshot, res);
                            result.AddRange(res.PossibleValues);
                        }


                        //incremeneting functionArgumentNumber
                        if (nativeFunction.Arguments.ElementAt(functionArgumentNumber).Dots == false)
                        {
                            functionArgumentNumber++;
                        }
                    }
                }
            }
            return(result);
        }
Beispiel #4
0
 /// <summary>
 /// Widens given values
 /// </summary>
 /// <param name="values">input values</param>
 /// <param name="Context">Snapshot</param>
 /// <returns>Memory entry with widen values</returns>
 public MemoryEntry Widen(IEnumerable <Value> values, SnapshotBase Context)
 {
     flags = FlagsHandler.GetFlags(values);
     foreach (var value in values)
     {
         value.Accept(this);
     }
     return(GetResult(Context));
 }
Beispiel #5
0
        /// <summary>
        /// Convert all possible values to string representation and concatenate every combination of them.
        /// </summary>
        /// <param name="leftOperand">The left operand of concatenation.</param>
        /// <param name="rightOperand">The right operand of concatenation.</param>
        /// <returns>All string ​​resulting from the combination of left and right operand values.</returns>
        public MemoryEntry EvaluateConcatenation(MemoryEntry leftOperand, MemoryEntry rightOperand)
        {
            var values = new HashSet <Value>();

            AnyStringValue leftAnyString;
            var            leftStrings = Evaluate(leftOperand, out leftAnyString);

            AnyStringValue rightAnyString;
            var            rightStrings = Evaluate(rightOperand, out rightAnyString);

            if ((leftAnyString != null) || (rightAnyString != null))
            {
                // Get all flags from both abstract operands if they are tainted
                Dictionary <FlagType, bool> flags;
                if (leftAnyString != null)
                {
                    if (rightAnyString != null)
                    {
                        flags = FlagsHandler.GetFlagsFromValues(leftAnyString, rightAnyString);
                    }
                    else
                    {
                        flags = FlagsHandler.GetFlagsFromValues(leftAnyString);
                    }
                }
                else
                {
                    flags = FlagsHandler.GetFlagsFromValues(rightAnyString);
                }

                var flagInfo = new Flags(flags);
                values.Add(OutSet.AnyStringValue.SetInfo(flagInfo));
            }

            foreach (var leftValue in leftStrings)
            {
                foreach (var rightValue in rightStrings)
                {
                    // Get all flags from all combinations of both operands if they are tainted
                    var taintedResult = OutSet.CreateString(string.Concat(leftValue.Value,
                                                                          rightValue.Value));

                    if ((leftValue.GetInfo <Flags>() != null) || (rightValue.GetInfo <Flags>() != null))
                    {
                        var flags    = FlagsHandler.GetFlagsFromValues(leftValue, rightValue);
                        var flagInfo = new Flags(flags);
                        values.Add(taintedResult.SetInfo(flagInfo));
                    }
                    else
                    {
                        values.Add(taintedResult);
                    }
                }
            }

            return(new MemoryEntry(values));
        }
Beispiel #6
0
        internal static void AssertIsXSSDirty(FlowOutputSet outSet, string variableName, string assertMessage)
        {
            var variable = outSet.GetVariable(new VariableIdentifier(variableName));
            var values   = variable.ReadMemory(outSet.Snapshot).PossibleValues.ToArray();

            if (!FlagsHandler.IsDirty(values, FlagType.SQLDirty))
            {
                Assert.Fail("No possible value for variable ${0} is dirty", variableName);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Main loop, runs the WebSocket connection.
        /// </summary>
        protected void RunSocket()
        {
            //We don't really need to store the handlers;
            //just create them and let them call our EnqueueMessage method.
            //XXX automatically find these like WebServer does.
            Log($"Creating socket handlers (thread: {Thread.CurrentThread.Name})");
            BudgetHandler       budgetHandler       = new BudgetHandler(this);
            BuildingHandler     buildingHandler     = new BuildingHandler(this);
            CameraHandler       cameraHandler       = new CameraHandler(this);
            ChirperHandler      chirperHandler      = new ChirperHandler(this);
            CitizenHandler      citizenHandler      = new CitizenHandler(this);
            CityInfoHandler     cityInfoHandler     = new CityInfoHandler(this);
            DebugHandler        debugHandler        = new DebugHandler(this);
            DistrictHandler     districtHandler     = new DistrictHandler(this);
            FlagsHandler        flagsHandler        = new FlagsHandler(this);
            InstancesHandler    instancesHandler    = new InstancesHandler(this);
            LimitsHandler       limitsHandler       = new LimitsHandler(this);
            NotificationHandler notificationHandler = new NotificationHandler(this);
            ReflectionHandler   reflectionHandler   = new ReflectionHandler(this);
            TerrainHandler      terrainHandler      = new TerrainHandler(this);
            TransportHandler    transportHandler    = new TransportHandler(this);
            VehicleHandler      vehicleHandler      = new VehicleHandler(this);

            Log("Waiting for messages");
            try {
                while (true)
                {
                    if (stream.DataAvailable)
                    {
                        HandleNextMessage();
                    }
                    String msg = GetNextOutgoingMessage();
                    if (msg != null)
                    {
                        byte[] buf = Encoding.UTF8.GetBytes(msg);
                        SendFrame(buf);
                    }
                    Thread.Sleep(100);
                }
            }
            catch (ObjectDisposedException) {
                //we're done, stream is closed
                Log("Connection closed");
            }
            catch (OperationCanceledException) {
                Log("Connection closed");
            }
        }
Beispiel #8
0
        /// <inheritdoc />
        public override void VisitAnyValue(AnyValue value)
        {
            // TODO: This is possible fatal error
            result = null;

            if (value.GetInfo <Flags>() != null)
            {
                var flags    = FlagsHandler.GetFlagsFromValues(value);
                var flagInfo = new Flags(flags);
                abstractResult = (AnyStringValue)OutSet.AnyStringValue.SetInfo(flagInfo);
            }
            else
            {
                abstractResult = OutSet.AnyStringValue;
            }
        }
Beispiel #9
0
        /// <inheritdoc />
        public override IEnumerable <Value> WriteStringIndex(StringValue indexed, MemberIdentifier index, MemoryEntry writtenValue)
        {
            HashSet <Value>       result    = new HashSet <Value>();
            SimpleStringConverter converter = new SimpleStringConverter(Context);
            bool isConcrete = false;

            foreach (var value in converter.Evaluate(writtenValue.PossibleValues, out isConcrete))
            {
                string WrittenChar = value.Value;

                foreach (var number in ResolveStringIndex(indexed, index))
                {
                    Value newValue;
                    if (number < 0)
                    {
                        newValue = indexed;
                        SetWarning("Cannot index string with negative numbers", AnalysisWarningCause.INDEX_OUT_OF_RANGE);
                    }
                    else if (number < indexed.Value.Count())
                    {
                        StringBuilder newString = new StringBuilder();
                        newString.Append(indexed.Value);
                        newString[number] = WrittenChar[0];
                        newValue          = FlagsHandler.CopyFlags(indexed, Context.CreateString(newString.ToString()));
                    }
                    else if (number == indexed.Value.Count())
                    {
                        newValue = FlagsHandler.CopyFlags(indexed, Context.CreateString(indexed.Value + "" + WrittenChar[0].ToString()));
                    }
                    else
                    {
                        newValue = FlagsHandler.CopyFlags(indexed, Context.CreateString(indexed.Value + " " + WrittenChar[0].ToString()));
                    }
                    result.Add(newValue);
                }
            }
            if (!isConcrete)
            {
                result.Add(FlagsHandler.CopyFlags(indexed, Context.AnyStringValue));
            }
            return(result);
        }
Beispiel #10
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);
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Converts all possible values in memory entry to string representation.
        /// </summary>
        /// <param name="entry">Memory entry with all possible values to convert.</param>
        /// <param name="abstractString">Abstract string value if any conversion fails.</param>
        /// <returns>List of strings after conversion of all possible values.</returns>
        public IEnumerable <StringValue> Evaluate(MemoryEntry entry, out AnyStringValue abstractString)
        {
            var values          = new HashSet <StringValue>();
            var abstractStrings = new HashSet <AnyStringValue>();

            foreach (var value in entry.PossibleValues)
            {
                // Gets type of value and convert to string
                value.Accept(this);

                Debug.Assert((result != null) != (abstractResult != null),
                             "Result can be either concrete or abstract string value");

                if (result != null)
                {
                    values.Add(result);
                }
                else
                {
                    abstractStrings.Add(abstractResult);
                }
            }

            if (abstractStrings.Count > 0)
            {
                var flags    = FlagsHandler.GetFlagsFromValues(abstractStrings);
                var flagInfo = new Flags(flags);
                abstractString = (AnyStringValue)OutSet.AnyStringValue.SetInfo(flagInfo);
            }
            else
            {
                abstractString = null;
            }

            return(values);
        }
Beispiel #12
0
        /// <summary>
        /// Perform simplification of memory entry
        /// In some cases resulting memory entry contains leas accurate information
        /// </summary>
        /// <param name="entry">Memory entry</param>
        /// <returns>simplified memory entry</returns>
        public IEnumerable <Value> Simplify(MemoryEntry entry)
        {
            foreach (var value in entry.PossibleValues)
            {
                value.Accept(this);
            }

            if (booleans.Count >= 2)
            {
                result.Add(context.AnyBooleanValue);
            }
            else
            {
                foreach (var boolean in booleans)
                {
                    result.Add(boolean);
                }
            }

            if (strings.Count >= 2)
            {
                result.Add(FlagsHandler.CopyFlags(strings, context.AnyStringValue));
            }
            else
            {
                foreach (var str in strings)
                {
                    result.Add(str);
                }
            }

            if (containsInt)
            {
                if (minInt == maxInt)
                {
                    result.Add(context.CreateInt(minInt));
                }
                else
                {
                    result.Add(context.CreateIntegerInterval(minInt, maxInt));
                }
            }

            if (containsLong)
            {
                if (minLong == maxLong)
                {
                    result.Add(context.CreateLong(minLong));
                }
                else
                {
                    result.Add(context.CreateLongintInterval(minLong, maxLong));
                }
            }

            if (containsFloat)
            {
                if (minFloat == maxFloat)
                {
                    result.Add(context.CreateDouble(minFloat));
                }
                else
                {
                    result.Add(context.CreateFloatInterval(minFloat, maxFloat));
                }
            }


            return(result);
        }
Beispiel #13
0
 public static void IsDirty(IEnumerable <Value> values)
 {
     Debug.Assert(FlagsHandler.IsDirty(values, FlagType.SQLDirty) && FlagsHandler.IsDirty(values, FlagType.HTMLDirty) && FlagsHandler.IsDirty(values, FlagType.FilePathDirty));
 }
Beispiel #14
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);
                }
            }
        }
Beispiel #15
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);
                }
            }
        }
Beispiel #16
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());
        }