예제 #1
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);
        }
예제 #2
0
        /// <summary>
        /// Creates an object a initialize default with defualt fields.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="type">Type to resolve</param>
        /// <returns>ObjectValue</returns>
        private static Value CreateObject(FlowController flow, string type)
        {
            var           objectAnalyzer = NativeObjectAnalyzer.GetInstance(flow.OutSet);
            QualifiedName typeName       = new QualifiedName(new Name(type));

            if (objectAnalyzer.ExistClass(typeName))
            {
                ClassDecl   decl      = objectAnalyzer.GetClass(typeName);
                var         fields    = objectAnalyzer.GetClass(typeName).Fields;
                ObjectValue value     = flow.OutSet.CreateObject(flow.OutSet.CreateType(decl));
                var         newObject = flow.OutSet.GetLocalControlVariable(new VariableName(".tmpObject" + type));
                newObject.WriteMemory(flow.OutSet.Snapshot, new MemoryEntry(value));
                if (value is ObjectValue)
                {
                    foreach (FieldInfo field in fields.Values)
                    {
                        if (field.IsStatic == false)
                        {
                            var newField = newObject.ReadField(flow.OutSet.Snapshot, new VariableIdentifier(field.Name.Value));
                            try {
                                newField.WriteMemory(flow.OutSet.Snapshot, NativeAnalyzerUtils.ResolveReturnValue(field.Type, flow));
                            } catch (Exception) {}
                        }
                    }
                }
                return(value);
            }
            else
            {
                return(flow.OutSet.AnyObjectValue);
            }
        }
예제 #3
0
        /// <summary>
        /// Models constructor of native object
        /// </summary>
        /// <param name="flow">FlowController</param>
        public void Construct(FlowController flow)
        {
            if (NativeAnalyzerUtils.checkArgumentsCount(flow, Method))
            {
                NativeAnalyzerUtils.checkArgumentTypes(flow, Method);
            }

            initObject(flow);
        }
예제 #4
0
        /// <summary>
        /// Reads all arguments and returns them in List
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <returns>List of arguments</returns>
        private List <MemoryEntry> getArguments(FlowController flow)
        {
            MemoryEntry argc          = flow.InSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(flow.OutSet.Snapshot);
            int         argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value;
            var         arguments     = new List <MemoryEntry>();

            for (int i = 0; i < argumentCount; i++)
            {
                arguments.Add(flow.OutSet.ReadVariable(NativeAnalyzerUtils.Argument(i)).ReadMemory(flow.OutSet.Snapshot));
            }

            return(arguments);
        }
예제 #5
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);
                }
            }
        }
예제 #6
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);
            }
        }
예제 #7
0
        /// <summary>
        /// Check type of one argument and reports warnings if they doesn't match.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="memoryEntry">Values of argument</param>
        /// <param name="argument">Information about argument</param>
        /// <param name="argumentNumber">Number of argument</param>
        /// <param name="functionName">Name of function</param>
        /// <param name="warnings">List of warnings, for inserting warnings</param>
        private static void CheckArgumentTypes(FlowController flow, MemoryEntry memoryEntry, NativeFunctionArgument argument, int argumentNumber, string functionName, List <AnalysisWarning> warnings)
        {
            bool argumentMatches = true;

            foreach (Value value in memoryEntry.PossibleValues)
            {
                if (value is AnyValue || value is UndefinedValue)
                {
                    continue;
                }

                switch (argument.Type)
                {
                case "mixed":
                    break;

                case "int":
                case "integer":
                    //TODO: workaround: type declarations in .xml files specifies the arguments that should be of type number by type int
                    // fix declarations in xml files!!
                    //if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value)))
                    if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value) || ValueTypeResolver.IsFloat(value)))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "float":
                case "number":
                    if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value) || ValueTypeResolver.IsFloat(value)))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "string":
                case "char":
                    if (!ValueTypeResolver.IsString(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "array":
                    if (!ValueTypeResolver.IsArray(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "object":
                    if (!ValueTypeResolver.IsObject(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "bool":
                case "boolean":
                    if (!ValueTypeResolver.IsBool(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "resource":
                case "resouce":
                    if (!(value is AnyResourceValue))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "callable":
                case "callback":
                    if (!ValueTypeResolver.IsString(value) && !(value is FunctionValue))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "void":
                    throw new Exception("Void is not a type of argument");

                default:
                    if (!ValueTypeResolver.IsObject(value))
                    {
                        argumentMatches = false;
                    }
                    break;
                }
            }
            if (argumentMatches == false)
            {
                warnings.Add(new AnalysisWarning(NativeAnalyzerUtils.GetCallerScript(flow.OutSet), "Wrong type of argument number " + argumentNumber + " in function " + functionName + ", expecting " + argument.Type, flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.WRONG_ARGUMENTS_TYPE));
            }
        }
예제 #8
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());
        }