/// <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)); } }
/// <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)); }
/// <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); }
/// <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)); }
/// <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)); }
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); } }
/// <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"); } }
/// <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; } }
/// <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); }
/// <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); } } }
/// <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); }
/// <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); }
public static void IsDirty(IEnumerable <Value> values) { Debug.Assert(FlagsHandler.IsDirty(values, FlagType.SQLDirty) && FlagsHandler.IsDirty(values, FlagType.HTMLDirty) && FlagsHandler.IsDirty(values, FlagType.FilePathDirty)); }
/// <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); } } }
/// <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); } } }
/// <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()); }