public override void Analyze(BinaryAnalyzerContext context) { PEHeader peHeader = context.PE.PEHeaders.PEHeader; if (context.Pdb == null) { Errors.LogExceptionLoadingPdb(context, context.PdbParseException); return; } Pdb di = context.Pdb; bool noCode = !di.CreateGlobalFunctionIterator().Any() && !di.ContainsExecutableSectionContribs(); if (noCode) { // '{0}' is a C or C++ binary that is not required to initialize the stack protection, as it does not contain executable code. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA2013_Pass_NoCode), context.TargetUri.GetFileName())); return; } bool bHasGSCheck = di.CreateGlobalFunctionIterator( StackProtectionUtilities.GSCheckFunctionName, NameSearchOptions.nsfCaseSensitive).Any(); bool bHasGSInit = StackProtectionUtilities.GSInitializationFunctionNames.Any( functionName => di.CreateGlobalFunctionIterator(functionName, NameSearchOptions.nsfCaseSensitive).Any()); if (!bHasGSCheck && !bHasGSInit) { // '{0}' is a C or C++ binary that does enable the stack protection buffer // security feature. It is therefore not required to initialize the stack protector. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.NotApplicable, context, null, nameof(RuleResources.BA2013_NotApplicable_FeatureNotEnabled), context.TargetUri.GetFileName())); return; } if (!bHasGSInit) { // '{0}' is a C or C++ binary that does not initialize the stack protector. // The stack protector(/ GS) is a security feature of the compiler which // makes it more difficult to exploit stack buffer overflow memory // corruption vulnerabilities. The stack protector requires access to // entropy in order to be effective, which means a binary must initialize // a random number generator at startup, by calling __security_init_cookie() // as close to the binary's entry point as possible. Failing to do so will // result in spurious buffer overflow detections on the part of the stack // protector. To resolve this issue, use the default entry point provided // by the C runtime, which will make this call for you, or call // __security_init_cookie() manually in your custom entry point. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Error, context, null, nameof(RuleResources.BA2013_Error), context.TargetUri.GetFileName())); return; } // '{0}' is a C or C++ binary built with the buffer security feature // that properly initializes the stack protecter. This has the //effect of increasing the effectiveness of the feature and reducing // spurious detections. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA2013_Pass), context.TargetUri.GetFileName())); }