1. Record a baseline
Create a throwaway console project with the code below, build it in Release and run it. Its expected output is proof=42. Copy the output directory before replacing anything. Keep the source and original assembly: without a baseline you cannot distinguish a protection change from a build or dependency change. This small check is a reproducible starting point, not evidence that your whole production application is compatible.
2. Protect and inspect
Upload the compiled managed DLL, then put the returned file into the copied output directory under the original DLL name. Run the copied application with dotnet. The output should still be proof=42. Open the original and protected assemblies in ILSpy and compare the internal Proof class and Compute method names. Libraries deliberately retain public API contracts, so readable public names alone do not show failure. A different SHA256 or file size only proves that bytes changed.
3. Verify each enabled layer separately
If string encryption was selected, inspect and exercise representative string literals; do not assume every visible string must disappear, because constants and metadata are different from executable string loads. If control-flow protection was selected, inspect eligible methods and execute each branch. Save the options, input/output hashes, comparison notes and test result. Then repeat with your real application, including error paths, async methods and dependencies. No inspection can demonstrate that managed code has become impossible to reverse engineer.
internal static class Proof
{
internal static int Compute(int x) => x * 6;
}
public static class Program
{
public static void Main() => System.Console.WriteLine($"proof={Proof.Compute(7)}");
}dotnet new console -n ProtectionProof -f net8.0 → dotnet build ProtectionProof -c Release → dotnet ProtectionProof/bin/Release/net8.0/ProtectionProof.dll
proof=42 → proof=42
2026-11-06 · FreeObfuscator · .NET 8
Download the source and recorded test results