Example #1
0
        public void Audit(ProjectReport projectReport, IProgressBar progressBar = null)
        {
            var userAssemblies = GetPlayerAssemblies();

            if (userAssemblies.Count > 0)
            {
                m_AssemblyResolver = new DefaultAssemblyResolver();
#if UNITY_2019_1_OR_NEWER
                List <string> assemblyPaths = new List <string>();
                assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources
                                                                                       .UserAssembly));
                assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources
                                                                                       .UnityEngine));
                foreach (var dir in assemblyPaths.Select(path => Path.GetDirectoryName(path)).Distinct())
                {
                    m_AssemblyResolver.AddSearchDirectory(dir);
                }
#else
                m_AssemblyResolver.AddSearchDirectory(Path.Combine(EditorApplication.applicationContentsPath, "Managed", "UnityEngine"));
#endif
                m_AssemblyResolver.AddSearchDirectory(Path.Combine(EditorApplication.applicationContentsPath, "UnityExtensions", "Unity", "GUISystem"));

                foreach (var dir in userAssemblies.Select(path => Path.GetDirectoryName(path)).Distinct())
                {
                    m_AssemblyResolver.AddSearchDirectory(dir);
                }

                var callCrawler = new CallCrawler();

                if (progressBar != null)
                {
                    progressBar.Initialize("Analyzing Scripts", "Analyzing project scripts", m_PlayerAssemblies.Length);
                }

                // Analyse all Player assemblies, including Package assemblies.
                foreach (var assemblyPath in userAssemblies)
                {
                    if (progressBar != null)
                    {
                        progressBar.AdvanceProgressBar(string.Format("Analyzing {0} scripts", Path.GetFileName(assemblyPath)));
                    }

                    if (!File.Exists(assemblyPath))
                    {
                        Debug.LogError(assemblyPath + " not found.");
                        continue;
                    }

                    AnalyzeAssembly(assemblyPath, projectReport, callCrawler);
                }

                if (progressBar != null)
                {
                    progressBar.ClearProgressBar();
                }

                callCrawler.BuildCallHierarchies(projectReport, progressBar);
            }
        }
Example #2
0
        public void Audit(ProjectReport projectReport, IProgressBar progressBar = null)
        {
            if (!AssemblyHelper.CompileAssemblies())
            {
                return;
            }

            var callCrawler = new CallCrawler();

            using (var assemblyResolver = new DefaultAssemblyResolver())
            {
                var compiledAssemblyPaths = AssemblyHelper.GetCompiledAssemblyPaths();

                foreach (var dir in AssemblyHelper.GetPrecompiledAssemblyDirectories())
                {
                    assemblyResolver.AddSearchDirectory(dir);
                }

                foreach (var dir in AssemblyHelper.GetPrecompiledEngineAssemblyDirectories())
                {
                    assemblyResolver.AddSearchDirectory(dir);
                }

                foreach (var dir in AssemblyHelper.GetCompiledAssemblyDirectories())
                {
                    assemblyResolver.AddSearchDirectory(dir);
                }

                if (progressBar != null)
                {
                    progressBar.Initialize("Analyzing Scripts", "Analyzing project scripts", m_PlayerAssemblies.Length);
                }

                // Analyse all Player assemblies, including Package assemblies.
                foreach (var assemblyPath in compiledAssemblyPaths)
                {
                    if (progressBar != null)
                    {
                        progressBar.AdvanceProgressBar(string.Format("Analyzing {0} scripts", Path.GetFileName(assemblyPath)));
                    }

                    if (!File.Exists(assemblyPath))
                    {
                        Debug.LogError(assemblyPath + " not found.");
                        continue;
                    }

                    AnalyzeAssembly(assemblyPath, assemblyResolver, projectReport, callCrawler);
                }
            }

            if (progressBar != null)
            {
                progressBar.ClearProgressBar();
            }

            callCrawler.BuildCallHierarchies(projectReport, progressBar);
        }
Example #3
0
        private void AnalyzeMethodBody(ProjectReport projectReport, AssemblyDefinition a, MethodDefinition caller, CallCrawler callCrawler)
        {
            if (!caller.DebugInformation.HasSequencePoints)
            {
                return;
            }

            var callerNode = new CallTreeNode(caller);

            foreach (var inst in caller.Body.Instructions.Where(i => m_OpCodes.Contains(i.OpCode)))
            {
                //var msg = string.Empty;
                SequencePoint s = null;
                for (var i = inst; i != null; i = i.Previous)
                {
                    s = caller.DebugInformation.GetSequencePoint(i);
                    if (s != null)
                    {
                        // msg = i == inst ? " exactly" : "nearby";
                        break;
                    }
                }

                var location = callerNode.location = new Location
                {
                    path = s.Document.Url.Replace("\\", "/"), line = s.StartLine
                };

                if (inst.OpCode == OpCodes.Call || inst.OpCode == OpCodes.Callvirt)
                {
                    callCrawler.Add(caller, (MethodReference)inst.Operand, location);
                }

                foreach (var analyzer in m_InstructionAnalyzers)
                {
                    if (analyzer.GetOpCodes().Contains(inst.OpCode))
                    {
                        var projectIssue = analyzer.Analyze(caller, inst);
                        if (projectIssue != null)
                        {
                            projectIssue.callTree.AddChild(callerNode);
                            projectIssue.location = location;
                            projectIssue.assembly = a.Name.Name;

                            projectReport.AddIssue(projectIssue);
                        }
                    }
                }
            }
        }
Example #4
0
        private void AnalyzeAssembly(string assemblyPath, IAssemblyResolver assemblyResolver, ProjectReport projectReport, CallCrawler callCrawler)
        {
            using (var a = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters()
            {
                ReadSymbols = true, AssemblyResolver = assemblyResolver
            }))
            {
                foreach (var methodDefinition in MonoCecilHelper.AggregateAllTypeDefinitions(a.MainModule.Types).SelectMany(t => t.Methods))
                {
                    if (!methodDefinition.HasBody)
                    {
                        continue;
                    }

                    AnalyzeMethodBody(projectReport, a, methodDefinition, callCrawler);
                }
            }
        }