internal FlowOutputSet GetDeclarationOutput(ProgramPointGraph ppg, string name) { var visitedPoints = new HashSet <ProgramPointBase>(); var bfsQueue = new Queue <ProgramPointBase>(); bfsQueue.Enqueue(ppg.Start); while (bfsQueue.Count > 0) { var point = bfsQueue.Dequeue(); var variable = point.OutSet.GetVariable(new VariableIdentifier(name)); if (variable.IsDefined(point.OutSnapshot)) { //we have found first place where variable is defined return(point.OutSet); } visitedPoints.Add(point); foreach (var child in point.FlowChildren) { if (visitedPoints.Contains(child)) { continue; } bfsQueue.Enqueue(child); } } return(null); }
internal void ExtendAsCall(SnapshotBase callerContext, ProgramPointGraph callee, MemoryEntry thisObject, MemoryEntry[] arguments) { checkCanUpdate(); _statistics.Report(Statistic.AsCallExtendings); extendAsCall(callerContext, callee, thisObject, arguments); }
/// <summary> /// Runs the first phase analysis. /// </summary> private void runFirstPhaseAnalysis() { State = AnalysisState.ForwardAnalysis; FirstPhaseInitialMemory = GC.GetTotalMemory(true); WatchFirstPhase.Start(); try { firstPhaseAnalysis = new Weverca.Analysis.ForwardAnalysis(controlFlowGraph, MemoryModel); IsFirstPhaseStarted = true; firstPhaseAnalysis.Analyse(); } finally { WatchFirstPhase.Stop(); FirstPhaseEndMemory = GC.GetTotalMemory(true); if (IsFirstPhaseStarted) { programPointGraph = firstPhaseAnalysis.ProgramPointGraph; analysisWarnings = AnalysisWarningHandler.GetWarnings(); securityWarnings = AnalysisWarningHandler.GetSecurityWarnings(); } } if (IsFirstPhaseStarted) { IsFirstPhaseFinished = true; } }
/// <summary> /// Walk given program point graph of call /// </summary> /// <param name="callPpGraph">Program point of walked call</param> /// <param name="visitedPoints">allready visited points</param> private void walkCall(ProgramPointGraph callPpGraph, HashSet <ProgramPointBase> visitedPoints) { pushCall(callPpGraph); var pointsToVisit = new Queue <ProgramPointBase>(); visitPoint(callPpGraph.Start, pointsToVisit, visitedPoints); while (pointsToVisit.Count > 0) { var point = pointsToVisit.Dequeue(); onWalkPoint(point); if (point.Extension.IsConnected) { walkExtension(point.Extension, pointsToVisit, visitedPoints); } else { //walk flow children foreach (var child in point.FlowChildren) { visitPoint(child, pointsToVisit, visitedPoints); } } } popCall(); }
public void IncludeTest1() { // Run analysis FileInfo entryFile = new FileInfo(TrunkStructure.PHP_SOURCES_DIR + @"\test_programs\include_tests\include_test_01\index.php"); ProgramPointGraph ppGraph = Analyzer.Run(entryFile, MemoryModels.MemoryModels.VirtualReferenceMM); FlowOutputSet outSet = ppGraph.End.OutSet; // For each variable test whether it has given value testVariable(outSet, "include_main_dir", "In ./include_main_dir.php"); testVariable(outSet, "include_main_dir2", "In ./include_main_dir2.php"); testVariable(outSet, "include_included_dir", "In include_dir/include_included_dir.php"); testVariable(outSet, "test_main", "In ./test.php"); testVariable(outSet, "test_included", ""); testVariable(outSet, "test2_included", "In included_dir/test2.php"); testVariable(outSet, "test3_included", "In included_dir/test3.php"); testVariable(outSet, "test4_included", ""); testVariable(outSet, "test5_included", "In included_dir/test5.php"); testVariable(outSet, "test6_included", ""); testVariable(outSet, "test7_included", ""); testVariable(outSet, "in_func1", "In function func1"); testVariable(outSet, "in_func2", ""); testVariable(outSet, "in_func3", "In function func3"); testVariable(outSet, "in_meth1", "In method meth1 of class Cl"); testVariable(outSet, "in_meth2", ""); testVariable(outSet, "index1", "In ./index.php"); testVariable(outSet, "index2", "In ./index.php"); testVariable(outSet, "index3", "In ./index.php"); }
public override void Include(FlowController flow, MemoryEntry includeFile) { //extend current program point as Include var files = new HashSet <string>(); foreach (StringValue possibleFile in includeFile.PossibleValues) { files.Add(possibleFile.Value); } 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); } } foreach (var file in files) { //Create graph for every include - NOTE: we can share pp graphs var cfg = AnalysisTestUtils.CreateCFG(_includes[file], null); var ppGraph = ProgramPointGraph.FromSource(cfg); flow.AddExtension(file, ppGraph, ExtensionType.ParallelInclude); } }
public override void Eval(FlowController flow, MemoryEntry code) { //extend current program point as Eval var codes = new HashSet <string>(); foreach (StringValue possibleFile in code.PossibleValues) { codes.Add(possibleFile.Value); } foreach (var branchKey in flow.ExtensionKeys) { if (!codes.Remove(branchKey as string)) { //this eval is now not resolved as possible eval branch flow.RemoveExtension(branchKey); } } foreach (var sourceCode in codes) { //Create graph for every evaluated code - NOTE: we can share pp graphs var cfg = AnalysisTestUtils.CreateCFG(sourceCode, null); var ppGraph = ProgramPointGraph.FromSource(cfg); flow.AddExtension(sourceCode, ppGraph, ExtensionType.ParallelEval); } }
internal ExtensionPoint(ProgramPointBase caller, ProgramPointGraph graph, ExtensionType type) { Graph = graph; Type = type; Caller = caller; AddFlowChild(Graph.Start); }
/// <summary> /// Create graph walker /// </summary> /// <param name="entryGraph">Program point graph, where walking starts</param> protected GraphWalkerBase(ProgramPointGraph entryGraph) { if (entryGraph == null) { throw new ArgumentNullException("entryGraph"); } _entryGraph = entryGraph; }
/// <inheritdoc /> public void ExtendAsCall(Snapshot extendedSnapshot, Snapshot sourceSnapshot, ProgramPointGraph calleeProgramPoint, MemoryEntry thisObject) { ISnapshotDataProxy data = Factories.SnapshotDataFactory.CopyInstance(sourceSnapshot.Infos); data.Writeable.WriteableChangeTracker.SetCallLevel(extendedSnapshot.CallLevel); data.Writeable.WriteableChangeTracker.SetConnectionType(TrackerConnectionType.CALL_EXTEND); extendedSnapshot.SetInfoMergeResult(data); }
/// <inheritdoc /> public void ExtendAsCall(Snapshot extendedSnapshot, Snapshot sourceSnapshot, ProgramPointGraph calleeProgramPoint, MemoryEntry thisObject) { ISnapshotStructureProxy structure = Factories.SnapshotStructureFactory.CopyInstance(sourceSnapshot.Structure); ISnapshotDataProxy data = Factories.SnapshotDataFactory.CopyInstance(sourceSnapshot.Data); int localLevel = sourceSnapshot.CallLevel + 1; structure.Writeable.AddLocalLevel(); extendedSnapshot.SetMemoryMergeResult(localLevel, structure, data); }
internal void Assert(ProgramPointGraph ppg) { foreach (var assert in _asserts) { assert(ppg); } if (PreviousTest != null) { PreviousTest.Assert(ppg); } }
private static void printIncludes(ConsoleOutput console, ProgramPointGraph ppGraph) { Console.WriteLine(); var includes = new HashSet <String>(); getIncludes(includes, new HashSet <ProgramPointGraph>(), ppGraph); console.CommentLine(string.Format("Included files: {0}\n", includes.Count)); foreach (var incl in includes) { console.CommentLine(incl); } Console.WriteLine(); }
private static void writeExtension(ExtensionPoint point, ref HashSet <ProgramPointGraph> processedPPGraphs, ref HashSet <ProgramPointBase> processedPPoints) { ProgramPointGraph graph = point.Graph; foreach (ProgramPointGraph processedGraph in processedPPGraphs) { if (graph == processedGraph) { return; } } fileOutput.WriteLine("Extension"); writeAll(graph, ref processedPPGraphs, ref processedPPoints); fileOutput.WriteLine("End extension"); }
internal void VisualizeProgramPointGraph(ProgramPointGraph ppg, string graphvizPath) { if (ppgFileName != null) { string visualisationDir = new FileInfo(ppgFileName).Directory.FullName; if (!Directory.Exists(visualisationDir)) { Directory.CreateDirectory(visualisationDir); } DotGraphVisualizer visualizer = new DotGraphVisualizer(graphvizPath); ppg.BuildGraphVisualisation(visualizer, skipProgramPoints); visualizer.CreateVisualization(ppgFileName); } }
/// <inheritdoc /> protected override void extendAsCall(SnapshotBase callerContext, ProgramPointGraph callee, MemoryEntry thisObject, MemoryEntry[] arguments) { switch (CurrentMode) { case SnapshotMode.MemoryLevel: extendAsCallMemory(callerContext, thisObject, arguments); break; case SnapshotMode.InfoLevel: extendAsCallInfo(callerContext, thisObject, arguments); break; default: throw notSupportedMode(); } }
private static void writeAll(ProgramPointGraph graph, ref HashSet <ProgramPointGraph> processedPPGraphs, ref HashSet <ProgramPointBase> processedPPoints) { processedPPGraphs.Add(graph); ProgramPointBase lastPPoint = null; foreach (ProgramPointBase p in graph.Points) { foreach (ProgramPointBase processedPoint in processedPPoints) { if (processedPoint == p) { continue; } } processedPPoints.Add(p); if (p.Partial == null || !p.Partial.Position.IsValid) { continue; } //only first and last program point from one line is shown if (lastPPoint != null && lastPPoint.Partial.Position.FirstLine == p.Partial.Position.FirstLine) { lastPPoint = p; } else { // For efficiency reasons, information about instate of program points are now not printed if (lastPPoint != null) // show the last program point { //writeProgramPointInformation(lastPPoint, true); } //writeProgramPointInformation(p, false); writeProgramPointInformation(p, true); lastPPoint = p; } // for each program poind resolve extensions FlowExtension ext = p.Extension; foreach (ExtensionPoint extPoint in ext.Branches) { writeExtension(extPoint, ref processedPPGraphs, ref processedPPoints); } } writeProgramPointInformation(lastPPoint, true); }
/// <summary> /// Initialize call into callInput. /// /// NOTE: /// arguments has to be initialized /// sharing program point graphs is possible /// </summary> /// <param name="callInput"></param> /// <param name="extensionGraph"></param> /// <param name="arguments"></param> public override void InitializeCall(ProgramPointBase caller, ProgramPointGraph extensionGraph, MemoryEntry[] arguments) { _environmentInitializer(OutSet); var declaration = extensionGraph.SourceObject; var signature = getSignature(declaration); var hasNamedSignature = signature.HasValue; if (hasNamedSignature) { //we have names for passed arguments setNamedArguments(OutSet, arguments, signature.Value); } else { //there are no names - use numbered arguments setOrderedArguments(OutSet, arguments); } }
/// <inheritdoc /> public void ExtendAsCall(Snapshot extendedSnapshot, Snapshot sourceSnapshot, ProgramPointGraph calleeProgramPoint, MemoryEntry thisObject) { int localLevel = calleeProgramPoint.ProgramPointGraphID; ISnapshotStructureProxy structure = Factories.SnapshotStructureFactory.CopyInstance(sourceSnapshot.Structure); if (!structure.Writeable.ContainsStackWithLevel(localLevel)) { structure.Writeable.AddStackLevel(localLevel); } structure.Writeable.SetLocalStackLevelNumber(localLevel); structure.Writeable.WriteableChangeTracker.SetCallLevel(localLevel); structure.Writeable.WriteableChangeTracker.SetConnectionType(TrackerConnectionType.CALL_EXTEND); ISnapshotDataProxy data = Factories.SnapshotDataFactory.CopyInstance(sourceSnapshot.Data); data.Writeable.WriteableChangeTracker.SetCallLevel(localLevel); data.Writeable.WriteableChangeTracker.SetConnectionType(TrackerConnectionType.CALL_EXTEND); extendedSnapshot.SetMemoryMergeResult(localLevel, structure, data); }
/// <summary> /// Clears the inner fields before new computation is performed. /// </summary> private void clearComputation() { AnalysisWarningHandler.ResetWarnings(); IsFirstPhaseStarted = false; IsSecondPhaseStarted = false; IsFirstPhaseFinished = false; IsSecondPhaseFinished = false; analysisWarnings = null; securityWarnings = null; secondPhaseWarnings = null; programPointGraph = null; firstPhaseAnalysis = null; secondPhaseAnalysis = null; // Force garbage collecting GC.Collect(); GC.WaitForPendingFinalizers(); }
private void addCallBranch(FunctionValue function) { var functionName = function.Name.Value; ProgramPointGraph functionGraph; if (_sharedFunctionNames.Contains(functionName)) { //set graph sharing for this function if (!_sharedPpGraphs.ContainsKey(functionName)) { //create single graph instance _sharedPpGraphs[functionName] = ProgramPointGraph.From(function); } //get shared instance of program point graph functionGraph = _sharedPpGraphs[functionName]; } else { functionGraph = ProgramPointGraph.From(function); } Flow.AddExtension(function.DeclaringElement, functionGraph, ExtensionType.ParallelCall); }
public SimpleTaintForwardAnalysis(ProgramPointGraph analyzedGraph) : base(analyzedGraph, AnalysisDirection.Forward, new TaintAnalyzer()) { initialize(EntryInput); }
/// <summary> /// Push call program point graph onto stack /// </summary> /// <param name="callPpGraph">Call program point graph</param> private void pushCall(ProgramPointGraph callPpGraph) { _callStack.Push(callPpGraph); afterPushCall(); }
/// <summary> /// Gets all includes in the program point graph and program point graphs that are its transitive extensions. /// TODO: numProgramPoints, includes, NextPhaseAnalysis.resetPoints - code duplication of /// traversing program point graph - implement this using visitors. /// </summary> public static void getIncludes(HashSet <String> includes, HashSet <ProgramPointGraph> processedGraphs, ProgramPointGraph ppg) { processedGraphs.Add(ppg); foreach (var point in ppg.Points) { includes.UnionWith(point.Extension.KeysIncludes.Select(i => (String)i)); foreach (var branch in point.Extension.Branches) { if (!processedGraphs.Contains(branch.Graph)) { getIncludes(includes, processedGraphs, branch.Graph); } } } }
public override MemoryEntry InitializeCalledObject(ProgramPointBase caller, ProgramPointGraph extensionGraph, MemoryEntry calledObject) { return(calledObject); }
/// <summary> /// Create call graph printer /// </summary> /// <param name="entryGraph">Program point graph, where walking starts</param> internal CallGraphPrinter(ProgramPointGraph entryGraph) : base(entryGraph) { }
/// <summary> /// Get representative name of given ppGraph /// </summary> /// <param name="ppGraph">Program point graph</param> /// <returns>Representative name of given ppGraph</returns> private string getName(ProgramPointGraph ppGraph) { return(NameResolver.Resolve(ppGraph.SourceObject)); }
/// <summary> /// Push call onto stack /// </summary> /// <param name="ppGraph">Pushed call</param> internal void Push(ProgramPointGraph ppGraph) { callStack.Push(ppGraph); }
/// <summary> /// Extend snapshot as a call to function/method callee from given callerContext /// </summary> /// <param name="callerContext">The caller context.</param> /// <param name="callee">Program point graph of the callee (identification of function or method that was called).</param> /// <param name="thisObject">The this object.</param> /// <param name="arguments">The arguments.</param> protected abstract void extendAsCall(SnapshotBase callerContext, ProgramPointGraph callee, MemoryEntry thisObject, MemoryEntry[] arguments);
/// <summary> /// Get output set of the last program point, where are the results of program execution /// </summary> /// <param name="ppg"><see cref="ProgramPointGraph"/> generated during the analysis</param> /// <returns>Output set of analysis</returns> public static FlowOutputSet GetResultOutputSet(ProgramPointGraph ppg) { return(ppg.End.OutSet); }