The .NET Framework & Protecting your Code

More features

Metadata obfuscation

Finally, both obfuscators remove metadata not required at runtime such as fields and methods marked as properties and events, which don't actually exist in the runtime environment, as well as parameter names. For example, a property is a type, a name and a pair of methods (get_/set_). This information is used by compilers - you read from a property, the compiler generates a call to the getter method - however, this information is not required at runtime. At runtime, the execution engine simply sees a call to a method. This means that the obfuscators are free to independently obfuscate both the get_ and set_ methods.

Pruning/Compaction

There are two features of Dotfuscator with no equivalent in Demeanor - pruning, and control-flow obfuscation. If you are re-using classes within your application, you may find that you're only using a fraction of its functionality. Dotfuscator's pruning feature offers to remove unused code and metadata from an assembly, and PreEmptive claim that in some situations customers have had up to a 70% size reduction in their assembly. It seems unlikely that such a large figure would be repeated in most common situations, but it could still prove a bonus for some people. On the other hand, the use of this feature is only really going to make sense to assemblies to which you have access to the source code - and so in theory you could make the same savings by removing the non-used features manually (albiet taking a little longer!). Like everything else in Dotfuscator, you can configure exactly which classes/namespaces to apply this to, and this feature should be treated with care if you are using reflection in your application, as it won't be able to detect the methods referenced by reflection as being used.

Control-flow obfuscation

Whatever quantity of renaming takes place, identifiers are not the only thing that can reveal information about the way your program works. Dotfuscator Pro includes an option which effectively tries to obscure the logic of your program. However, unlike pruning and identifier renaming which can actually improve the performance of your application, control-flow obfuscation can degrade it. Fortunately, Dotfuscator provides three levels of this obfuscation so that you can decide how far you are willing to trade off performance for better protection. With control-flow obfuscation set to high,

int j=0;
for(int i=0; i<100; i++)
{
   if ( Math.IEEERemainder(i , 10) ==0 )
   MessageBox.Show(j.ToString());
   j=j+i;
}
MessageBox.Show(j.ToString());

was converted to

int i = 0;
int j = 0;

goto i0;
do {
   while (true) {
      local0 += local1;
      local1++;
      goto i0;
      i1: MessageBox.Show(j.ToString());
   }
} while (Math.IEEERemainder((double) i, 10) != 0);
goto i1;
i0: if (local1 < 100)
   goto i-1;
MessageBox.Show(j.ToString());

Clearly this has made it far more difficult to determine what is going on! As an interesting side-effect, this obfuscation can also cause a number of decompilers to crash, and Dotfuscator also includes an option to make the ildasm program crash. PreEmptive say that they constantly monitor new dcompiler releases and attempt to break them using their obfuscator, but obviously this can never be a particularly effective way to protect your code, given its reactive rather than proactive nature.

Multi-assembly applications

In many situations, you may find yourself with a number of assemblies for whatever application you are developing - but these assemblies are only ever used internally by the application. In this situation, although assemblies may have public members, it still makes sense to keep these obfuscated, provided the necessary changes are made in the other assemblies using them. This is exactly what Demeanor allows you to do - pass it one assembly, and it will automatically obfuscate all the related assemblies that you want obfuscated with it. Finally, with the support for incremental obfuscation, you are still free to release an update to just a single assembly within your application without having to do recompile the whole lot. Dotfuscator provides similar functionality, allowing you to select multiple assemblies to be obfuscated similtaneously.

Obfuscation of managed C++ assemblies

Both Demeanor and Dotfuscator also provide support for obfuscating Managed C++ assemblies, which can't actually be decompiled using ildasm, as they contain a mixture of native and il code. In this situation, both directly process an assembly rather than relying in ildasm and ilasm - this is standard behavoir for Demeanor, and Dotfuscator switches to this mode when needed.

You might also like...

Comments

About the author

James Crowley

James Crowley United Kingdom

James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audien...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler