From 960b47d58965632610d1893056828b00b583253f Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Thu, 16 Apr 2026 12:51:29 -0600 Subject: [PATCH 1/6] Suppress ERR997 for IL-only managed assemblies Remove EnforcePdbLoadForManagedAssemblies from the ERR997 gate condition so that IL-only managed assemblies (including satellite resource assemblies) no longer trigger ERR997.ExceptionLoadingPdb. These assemblies typically have no PDB, and no current rule requires PDB data for IL-only binaries. Native and mixed-mode binaries still trigger ERR997 as before. The two PDB-using rules applicable to IL-only assemblies (BA2004, BA2027) already handle null PDB gracefully via LogPdbLoadException => false. Mark EnforcePdbLoadForManagedAssemblies as [Obsolete] since it is public virtual but no longer referenced in the gate logic. Fixes #1173 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index 39e09eb95..95629fd94 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -24,6 +24,9 @@ public abstract class WindowsBinaryAndPdbSkimmerBase : WindowsBinarySkimmerBase /// managed and native code require PDBs for the native case but not /// for managed. /// + [Obsolete("This property is no longer used. IL-only managed assemblies no longer trigger " + + "ERR997. Rules that require PDB for managed assemblies should check for null PDB " + + "in their AnalyzePortableExecutableAndPdb implementation.")] public virtual bool EnforcePdbLoadForManagedAssemblies => true; public virtual bool LogPdbLoadException => true; @@ -51,8 +54,7 @@ public sealed override void Analyze(BinaryAnalyzerContext context) { if (target.Pdb == null && (!target.PE.IsManaged || - target.PE.IsMixedMode || - EnforcePdbLoadForManagedAssemblies)) + target.PE.IsMixedMode)) { LogExceptionLoadingPdb(context, target.PdbParseException, target.PdbLoadTrace?.ToString()); return; From 4273557e7f585fb3f529769d2de983e15f56f5d1 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 17 Apr 2026 21:11:38 -0600 Subject: [PATCH 2/6] Replace EnforcePdbLoadForManagedAssemblies with RequiresPdbForManagedAssemblies - New property defaults to false (opt-in instead of opt-out) - Add IsManagedResourceOnly unconditional skip for satellite DLLs - Future rules can override RequiresPdbForManagedAssemblies => true to get the ERR997 safety net for IL-only managed assemblies Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../PERules/WindowsBinaryAndPdbSkimmerBase.cs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index 95629fd94..02264ce8a 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -19,15 +19,14 @@ namespace Microsoft.CodeAnalysis.IL.Rules public abstract class WindowsBinaryAndPdbSkimmerBase : WindowsBinarySkimmerBase { /// - /// Gets a property indicating whether the rule should require that PDBs - /// can be located for managed assemblies. Some checks that inspect both - /// managed and native code require PDBs for the native case but not - /// for managed. + /// Gets a property indicating whether the rule requires that PDBs + /// can be located for IL-only managed assemblies. Defaults to false + /// because most rules only need PDBs for native/mixed-mode code. + /// Rules that need PDB data for IL-only managed assemblies should + /// override this to return true so that ERR997 fires and the rule + /// body is skipped when the PDB cannot be loaded. /// - [Obsolete("This property is no longer used. IL-only managed assemblies no longer trigger " - + "ERR997. Rules that require PDB for managed assemblies should check for null PDB " - + "in their AnalyzePortableExecutableAndPdb implementation.")] - public virtual bool EnforcePdbLoadForManagedAssemblies => true; + public virtual bool RequiresPdbForManagedAssemblies => false; public virtual bool LogPdbLoadException => true; @@ -52,9 +51,9 @@ public sealed override void Analyze(BinaryAnalyzerContext context) if (LogPdbLoadException) { - if (target.Pdb == null && - (!target.PE.IsManaged || - target.PE.IsMixedMode)) + bool targetRequiresPdb = !target.PE.IsManaged || target.PE.IsMixedMode || this.RequiresPdbForManagedAssemblies; + + if (target.Pdb == null && targetRequiresPdb && !target.PE.IsManagedResourceOnly) { LogExceptionLoadingPdb(context, target.PdbParseException, target.PdbLoadTrace?.ToString()); return; From a27d1da848a23030380b44c381bc57ee721c0264 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 17 Apr 2026 21:14:22 -0600 Subject: [PATCH 3/6] Refactor: fold IsManagedResourceOnly into targetRequiresPdb local Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index 02264ce8a..e2a5368d2 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -53,7 +53,9 @@ public sealed override void Analyze(BinaryAnalyzerContext context) { bool targetRequiresPdb = !target.PE.IsManaged || target.PE.IsMixedMode || this.RequiresPdbForManagedAssemblies; - if (target.Pdb == null && targetRequiresPdb && !target.PE.IsManagedResourceOnly) + targetRequiresPdb = targetRequiresPdb && !target.PE.IsManagedResourceOnly; + + if (target.Pdb == null && targetRequiresPdb) { LogExceptionLoadingPdb(context, target.PdbParseException, target.PdbLoadTrace?.ToString()); return; From 5b10cf3ffceaa3eac95067c9f8e285c42266e417 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 20 Apr 2026 09:20:56 -0600 Subject: [PATCH 4/6] Revert API rename: keep EnforcePdbLoadForManagedAssemblies, default to false Restore the original property name to avoid a breaking public API change. The default is changed from true to false so IL-only managed assemblies no longer trigger ERR997. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../PERules/WindowsBinaryAndPdbSkimmerBase.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index e2a5368d2..63138c509 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -19,14 +19,13 @@ namespace Microsoft.CodeAnalysis.IL.Rules public abstract class WindowsBinaryAndPdbSkimmerBase : WindowsBinarySkimmerBase { /// - /// Gets a property indicating whether the rule requires that PDBs - /// can be located for IL-only managed assemblies. Defaults to false - /// because most rules only need PDBs for native/mixed-mode code. - /// Rules that need PDB data for IL-only managed assemblies should - /// override this to return true so that ERR997 fires and the rule - /// body is skipped when the PDB cannot be loaded. + /// Gets a property indicating whether the rule should require that PDBs + /// can be located for managed assemblies. Some checks that inspect both + /// managed and native code require PDBs for the native case but not + /// for managed. Defaults to false so that IL-only managed assemblies + /// (which typically have no PDB) do not trigger ERR997. /// - public virtual bool RequiresPdbForManagedAssemblies => false; + public virtual bool EnforcePdbLoadForManagedAssemblies => false; public virtual bool LogPdbLoadException => true; @@ -51,7 +50,7 @@ public sealed override void Analyze(BinaryAnalyzerContext context) if (LogPdbLoadException) { - bool targetRequiresPdb = !target.PE.IsManaged || target.PE.IsMixedMode || this.RequiresPdbForManagedAssemblies; + bool targetRequiresPdb = !target.PE.IsManaged || target.PE.IsMixedMode || this.EnforcePdbLoadForManagedAssemblies; targetRequiresPdb = targetRequiresPdb && !target.PE.IsManagedResourceOnly; From 63ff910b9cc82edf28a120a8247ce5ad9337d388 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 20 Apr 2026 09:28:38 -0600 Subject: [PATCH 5/6] Simplify: inline condition instead of targetRequiresPdb local Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../PERules/WindowsBinaryAndPdbSkimmerBase.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index 63138c509..a94df9b90 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -50,11 +50,11 @@ public sealed override void Analyze(BinaryAnalyzerContext context) if (LogPdbLoadException) { - bool targetRequiresPdb = !target.PE.IsManaged || target.PE.IsMixedMode || this.EnforcePdbLoadForManagedAssemblies; - - targetRequiresPdb = targetRequiresPdb && !target.PE.IsManagedResourceOnly; - - if (target.Pdb == null && targetRequiresPdb) + if (target.Pdb == null && + !target.PE.IsManagedResourceOnly && + (!target.PE.IsManaged || + target.PE.IsMixedMode || + EnforcePdbLoadForManagedAssemblies)) { LogExceptionLoadingPdb(context, target.PdbParseException, target.PdbLoadTrace?.ToString()); return; From 324b282ff2c218ea3cfb971e038f288fbcb4700b Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 20 Apr 2026 09:31:34 -0600 Subject: [PATCH 6/6] Fix doc comment: remove inaccurate IL-only claim Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs index a94df9b90..c005bcb9a 100644 --- a/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs +++ b/src/BinSkim.Rules/PERules/WindowsBinaryAndPdbSkimmerBase.cs @@ -22,8 +22,7 @@ public abstract class WindowsBinaryAndPdbSkimmerBase : WindowsBinarySkimmerBase /// Gets a property indicating whether the rule should require that PDBs /// can be located for managed assemblies. Some checks that inspect both /// managed and native code require PDBs for the native case but not - /// for managed. Defaults to false so that IL-only managed assemblies - /// (which typically have no PDB) do not trigger ERR997. + /// for managed. /// public virtual bool EnforcePdbLoadForManagedAssemblies => false;