FreeObfuscator.NET protection

.NET · C# · DLL · EXE

Protect .NET code without changing your JSON and reflection contracts

Use explicit wire names and real compatibility tests to avoid renamed properties, missing types and failed plugin discovery.

Open the obfuscator

The upload, account and checkout interface is in English.

Separate wire names from CLR names

JSON consumers depend on the document contract, not your C# spelling. With System.Text.Json, JsonPropertyName gives a property an explicit JSON name. Test both serialization and deserialization: an expected outbound document is only half the contract. This attribute does not promise that every obfuscator preserves every reflection-accessed member, constructor or converter.

Try a small round-trip test

Place the code below in a .NET 8 console project and run it before protection. It must print json-contract=OK. Repeat from a copied output directory after replacing only the application assembly with its protected version. The test verifies a stable order_id name and a successful read back into the DTO. Add cases for your own naming policy, enum representation, constructor selection and custom converters rather than generalizing this tiny result to every DTO.

Inventory names stored as text

Type.GetType strings, GetMethod lookups, configuration entries and plugin discovery can bypass normal compiled references. Do not assume that an obfuscator rewrites arbitrary strings. Prefer explicit registrations or references where possible, but also test the actual production mechanism. Preserving public API names helps a compiled library consumer; it does not guarantee that internal reflective lookups remain valid.

Check both sides of a deployment

Save representative documents from the old release and read them with the protected one. Let an unchanged consumer call the protected DLL, and verify a real plugin and UI screen. Test missing and null values as well as the happy path. Source-generated serialization can reduce some reflection use, but it is not an automatic repair for arbitrary renaming. If a required name cannot be retained with the available options, reduce protection or use a workflow that supports that contract.

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public sealed class OrderDto
{
    [JsonPropertyName("order_id")]
    public int Id { get; set; }
}
public static class Program
{
    public static void Main()
    {
        string json = JsonSerializer.Serialize(new OrderDto { Id = 42 });
        var copy = JsonSerializer.Deserialize<OrderDto>(json);
        if (json != "{\"order_id\":42}" || copy?.Id != 42)
            throw new InvalidOperationException("JSON contract changed");
        Console.WriteLine("json-contract=OK");
    }
}

Protection guides