Skip to Content
New release 12 available 🎉
ObfuscatorNuGet PackageDefense in Depth

Defense in Depth: Every Layer in One Build

Strong protection does not come from a single trick — it comes from layers. This example turns on every protection of the Babel Obfuscator NuGet package on one small assembly, so you can see the complete Ultimate configuration in a single project file and adapt it to your own application.

To use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center editions). The source code is available on GitHub:

git clone https://github.com/babelfornet/defense-in-depth-nuget-example.git

The application is a small feature gate (src/LicenseGate/FeatureGate.cs) that carries exactly the kinds of things every layer protects — strings, numeric weights, an array, and branching logic:

internal static class FeatureGate { private static readonly int[] Weights = { 3, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; private static readonly string Pepper = "d3f3ns3-1n-d3pth-pepper"; public static GateReport Evaluate(string edition, int tokens, double budget) { bool allowed = edition is "PRO" or "ENTERPRISE" && tokens > 0 && budget >= 100.0; double score = 0.0; for (int i = 0; i < Weights.Length; i++) score += Weights[i] * (tokens + 1) * 0.5; return new GateReport(edition, allowed, Math.Round(score / budget, 4), Digest(edition, tokens)); } // Digest … }

The LicenseGate console project stacks the layers in Release:

<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <!-- Rename & restructure --> <FlattenNamespaces>true</FlattenNamespaces> <OverloadedRenaming>true</OverloadedRenaming> <VirtualFunctions>true</VirtualFunctions> <!-- Hide data --> <StringEncryption>stream</StringEncryption> <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption> <ResourceEncryption>true</ResourceEncryption> <!-- Obscure logic --> <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation> <ControlFlowIterations>3</ControlFlowIterations> <DynamicProxy>external=true;true</DynamicProxy> <!-- Detect & deter runtime attacks --> <TamperingDetection>true</TamperingDetection> <DebuggingProtection>true</DebuggingProtection> <SuppressIldasm>true</SuppressIldasm> <!-- Strip metadata --> <CleanAttributes>true</CleanAttributes> <SealClasses>true</SealClasses> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

Each property adds a layer: renaming and namespace flattening hide intent; String, Value and Resource encryption hide data; control flow and dynamic proxy hide logic; tampering detection and anti-debugging deter runtime attacks; and metadata hygiene removes what the running application does not need. Because the package is a build-only dependency (PrivateAssets=all), none of this leaks into the app’s own dependency graph, and the SDK’s later steps work on the already-protected assembly.

Building the sample in Release applies all of the above with identical program output; open the result in a decompiler and compare it with the Debug build to see the difference. This mirrors the guidance in Enhancing Code Security — start from this configuration and drop the layers you do not need.

Last updated on