Example Rules

To tailor the Babel Obfuscator's obfuscation process, users can craft their own XML rules. These guidelines dictate how the obfuscator interacts with particular classes, methods, and properties, among others. Offering detailed control, these rules enable users to refine the obfuscator's results. This section presents several examples of XML rules for Babel Obfuscator.

Disable Class Renaming

To disable renaming for a given class using Babel Obfuscator's XML rules, you can use the following XML rule:

<Rule name="disable-myclass-renaming" feature="renaming" exclude="true" 
      applyToMembers="true">
  <Target>Classes</Target>
  <Pattern>MyNamespace.MyClass</Pattern>
  <Description>Disable renaming for MyClass.</Description>
</Rule>

Note:

Replace MyNamespace.MyClass with the fully qualified name of the class you want to exclude from renaming.

  • The feature attribute is set to "renaming" to target the renaming feature.

  • The exclude attribute is set to "true" to prevent renaming for the specified class.

  • The applyToMembers is set to "true" to prevent the renaming of class members.

  • The Target element specifies that the rule applies to classes.

  • The Pattern element specifies the fully qualified name of the class.

Compiled Generated Code

The following rule will prevent some enhanced obfuscation features for compiler-generated code.

<Rule name="no-compiler-generated" 
      feature="control flow, value encryption, string encryption" 
      exclude="true" applyToMembers="false">
  <Target>Classes</Target>
  <Pattern>*</Pattern>
  <HasAttribute onEnclosingType="false">
    System.Runtime.CompilerServices.CompilerGeneratedAttribute,
    System.Diagnostics.DebuggerHiddenAttribute
  </HasAttribute>
  <Description>Do not obfuscate compiler-generated methods.</Description>
</Rule>

Anonymous Types

In C#, an anonymous type is a type that is defined without a name using the new operator together with an object initializer.

var query =
    from prod in products
    select new { prod.Name, prod.Price };

foreach (var v in query)
{
    Console.WriteLine("Name={0}, Price={1}", v.Name, v.Price);
}

This allows for creating objects on the fly without the need to define a specific type beforehand. The compiler generates a type name for the anonymous type, which typically starts with the characters <>f__Anonymous. The generated name is unique and is not meant to be used by the developer.

Anonymous types are used extensively in LINQ queries and other scenarios like ASP.NET web applications where the creation of objects on the fly is required.

In the context of obfuscation, anonymous types can pose a challenge as their generated names could be obfuscated. Renaming them may cause issues with the code that uses them, so it is often recommended to exclude them from obfuscation.

One way to achieve this is by adding the rule targeting any symbol with the attribute

System.Runtime.CompilerServices.CompilerGeneratedAttribute

to exclude all compiler-generated code, including anonymous types.

<Rule name="rule1" feature="renaming, dead code" exclude="true" applyToMembers="true">
  <Pattern>*</Pattern>
  <HasAttribute>System.Runtime.CompilerServices.CompilerGeneratedAttribute</HasAttribute>
</Rule>

Another option is to use a regular expression pattern to match the name of any inline type, as these types typically have the prefix <>f__Anonymous.

<Pattern isRegEx="true">
  <![CDATA[<>f__Anonymous.*]]>
</Pattern>

By checking the name of the anonymous type in any .NET assembly inspector like ILSpy or dotPeek, you can verify if it follows this rule.

Using Dynamic Proxy Calls Filters

Dynamic Proxy Call Filters provide a valuable tool within Babel Obfuscator to fine-tune Dynamic Proxy generation and achieve the desired level of obfuscation while maintaining optimal performance (see Dynamic Proxy).

<Rule name="rule1" feature="dynamic proxy" exclude="false" applyToMembers="true">
  <Pattern>*</Pattern>
  <Description>Set Dynamic Proxy Call Filters</Description>
  <Properties>
    <DynamicProxyCallFilters>IEnumerator.*;ICollection.*</DynamicProxyCallFilters>
  </Properties>
</Rule>

The provided XML rule represents a configuration in Babel to set Dynamic Proxy Call Filters.

By setting Dynamic Proxy Call Filters, you can precisely define which method calls should be intercepted and replaced with dynamic proxies. This allows you to protect critical sections of your code while leaving others untouched. With the ability to specify regular expressions for the filters, you have the flexibility to tailor the rule to match specific method naming patterns or behaviours that require dynamic proxying. This allows you to adapt the obfuscation and protection strategies based on your application's unique requirements.

Controlling Obfuscation Agent

The Obfuscation Agent in Babel Obfuscator is responsible for executing a series of tasks during the obfuscation process based on predefined rules. Its primary purpose is to prevent potential issues that obfuscation might introduce, which could break the resulting assembly. For instance, the Agent ensures that symbols used in reflection aren't obfuscated because doing so could lead to runtime errors. The tasks performed by the Agent can range from simple checks, like examining fields of serializable types, to more complex operations involving MSIL code static analysis.

While the Obfuscation Agent is crucial for ensuring the smooth functioning of obfuscated code, there might be scenarios where developers want to achieve specific obfuscation results that require disabling certain Agent tasks.

To skip specific Agent tasks using XML rules, developers can define an exclude rule targeting the agent feature. For instance, to disable tasks like "Serializable types" and "Reflected strings", an XML rule would look like:

<Rule name="rule1" feature="agent" exclude="true">
    <Pattern>ACME.Data.*</Pattern>
    <Properties>
        <TaskNameList>Serializable types;Reflected strings</TaskNameList>
    </Properties>
</Rule>

In conclusion, while the Obfuscation Agent plays a pivotal role in ensuring that obfuscated code operates without hitches, there are situations where developers might need to disable specific tasks to achieve their desired obfuscation outcomes. It's essential to approach this with caution, understanding the implications of each disabled task on the final application.

Last updated