Ejemplo n.º 1
0
        /// This does the interprocedural analysis.
        /// It (currently) does NOT support recursive method invocations
        /// </summary>
        /// <param name="instruction"></param>
        /// <param name="resolvedCallee"></param>
        /// <param name="calleeCFG"></param>
        private InterProceduralReturnInfo InterproceduralAnalysis(InterProceduralCallInfo callInfo, ControlFlowGraph calleeCFG)
        {
            if (stackDepth > InterproceduralManager.MaxStackDepth)
            {
                callInfo.CallerState.Dependencies.IsTop = true;
                AnalysisStats.AddAnalysisReason(new AnalysisReason(callInfo.Caller, callInfo.Instruction, String.Format(CultureInfo.InvariantCulture, "Reach maximum call depth {0}", callInfo.Callee.Name)));
                return(new InterProceduralReturnInfo(callInfo.CallerState));
            }

            stackDepth++;
            // I currently do not support recursive calls
            // Will add support for this in the near future
            if (callStack.Contains(callInfo.Callee))
            {
                callInfo.CallerState.Dependencies.IsTop = true;
                AnalysisStats.AddAnalysisReason(new AnalysisReason(callInfo.Caller, callInfo.Instruction, String.Format(CultureInfo.InvariantCulture, "Recursive call to {0}", callInfo.Callee.Name)));
                return(new InterProceduralReturnInfo(callInfo.CallerState));
            }

            this.callStack.Push(callInfo.Callee);
            //Console.WriteLine("Analyzing Method {0} Stack: {1}", new string(' ',stackDepth*2) + callInfo.Callee.ToString(), stackDepth);
            // 1) Bind PTG and create a Poinst-to Analysis for the  callee. In pta.Result[node.Exit] is the PTG at exit of the callee
            var calleePTG = PTABindCallerCallee(callInfo.CallerPTG, callInfo.CallArguments, callInfo.Callee);
            SimplePointsToAnalysis calleePTA = new SimplePointsToAnalysis(calleeCFG, callInfo.Callee, calleePTG);

            IDictionary <IVariable, IExpression> equalities = new Dictionary <IVariable, IExpression>();

            calleeCFG.PropagateExpressions(equalities);

            // 2) Bind Parameters of the dependency analysis
            VariableRangeDomain boundVariablesRanges;
            var calleeDomain   = BindCallerCallee(callInfo, out boundVariablesRanges);
            var rangesAnalysis = new RangeAnalysis(calleeCFG, callInfo.Callee, boundVariablesRanges);

            // 4) Now we perform the analyses
            rangesAnalysis.Analyze();

            calleeDomain.PTG = calleePTG;
            var dependencyAnalysis = new IteratorDependencyAnalysis(processToAnalyze, callInfo.Callee, calleeCFG, calleePTA, callInfo.ProtectedNodes, equalities, this, rangesAnalysis, calleeDomain, callInfo.ScopeData);

            // If we already did the dataflow analysis for this method we recover the dataflow state
            // This should be adapted (or removed) if we want the analysis to be context sensitive

            //if (dataflowCache.ContainsKey(callInfo.Callee))
            //{
            //    var previosResult = dataflowCache[callInfo.Callee];
            //    //DataFlowAnalysisResult<DependencyPTGDomain>[] resultsCopy = new DataFlowAnalysisResult<DependencyPTGDomain>[previosResult.Length];
            //    //for(int i=0; i< previosResult.Length; i++)
            //    //{
            //    //    resultsCopy[i] = new DataFlowAnalysisResult<DependencyPTGDomain>();
            //    //    resultsCopy[i].Input = previosResult[i].Input!=null? previosResult[i].Input.Clone(): null;
            //    //    resultsCopy[i].Output = previosResult[i].Output!=null? previosResult[i].Output.Clone(): null;
            //    //}
            //    //dependencyAnalysis.SetPreviousResult(resultsCopy);

            //    dependencyAnalysis.SetPreviousResult(previosResult);
            //}

            dependencyAnalysis.Analyze();


            this.dataflowCache[callInfo.Callee] = dependencyAnalysis.Result;

            stackDepth--;
            this.callStack.Pop();

            // 3) Bind callee with caller
            // Should I need the PTG of caller and callee?
            //var exitCalleePTG = calleePTA.Result[calleeCFG.Exit.Id].Output;
            var exitCalleePTG = dependencyAnalysis.Result[calleeCFG.Exit.Id].Output.PTG;


            var exitResult = BindCalleeCaller(callInfo, calleeCFG, dependencyAnalysis, rangesAnalysis);

            // Recover the frame of the original Ptg and bind ptg results
            //PointsToGraph bindPtg = PTABindCaleeCalleer(callInfo.CallLHS, calleeCFG, calleePTA);
            var bindPtg = PTABindCaleeCalleer(callInfo.CallLHS, calleeCFG, exitCalleePTG, calleePTA.ReturnVariable);

            exitResult.PTG = bindPtg;

            return(new InterProceduralReturnInfo(exitResult)
            {
                InputColumns = dependencyAnalysis.InputColumns,
                OutputColumns = dependencyAnalysis.OutputColumns
            });
            //return new InterProceduralReturnInfo(exitResult, bindPtg);
        }
