# Declarative Protection

The .NET Reactor user interface offers various ways to refine the level of protection applied to your application. The Advanced Rules editor allows you to select different inclusion and exclusion options, and you can also control the protection level using the standard .NET Obfuscation Attribute.

If you want .NET Reactor to respect this attribute, you must enable the Declarative Protection option in the settings:

Once you have enabled this option you can use the attribute to select specific protection features, choose whether to include or exclude those features, and specify the classes and members that should be affected.

# Selecting Protection Features

Protection features can be selected by assigning values to the attribute Feature property.

[System.Reflection.Obfuscation(Feature = "renaming,controlflow")

The following values are available:

  • "renaming or "obfuscation"
  • "stringencryption"
  • "controlflow"
  • "necrobit"
  • "antitamp"
  • "hidemethods"

Important: The values must be entered with the quotation marks and are case insensitive.

# Defining the behavior

Use the Exclude property to define whether the features should be included or excluded.

[System.Reflection.Obfuscation(Exclude = true, Feature = "renaming")
[System.Reflection.Obfuscation(Exclude = false, Feature = "controlflow")
  • To include features, set the Exclude property to false.

  • To exclude features, set the Exclude property to true. The default value is true, so explicitly setting the Exclude property is optional if you wish to exclude a feature.

# Placing the attribute and the 'ApplyToMembers' property

You can place the attribute on top of classes and members (methods, properties, and fields).

[System.Reflection.Obfuscation(Exclude = true, Feature = "controlflow")
internal void MyMethod()
[System.Reflection.Obfuscation(Exclude = false, Feature = "renaming", ApplyToMembers = false)
public class MyClass

The ApplyToMembers property has a default value of true. As it only affects whether class members (methods, properties, fields, and nested classes) are affected, it is only appropriate for attributes decorating a class.

If you do not want the class members to be affected, set the ApplyToMembers property to false.

# Examples

Example 1:

[System.Reflection.Obfuscation(Feature = "renaming")
class MyClass
{
   class NestedClass
   {}
    
   void MyMethod(){}    
}

MyClass, NestedClass, and MyMethod will not be renamed.

Example 2:

[System.Reflection.Obfuscation(Exclude = true, Feature = "renaming", ApplyToMembers = true)
class MyClass
{
   class NestedClass
   {}
    
   void MyMethod(){}    
}

This is equivalent to Example 1.

Example 3:

[System.Reflection.Obfuscation(Feature = "renaming", ApplyToMembers = false)]
class MyClass
{
   class NestedClass
   {}
    
   void MyMethod(){}    
}

Only MyClass is excluded from renaming, but not NestedClass and MyMethod.

Example 4:

[System.Reflection.Obfuscation(Exclude = false, Feature = "renaming,stringencryption") // include
[System.Reflection.Obfuscation(Exclude = true, Feature = "necrobit")  // exclude
class MyClass
{   
   int MyField;
    
   [System.Reflection.Obfuscation(Exclude = true, Feature = "renaming") // exclude
   void MyMethod(){}   
   
   [System.Reflection.Obfuscation(Exclude = false, Feature = "necrobit") // include
   void MyMethod2(){}  
}
  • Only MyField and MyMethod2 will be renamed.

  • String Encryption will be applied to MyMethod and MyMethod2

  • NecroBit will be only applied to MyMethod2.

# Special case: [System.Reflection.Obfuscation()]

There is a special case that works independently from "Declarative Protection". If you don't set a value for the Feature property, the attribute excludes renaming.

Example 5:

[System.Reflection.Obfuscation(ApplyToMembers = false)]
class MyClass
{
   class NestedClass
   {}
    
   void MyMethod(){}    
}

Only MyClass is excluded from renaming, but not NestedClass and MyMethod.

Example 6:

[System.Reflection.Obfuscation()]
enum MyEnum
{
    A,
    B,
    C
}

MyEnum and all fields are excluded from renaming.

Example 7:

enum MyEnum
{
    A,
    [System.Reflection.Obfuscation()]
    B,
    C
}

Only the B field is excluded from renaming.

# Assembly Attributes

In addition to the standard Obfuscation attribute usage described above, you can define more complex, rule-based configurations via assembly attributes. These rules allow for finer-grained control over protection features and can be combined with filters specifying which classes, interfaces, enums, methods, properties, fields, or events they affect.

These rules are defined in the Feature property of the Obfuscation attribute using a special syntax starting with rule: or rule regex:.

# Basic Syntax for Rules

[assembly: Obfuscation(Feature = @"rule: ( ... ) where ( ... ) ( ... ) ( ... )")]

The structure is as follows:

# rule: or rule regex:

  • rule: indicates a standard rule set.

  • rule regex: indicates that all defined names (namespaces, types, methods, fields, properties, events) are interpreted as regular expressions.

  • ( ... ) – The first parentheses block defines which features to enable or disable.

    • Prefix + means enabling/applying a feature.
    • Prefix - means excluding/disabling a feature.

# Available Features:

  • -all: Disables all features for the listed filter elements.
  • -virtualization / +virtualization: Disables/Enables Code Virtualization for the listed filter elements.
  • -controlflow / +controlflow: Disables/Enables Control Flow Obfuscation.
  • -hidemethods / +hidemethods: Disables/Enables Hide Method Calls.
  • -necrobit / +necrobit: Disables/Enables NecroBit.
  • -renaming / +renaming: Disables/Enables Renaming.
  • -resourceencryption / +resourceencryption: Disables/Enables Resource Encryption.
  • -stringencryption / +stringencryption: Disables/Enables String Encryption.

Multiple features can be combined and must be comma-separated. For example:

rule: (-renaming, -necrobit, +stringencryption)

# where ( ... )

This section is optional and defines a filter on the types. If omitted, the rule applies to all types. The following values can be used (one per where(...) clause):

  • class – Affects all classes but no enums.
  • compiler – Affects all compiler-generated types.
  • enum – Affects only enums.
  • event – Affects only events.
  • interface – Affects only interfaces.
  • member_attr – Affects only members that have a special type attribute defined in the next filter.
  • type_attr – Affects only types that have a special type attribute defined in the next filter.
  • interface_impl – Affects only types that have implemented certain types defined in the next filter.
  • public_interface_impl – Affects only types that have implemented certain public types defined in the next filter.
  • inherited – Affects only types that are inherited from certain types defined in the next filter.
  • inherited_public – Affects only types that are inherited from certain public types defined in the next filter.
  • nested_excl – Affects only types containing nested excluded types.

# ( ... )

The next filter is again optional. If nothing is defined, it means all types in all namespaces are considered. You can specify a namespace and a list of types within it to restrict which elements the rules apply to:

(namespace=MyNamespace; types=Type1,Type2)

# ( ... )

The last filter is also optional and further restricts which members are affected. If not set, everything from the previously defined classes is selected. Possible values are:

  • -typenames – Typenames will not be renamed.
  • -namespaces – Namespaces will not be renamed.
  • -methods – No methods will be renamed.
  • -fields – No fields will be renamed.
  • -properties – No properties will be renamed.
  • methods: – A list of multiple methods, comma-separated.
  • fields: – A list of multiple fields, comma-separated.
  • properties: – A list of multiple properties, comma-separated.
  • events: – A list of multiple events, comma-separated.

For example:

(-typenames; -namespaces; methods=MyMethod,MyMethod2; properties=MyProperty)

# Using Regex

When using rule regex:, any name (namespace, type, method, field, property, event) you specify after methods=, fields=, properties=, events=, namespace=, or types= is treated as a regular expression.

# Complete Example

[assembly: Obfuscation(Feature = @"rule: (-renaming,-necrobit,+stringencryption) where (interface_impl) (namespace=MyNamespace; types=Interface1,Interface2) (-typenames; -namespaces; methods=MyMethod,MyMethod2; properties=MyProperty,Prop2)")]

# Explanation:

  • rule: (-renaming,-necrobit,+stringencryption)
    Disables Renaming and NecroBit, enables String Encryption.

  • where (interface_impl)
    Applies this rule only to types that have implemented the defined interfaces in the next filter.

  • (namespace=MyNamespace; types=Interface1,Interface2)
    Interfaces Interface1 and Interface2 within MyNamespace.

  • (-typenames; -namespaces; methods=MyMethod,MyMethod2; properties=MyProperty,MyProperty2)
    From the selected types, do not rename the type names or namespaces, but apply these rules specifically to methods named with name MyMethod and MyMethod2 and properties MyProperty and MyProperty2.

# Further examples:

[assembly: Obfuscation(Feature = @"rule: (-renaming, -hidemethods, +controlflow)")]

[assembly: Obfuscation(Feature = @"rule regex: (-renaming, +stringencryption) (types=.*Resource)")]

[assembly: Obfuscation(Feature = @"rule regex: (-hidemethods) (namespace=MyApp.Services; types=Service.*) (methods=Get.*)")]

[assembly: Obfuscation(Feature = @"rule: (+controlflow) where (inherited_public) (namespace=MyApp.Base; types=BaseClass) (-typenames; -namespaces)")]

[assembly: Obfuscation(Feature = @"rule: (-renaming) where (enum)")]

All these combined filters allow very fine-grained configuration of the obfuscation process directly from within your code using Obfuscation attributes.

How to Generate Assembly Attributes from Advanced Rules Editor:

If you prefer to set up rules visually and then generate the corresponding attributes:

  1. In .NET Reactor, go to 2. Protection Settings -> Advanced Rules.

  2. Define or select your rules from the GUI.

  3. Right-click on the selected rules and choose "Generate Assembly Attributes".