Пример #1
0
        private void Analyze(
            IEnumerable <IBinarySkimmer> skimmers,
            IList <string> roslynAnalyzerFilePaths,
            IEnumerable <string> targets,
            AggregatingLogger logger,
            PropertyBag policy)
        {
            HashSet <string> disabledSkimmers = new HashSet <string>();

            foreach (string target in targets)
            {
                var context = AnalyzeCommand.CreateContext(logger, policy, target);

                if (context.PE.LoadException != null)
                {
                    LogExceptionLoadingTarget(context);
                    continue;
                }
                else if (!context.PE.IsPEFile)
                {
                    LogExceptionInvalidPE(context);
                    continue;
                }

                context = CreateContext(logger, policy, target);

                // Analyzing {0}...
                logger.Log(MessageKind.AnalyzingTarget, context, DriverResources.Analyzing);

                foreach (IBinarySkimmer skimmer in skimmers)
                {
                    if (disabledSkimmers.Contains(skimmer.Id))
                    {
                        continue;
                    }

                    string reasonForNotAnalyzing = null;
                    context.Rule = skimmer;

                    AnalysisApplicability applicability = AnalysisApplicability.Unknown;

                    try
                    {
                        applicability = skimmer.CanAnalyze(context, out reasonForNotAnalyzing);
                    }
                    catch (Exception ex)
                    {
                        LogUnhandledRuleExceptionAssessingTargetApplicability(disabledSkimmers, context, skimmer, ex);
                        continue;
                    }

                    switch (applicability)
                    {
                    case AnalysisApplicability.NotApplicableToSpecifiedTarget:
                    {
                        // Image '{0}' was not evaluated for check '{1}' as the analysis
                        // is not relevant based on observed binary metadata: {2}.
                        context.Logger.Log(MessageKind.NotApplicable,
                                           context,
                                           RuleUtilities.BuildTargetNotAnalyzedMessage(
                                               context.PE.FileName,
                                               context.Rule.Name,
                                               reasonForNotAnalyzing));

                        break;
                    }

                    case AnalysisApplicability.NotApplicableToAnyTargetWithoutPolicy:
                    {
                        // Check '{0}' was disabled for this run as the analysis was not
                        // configured with required policy ({1}). To resolve this,
                        // configure and provide a policy file on the BinSkim command-line
                        // using the --policy argument (recommended), or pass
                        // '--policy default' to invoke built-in settings. Invoke the
                        // BinSkim.exe 'export' command to produce an initial policy file
                        // that can be edited if required and passed back into the tool.
                        context.Logger.Log(MessageKind.ConfigurationError, context,
                                           RuleUtilities.BuildRuleDisabledDueToMissingPolicyMessage(
                                               context.Rule.Name,
                                               reasonForNotAnalyzing));
                        disabledSkimmers.Add(skimmer.Id);
                        break;
                    }

                    case AnalysisApplicability.ApplicableToSpecifiedTarget:
                    {
                        try
                        {
                            skimmer.Analyze(context);
                        }
                        catch (Exception ex)
                        {
                            LogUnhandledRuleExceptionAnalyzingTarget(disabledSkimmers, context, skimmer, ex);
                        }
                        break;
                    }
                    }
                }

                // Once we've processed all portable executable skimmers for a specific
                // target, we'll proactively let go of the data associated with this
                // analysis phase. Follow-on analyses (such as the Roslyn integration)
                // shouldn't attempt to rehydrate this data. The context implementation
                // currently raises an exception if there is an attempt to rehydrate a
                // previously nulled PE instance.
                DisposePortableExecutableContextData(context);

                // IsManagedAssembly is computed on intitializing the binary context
                // object and is still valid after disposing the PE data. The Roslyn
                // analysis is driven solely off the binary file path in the context.
                if (context.IsManagedAssembly && roslynAnalyzerFilePaths?.Count > 0)
                {
                    AnalyzeManagedAssembly(context.Uri.LocalPath, roslynAnalyzerFilePaths, context);
                }
            }
        }