BinSkim Documentation

repository·main·Indexed 21 days ago

https://github.com/microsoft/binskim

BinSkim is a lightweight Portable Executable (PE) scanner used to validate compiler/linker settings and security-relevant binary characteristics. The documentation covers installation via NuGet, CLI usage for analyzing binaries, and detailed remediation guidance for security rules such as Control Flow Guard (BA2008), Address Space Layout Randomization (BA2009), and stack protection (BA3003).

Tokens
14.7K
Snippets
38
Records
85
Agent score
75%

What's inside BinSkim

  1. What is BinSkim and what does it analyze?

    main

    BinSkim is a security checker designed to examine Portable Executable (PE) files and their associated Program Database (PDB) files. It identifies security vulnerabilities in three primary areas:

    • Use of Outdated Compiler Tool Sets: Detects if binaries are compiled against older tool sets that lack modern compiler-level or OS-provided security mitigations.
    • Insecure Compilation Settings: Identifies missing or weak compilation settings that prevent the enablement of OS-provided security mitigations or reduce the effectiveness of compiler warnings.
    • Signing issues: Checks if signed binaries are using cryptographically-strong algorithms.
  2. BinSkim release terminology definitions

    main

    The BinSkim release history uses the following shorthand notation to describe changes:

    • NR: new rule
    • PRF: performance work
    • FCR: fingerprint change or refactor
    • RRR: rule rename or refactor
    • FPC: regex candidate reduction
    • FNC: regex candidate increase
    • FPS: FP (False Positive) reduction in static analysis
    • FNS: false negative reduction in static analysis
    • FPD: FP reduction in dynamic phase
    • FND: False negative reduction in dynamic phase
    • UER: eliminate unhandled exceptions in rules
    • UEE: eliminate unhandled exceptions in engine
    • DEP: upgrade dependency versions
    • DOC: documentation
    • CLN: cleaning solution
    • ADM: administrative
    • NEW: new feature
  3. Configure Symbol Paths with `--sympath`

    main

    BinSkim requires PDBs for a significant subset of its analysis. To ensure successful PDB loading, use the --sympath argument to provide a symbol server path.

    Important Considerations:

    • Syntax: Use the same syntax as Windows debuggers (e.g., SRV*https://msdl.microsoft.com/download/symbols).
    • Performance: Always include a Cache* component in your symbol path (e.g., Cache*d:\symbols;SRV*https://msdl.microsoft.com/download/symbols) to allow BinSkim to download and scan PDBs locally rather than over the network.
    • Environment Variable: BinSkim explicitly clears the %_NT_SYMBOL_PATH% environment variable at runtime to prevent unexpected network activity. You must use the --sympath argument to provide symbol information.
    • Errors: If a PDB cannot be loaded, BinSkim will emit error ERR97 (or ERR997 in some contexts) including the specific HRESULT error code.
    binskim analyze myapp.exe --sympath "Cache*d:\symbols;SRV*https://msdl.microsoft.com/download/symbols"
  4. Use `--rich-return-code` for detailed exit status

    main

    By default, BinSkim returns 0 for success and 1 for failure. If you enable --rich-return-code [true|false], BinSkim will return a bitmask exit code that provides granular information about what occurred during the session. This allows you to distinguish between different types of failures (e.g., PDB loading errors vs. rule exceptions).

    Common Exit Code Flags:

    • 0x1: InvalidCommandLineOption
    • 0x2: ExceptionInSkimmerInitialize
    • 0x4: ExceptionRaisedInSkimmerCanAnalyze
    • 0x8: ExceptionInSkimmerAnalyze
    • 0x10: ExceptionCreatingLogFile
    • 0x20: ExceptionLoadingPdb
    • 0x40: ExceptionInEngine
    • 0x80: ExceptionLoadingTargetFile
    • 0x200: NoRulesLoaded
    • 0x400: NoValidAnalysisTargets
    • 0x800: RuleMissingRequiredConfiguration
    • 0x2000: MissingFile
    • 0x4000: ExceptionAccessingFile
    • 0x8000: ExceptionInstantiatingSkimmers
    • 0x40000000: OneOrMoreWarningsFired (Non-Fatal)
    • 0x80000000: OneOrMoreErrorsFired (Non-Fatal)

    Masks:

    • NonFatalExitCode (0xF8000000): Reserved for codes that occur during normal execution (e.g., finding issues).
    • FatalExitCode (0x0000FFFF): Reserved for unexpected errors or incomplete analysis (e.g., missing PDBs).
    binskim analyze myapp.exe --rich-return-code true
  5. Configure SARIF output format

    main

    BinSkim supports exporting results in both SARIF v1 and v2 formats.

    • v1.6.0 and later: Provides support for both formats.
    • v1.7.0 and later: The default output format is SARIF v2.
    • v1.6.0: Introduced SARIF v2 (version 2.1.16) which enables results caching when using the --hashes command-line argument, improving performance for recursive directory analysis.
  6. Enable CET Shadow Stack (BA2025)

    main

    Rule BA2025.EnableShadowStack checks for Control-flow Enforcement Technology (CET) Shadow Stack, which defends against ROP-based malware attacks.

    • To resolve: Pass /CETCOMPAT on the linker command lines.
    • For VC projects: Set the ItemDefinitionGroup - Link - CETCompat property to true.

    Warning: Older versions of .NET (6 or earlier) are not compatible with CET/shadow stack. Loading older managed assemblies in a native process using CET may cause unhandled exceptions and process crashes.

    # Linker Command Line
    link.exe /CETCOMPAT ...
    
    # VC Project Property
    <CETCompat>true</CETCompat>
  7. Extract the BinSkim executable from a NuGet package

    main

    If you want to run the tool without a full installation, follow these steps to extract the standalone executable:

    1. Download the .nupkg file from NuGet.
    2. Rename the file extension from .nupkg to .zip (e.g., rename microsoft.codeanalysis.binskim.x.y.z.nupkg microsoft.codeanalysis.binskim.x.y.z.zip).
    3. Unzip the file.
    4. Locate the OS-specific executable in the _tools\netcoreapp3.1_ folder (e.g., linux-x64, win-x64, or osx-x64).
  8. Configure .NET Managed binaries

    main

    To generate specific .NET C# binaries, use Visual Studio and modify project settings:

    Standard Variants

    • ReadyToRun: Change publish settings to enable ReadyToRun compilation.
    • SelfContained/SingleFile: Enable both Self Contained and Single File compilation in publish settings.
    • AOT: Add <PublishAot>true</PublishAot> to the project settings.
    • Native: Enable "compile with .Net native toolchain" in the Build tab.

    HighEntropyVA (via .csproj)

    To test HighEntropyVA, add the following to your .csproj file: <HighEntropyVA>True</HighEntropyVA> or <HighEntropyVA>False</HighEntropyVA>.

    <!-- Example for HighEntropyVA -->
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <HighEntropyVA>True</HighEntropyVA>
      </PropertyGroup>
    </Project>
  9. Enable Integrity Checks (BA2029)

    main

    Rule BA2029.EnableIntegrityCheck ensures binaries opt into Windows digital signature validation by setting the /INTEGRITYCHECK linker flag. This is required for code interfacing with Early Launch Antimalware (ELAM) drivers or loading into protected process lite space.

    • To resolve: Pass /INTEGRITYCHECK on the link.exe command line.
    • Requirement: Binaries opting into this must be signed using the Microsoft Azure Code Signing program.
    # Linker Command Line
    link.exe /INTEGRITYCHECK ...
  10. Create a shell rule for implementation

    main

    Follow these steps to scaffold a new rule:

    1. Define Rule ID: Add a new constant to the RuleIds.cs class. The property name should be the friendly name (e.g., EnableControlEnforcementTechnologyShadowStack) and the value should be the identifier (e.g., BA2025).
    2. Add Resource Strings: In RuleResources.resx, add user-facing strings for pass and fail conditions using the pattern {RULEID}_{LEVEL} (e.g., BA2025_Pass, BA2025_Error).
    3. Add Description: Add a description string named {RULEID}_{FRIENDLYNAME}_Description (e.g., BA2025_EnableControlEnforcementTechnologyShadowStack_Description).
    4. Create Rule File: Copy the shell rule starter code from BAXXXX.RuleFriendlyName.cs to either the ELFRules or PERules directory (depending on the target platform). Rename the file to {RULEID}.{RuleFriendlyName} (e.g., BA2025.EnableControlEnforcementTechnologyShadowStack).
    5. Replace Placeholders: In the new file, replace all occurrences of BAXXXX with your rule ID and RULEFRIENDLYNAME with your rule's friendly name.
  11. Get Help in BinSkim

    main

    BinSkim provides two levels of help via the command line:

    1. General Help: Displays all built-in commands (e.g., help, analyze, capture).

      • Command: binskim.exe --help
    2. Detailed Help: Provides specific documentation for a particular command.

      • Command: binskim.exe help [command]
      • Examples: binskim.exe help analyze, binskim.exe help exportRules, binskim.exe help exportConfig, binskim.exe help dump, binskim.exe help version.
    binskim.exe --help
    binskim.exe help analyze