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())); }
public override void Analyze(BinaryAnalyzerContext context) { PEHeader peHeader = context.PE.PEHeaders.PEHeader; Pdb pdb = context.Pdb; if (pdb == null) { Errors.LogExceptionLoadingPdb(context, context.PdbParseException); return; } List <string> names = new List <string>(); foreach (DisposableEnumerableView <Symbol> functionView in pdb.CreateGlobalFunctionIterator()) { Symbol function = functionView.Value; if (function.IsManaged) { continue; } if (!function.IsSafeBuffers) { continue; } string functionName = function.GetUndecoratedName(); if (functionName == "__security_init_cookie" || context.Policy.GetProperty(ApprovedFunctionsThatDisableStackProtection).Contains(functionName)) { continue; } names.Add(functionName); } if (names.Count != 0) { string functionNames = string.Join(";", names); // '{0}' is a C or C++ binary built with function(s) ({1}) that disable 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. Disabling the stack protector, even on a // function -by-function basis, is disallowed by SDL policy. To resolve this // issue, remove occurrences of __declspec(safebuffers) from your code. If the // additional code inserted by the stack protector has been shown in profiling // to cause a significant performance problem for your application, attempt to // move stack buffer modifications out of the hot path of execution to allow the // compiler to avoid inserting stack protector checks in these locations rather // than disabling the stack protector altogether. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Error, context, null, nameof(RuleResources.BA2014_Error), context.TargetUri.GetFileName(), functionNames)); return; } // '{0}' is a C or C++ binary built with the stack protector buffer // security feature enabled which does not disable protection for // any individual functions (via __declspec(safebuffers), making it // more difficult for an attacker to exploit stack buffer overflow // memory corruption vulnerabilities. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA2014_Pass), context.TargetUri.GetFileName())); }