Пример #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));
     }
 }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
                }
            }
        }
Пример #5
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);
        }
Пример #6
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());
        }