Ejemplo n.º 2
0
        public static SarifLog AnalyzeDll(string inputPath, ScopeMethodKind kind,

                                          bool useScopeFactory = true, bool interProc = false, StreamWriter outputStream = null)
        {
            // Determine whether to use Interproc analysis
            AnalysisOptions.DoInterProcAnalysis = interProc;

            AnalysisStats.TotalNumberFolders++;

            var host = new MyHost();

            PlatformTypes.Resolve(host);

            var loader = new MyLoader(host);

            host.Loader = loader;

            var scopeGenAssembly = loader.LoadMainAssembly(inputPath);

            AnalysisStats.TotalDllsFound++;

            loader.LoadCoreAssembly();

            var program = new ScopeProgramAnalysis(host, loader);

            // program.interprocAnalysisManager = new InterproceduralManager(host);
            program.ScopeGenAssembly = scopeGenAssembly;
            //program.ReferenceFiles = referenceFiles;

            program.ClassFilters    = new HashSet <string>();
            program.ClousureFilters = new HashSet <string>();

            program.EntryMethods = new HashSet <string>();

            if (kind == ScopeMethodKind.Reducer || kind == ScopeMethodKind.All)
            {
                program.ClassFilters.Add("Reducer");
                program.ClousureFilters.Add("<Reduce>d__");
                program.EntryMethods.Add("Reduce");
            }
            if (kind == ScopeMethodKind.Producer || kind == ScopeMethodKind.All)
            {
                program.ClassFilters.Add("Processor");
                program.ClousureFilters.Add("<Process>d__");
                program.EntryMethods.Add("Process");
                //program.ClassFilter = "Producer";
                //program.ClousureFilter = "<Produce>d__";
                //program.EntryMethod = "Produce";
            }

            program.MethodUnderAnalysisName = "MoveNext";

            IEnumerable <Tuple <MethodDefinition, MethodDefinition, MethodDefinition> > scopeMethodPairs;

            if (useScopeFactory)
            {
                scopeMethodPairs = program.ObtainScopeMethodsToAnalyze();
                if (!scopeMethodPairs.Any())
                {
                    if (outputStream != null)
                    {
                        outputStream.WriteLine("Failed to obtain methods from the ScopeFactory. ");
                    }
                    System.Console.WriteLine("Failed to obtain methods from the ScopeFactory.");

                    //System.Console.WriteLine("Now trying to find methods in the the assembly");
                    //scopeMethodPairs = program.ObtainScopeMethodsToAnalyzeFromAssemblies();
                }
            }
            else
            {
                scopeMethodPairs = program.ObtainScopeMethodsToAnalyzeFromAssemblies();
            }


            if (scopeMethodPairs.Any())
            {
                var log = CreateSarifOutput();

                IReadOnlyDictionary <string, Tuple <Schema, Schema> > allSchemas;
                if (useScopeFactory)
                {
                    allSchemas = program.ReadSchemasFromXML(inputPath);
                }
                else
                {
                    allSchemas = program.ReadSchemasFromXML2(inputPath);
                }

                foreach (var methodPair in scopeMethodPairs)
                {
                    AnalysisStats.TotalMethods++;

                    var entryMethodDef = methodPair.Item1;
                    var moveNextMethod = methodPair.Item2;
                    var getEnumMethod  = methodPair.Item3;
                    System.Console.WriteLine("Method {0} on class {1}", moveNextMethod.Name, moveNextMethod.ContainingType.FullPathName());

                    Schema inputSchema  = null;
                    Schema outputSchema = null;
                    Tuple <Schema, Schema> schemas;
                    if (allSchemas.TryGetValue(moveNextMethod.ContainingType.ContainingType.Name, out schemas))
                    {
                        inputSchema  = schemas.Item1;
                        outputSchema = schemas.Item2;
                    }

                    try
                    {
                        InputSchema  = inputSchema;
                        OutputSchema = outputSchema;
                        var dependencyAnalysis = new SongTaoDependencyAnalysis(host, program.interprocAnalysisManager, moveNextMethod, entryMethodDef, getEnumMethod);
                        var depAnalysisResult  = dependencyAnalysis.AnalyzeMoveNextMethod();

                        WriteResultToSarifLog(inputPath, outputStream, log, moveNextMethod, depAnalysisResult, dependencyAnalysis, program.factoryReducerMap);

                        InputSchema  = null;
                        OutputSchema = null;
                    }
                    catch (Exception e)
                    {
                        System.Console.WriteLine("Could not analyze {0}", inputPath);
                        System.Console.WriteLine("Exception {0}\n{1}", e.Message, e.StackTrace);
                        AnalysisStats.TotalofDepAnalysisErrors++;
                        AnalysisStats.AddAnalysisReason(new AnalysisReason(moveNextMethod, moveNextMethod.Body.Instructions[0],
                                                                           String.Format(CultureInfo.InvariantCulture, "Throw exception {0}\n{1}", e.Message, e.StackTrace.ToString())));
                    }
                }
                return(log);
            }
            else
            {
                System.Console.WriteLine("No method {0} of type {1} in {2}", program.MethodUnderAnalysisName, program.ClassFilters, inputPath);
                return(null);
            }
        }