Selecting an obfuscator for Silverlight

by StefanOlson 22. October 2009 09:26

Update 31/July/10: Having had problems with .net reactor not correctly working with my WPF application, I have evaluated and chosen CodeFort as my obfuscation tool. A review will follow at some stage, but it supports obfuscating Baml and xaml on WPF and Silverlight and is very affordable ($199US), I would highly recommend it!  Their support has been outstanding!

Update 10/Nov/9: .net reactor can now directly work with xap files

Update 2/Nov/9: .net reactor now has no problems with control flow obfuscation, and as a result it is now my recommended product (see updated conclusion).

Update 24/Oct/9: DeepSea obfuscator now has anti-disassembly support, and have updated the review to reflect that it can open xap files directly.  Please note however that the current DeepSea as obfuscator build (2.1.6.120) causes exceptions with my project which requires me to exclude one assembly from removing unused delegates.

As I have expressed in a previous post I had struggled to find an affordable obfuscator that worked for Silverlight.  When it came time to submit my entry for the ComponentArt Silverlight coding competition (http://www.componentart.com/community/competition2009/details.aspx?id=1109), I wanted to ensure that the code was obfuscated before uploading it so that my hard work is not stolen. Unfortunately, the vision I had of .net reactor 4 beta didn't in fact work with my project.

So I set out on a very quick evaluation of the available obfuscators. This review describes my experiences with three products:

Not evaluated:

  • Spices.Net 5.6.6.0 - $699. At the time I started the evaluation they hadn't released a new version since Silverlight 3 was shipped and it is not clear what their Silverlight support was like
  • Dotfuscator for .NET - ~$2000US. Too expensive.
  • Crypto obfuscator - Enterprise edition $399US.  Wasn't aware of it when I started this review.
  • Eazfuscator.NET – Free. Needs to be added into the Visual Studio build process and looks too complicated.
  • If there are others I've missed, please let me know.

If you are developing a WPF application, please be aware that the findings may be completely different. WPF applications can include native code to make the obfuscation more effective, is not possible in Silverlight.

What is an obfuscator?

From Wikipedia: (http://en.wikipedia.org/wiki/Obfuscator)

“Obfuscated code is source or machine code that has been made difficult to understand. Programmers may deliberately obfuscate code to conceal its purpose (a form of security through obscurity), to deter reverse engineering, or as a puzzle or recreational challenge for readers. Programs known as obfuscators transform human-readable code into obfuscated code using various techniques.

Obfuscating code to prevent reverse engineering is typically done to manage risks that stem from unauthorized access to source code. These risks include loss of intellectual property, ease of probing for application vulnerabilities and loss of revenue that can result when applications are reverse engineered, modified to circumvent metering or usage control and then recompiled. Obfuscating code is, therefore, also a compensating control to manage these risks. The risk is greater in computing environments such as Java and Microsoft's .NET which take advantage of just-in-time compilation technology that allow developers to deploy an application as intermediate code rather than code which has been compiled into machine language before being deployed.”

Types of Obfuscation

Below is a list of the things that you might want a Silverlight obfuscator to be able to do.

Name Obfuscation

This involves changing the name of the type/function/property etc… so that it cannot be understood e.g:

From:

image

To:

image

Control flow obfuscation

This involves making it difficult to understand the flow of your function. E.g:

From:

image

To:

image

Even better is when the obfuscation is so complicated that .net reflector can't do anything with it at all. Currently the only reviewed product that can do this is {smartassembly}:

 image

Eually as good is what .net reactor can do, which ensures that it can't even be viewed in reflector:

image

Merging

One of the great features of obfuscators when working with Windows Forms is the fact that they can merge multiple assemblies into a single assembly, and therefore make all public classes internal, and as a result these classes can then have their names obfuscated. Unfortunately this is not possible with WPF because the compiled xaml, called Baml, is not a publicly documented file format and changing class names would break the Baml.

In Silverlight the xaml files are compiled directly and unchanged into the executable as resources. This means a decent obfuscator should be able to appropriately change the names of classes referenced in the xaml files and merge assemblies into one. Unfortunately, no obfuscator that I'm aware of is doing that at this point.

However, what can be done is that any data access layer classes with no xaml could be merged and made internal. None of the tools tested currently have that feature working, although I expect this to be working in DeepSea obfuscator very soon - it can build it this way, but it is currently causing exceptions at runtime. In .net reflector it looks like this:

image

Xaml obfuscation

None of the tools make any effort to change xaml files. This makes it very easy for anyone to take any of your xaml code and reuse it.

They don’t even make the simple effort to obfuscate the names of event handlers and change the reference in the xaml.

Anti-Disassembly

It's worth looking for an obfuscator that can make it impossible for people to look at in .net reflector. What happens here is that some changes are made to the metadata so that .net reflector cannot handle it - so it won't load your assembly, which makes it more difficult for people to look inside your code.

image

String Encryption

All the obfuscators can encrypt your strings so that people can search through your executable to find where your code is based on strings.

General Silverlight obfuscator issues

Files

One problem with most Silverlight obfuscators is that you have to work with the files outside of the xap file.  Admittedly, this is not too hard because you just work with the files on the release folder, but then you then have to manually copy them into the xap file. It would be preferable to have an automated process that can work directly on the xap file.

Currently DeepSea obfuscator and .net reactor allows you to directly open and work with xap files.

One alternative to this is that some of the tools describe how to add their obfuscation process into the Visual Studio build process. Unfortunately, this requires some manual work on the project file, which puts me off doing that.

Tips for obfuscating

Make every class you possibly can internal.

This allows the obfuscator to be more aggressive and make it more difficult for people to understand your code because the class names can often be changed. An exception to the class name being changed is when you make a class with an associated xaml file internal. However, .net reactor and DeepSea are able to then hide the InitializeComponent function more effectively. To make a class with a xaml file internal you need to add x:ClassModifier="internal" in the Xaml and make it internal in the .cs file

 

.net reactor

.net reactor is very easy to use. Simply select your main assembly, and then any other related assemblies that you wish to obfuscate:

image

Then you should select the type of obfuscation you require from the protection presets menu:

image

You can edit settings in a more detailed fashion via the settings tab:

image

in the latest version .net reactor protects the virtual tour viewer project perfectly.

Merging does not work at all, it crashes .net reactor when trying to build your project.

Here's how it looks when you load it up in.net reflector, which is what you want to see:

image

Unfortunately, by default, .net reactor outputs every assembly into a separate folder which makes it a time-consuming task to add to the obfuscator DLLs back into the xap file as you have to go into many separate folders.  However, you can set the target location to a particular folder, as you can see above in the target file property, and then it appears in one folder.

Support

Two separate Google groups have sprung up to provide for .net reactor because the support from the developer was either slow or non-existent. . More recently, the developer has been, very active in these forums and has provided me with fixes for problems I was having with control flow obfuscation.  The support was excellent , and I'm very much looking forward to some of the functionality in upcoming releases

 

DeepSea obfuscator

In DeepSea obfuscator you add all your files into a single list:

image

DeepSea obfuscator places all the output files in a single folder, which is very easy to use, because then all you need to do is add those files back to your xap file. It also produces a map file, which can be used to de-obfuscate the stack trace if you encounter any problems in your obfuscated application.

One really brilliant feature of this product is that if you go to the external configuration tab, you can see before it builds exactly what is going to do to each function in terms of obfuscation:

image

Also on this tab is full control over each and every setting for each and every function. This probably makes the user interface slightly more complicated than it needs to be, but it does give substantial power and flexibility. Once you get used to it, it is probably very useful.  However, if you want to set the same setting on multiple assemblies, you have to go through each assembly and change the settings - very time-consuming.

Unfortunately some of the concepts a bit confusing, they have a separate project and external configuration file, and I'm not entirely sure what the difference is.

Merging with DeepSea obfuscator is a slightly complicated task - there is no way to specify this in the user interface. You have to go into the assembly that you want to merge with other assemblies and add an attribute like this:

[assembly: Obfuscation(Feature="inject /a:TourObjects.dll /i:true")]

The /i:true indicates that I want to make all the classes in that DLL internal in the new dll (SilverlightTourViewer.dll). Unfortunately, DeepSea obfuscator has a problem with this and causes an exception when trying to run the application. If you don't make the classes internal the merge does work. As discussed below the support has been excellent and they are working on a fix for this.

The current release of DeepSea obfuscator now has any support for anti-disassembly, but not yet support for anti-disassembly features in the control flow obfuscation.

Support

The support from DeepSea obfuscator people has been outstanding. In response to my first e-mail requesting anti-disassembly support in the product they agreed to add it in. They've keep me up to date throughout the process of adding in this functionality. When I had problems with implementing the merge feature, their support was excellent and they have taken the files that are causing the problem and are working on a fix.

You can't ask for better than that!

 

{smartassembly}

Smart assembly was the first tool I tried. In some ways the user interface is the simplest. All you have to do is select your main assembly and check a few boxes.

image

Your files are output into a single folder, which is very easy to use, because then all you need to do is add those files back to your xap file.

Unfortunately, having checked all the boxes and built my application, it came up with all sorts of exceptions. The only two features that you could check that actually worked were control flow obfuscation and anti-disassembly. Name obfuscation, merging, pruning and anything else didn't actually work. It turns out that the problem with obfuscation is that it is obfuscating it ends that are referenced in the xaml. It is not changing the xaml, and therefore causes problems for Silverlight.

Support

The support from the {smartassembly} people was good, responses generally took around 24 to 48 hours. Unfortunately the support person didn't really appear to understand the problem and that it was actually a bug and suggested all sorts of things which made no difference, including excluding all the namespaces that were causing problems with the build - which effectively meant the application was not obfuscated.

He tells me that they will be working on this, but there is no timeframe for it to be fixed.

Conclusion

{smartassembly} didn't work for me at all. In addition, it is substantially more expensive than the other two options.

There are now two affordable Silverlight obfuscators in .net reactor and DeepSea obfuscator. Both of them work reasonably well.  Personally I have chosen to go with .net reactor. It provides better control flow obfuscation at this stage,  As long as the developer continues to provide excellent support I'm sure that the product will be very successful. However DeepSea obfuscator is an equally valid choice and it has excellent support.

A couple of other vendors have been in touch with me regarding reviewing their products, and I'll add these in at some stage in the future. However, both are more expensive than either the DeepSea or .net reactor obfuscators.

Tags:

Silverlight

Comments

10/23/2009 2:32:44 AM #

Pingback from topsy.com

Twitter Trackbacks for
        
        Stefan Olson's Blog | Selecting an obfuscator for Silverlight
        [olsonsoft.com]
        on Topsy.com

topsy.com

10/23/2009 9:51:41 AM #

Nice post.

Generally speaking, you will almost certainly have to do some manual tweaking/exclusions of types from renaming for proper functioning of WPF & Silverlight apps, due to XAML binding issues.  In fact, if you access assembly resources, you will probably have to do this even outside WPF/SL.

I've had good experiences Dotfuscator's Silverlight obfuscation - it is also able to break Reflector's disassembly at the method level, so {smartassembly} is not the only product that can do this, as you say (though Obfuscator is quite pricey).  Indeed, I haven't even had to concern myself with marking members internal, as Obfuscator detects anything that is not accessed externally and will go ahead and rename it even though it is public, unless you tell it the assembly is intended for external consumption as a "Library" (.dll for 3rd party use), which is very nice.

You may be interested in my "Do you obfuscate your Silverlight code" twtpoll: http://twtpoll.com/48z6ic -- 40% of respondents do obfuscate.

Tim Erickson

10/24/2009 10:31:40 AM #

Hi,

I remember testing various obfuscators a few months ago.
I almost went for DeepSea, until I found Eazfuscator.NET which supports Silverlight.

It is the only free solution that I found and it works well. I can't really talk about which is "better", but I know that it is certainly a good solution.

John

10/24/2009 4:54:48 PM #

Crypto Obfuscator : www.ssware.com/cryptoobfuscator/obfuscator-net.htm supports Silverlight assemblies, and does resoruce protection so that the resource files (XAML,BAML) cannot be viewed. Besides it also offers string encryption, overload renaming, control flow, anti-dissassembler, plus anti-tampering, anti-debug, etc.

LogicNP

10/25/2009 12:45:42 AM #

Trackback from uberVU - social comments

Social comments and analytics for this post

uberVU - social comments

10/26/2009 2:16:32 PM #

Tim,

Yes, you are right with having to tweak exclusions when you're dealing with data that will be accessed via bindings.  Some of this, however, could be alleviated by the tools changing the xaml on our behalf.

If I get some further time to lok at this I might see if Ican take a look at Dotfuscator and add it to the review.

Interesting poll. When you are deploying stuff internally, it probably doesn't matter if you do or don't obfuscate, but at least making an effort to obfuscate will make it more difficult for others to get into your code.

...Stefan

Stefan Olson

10/26/2009 2:17:53 PM #

John,

Thanks for the comments on Eazfuscator.NET.  I didn't look at it in the end because it just looked too time-consuming to have to change my project files when I have eight or so projects that make up the virtual tour.

...Stefan

Stefan Olson

10/26/2009 2:18:24 PM #

LogicNP,

Thanks for the suggestion. I am looking into adding this to the review.

...Stefan

Stefan Olson

10/26/2009 11:53:37 PM #

First, a disclaimer: I work for PreEmptive Solutions as a developer on Dotfuscator.

Our Silverlight/WPF support is quite good and although we do not (yet) obfuscate the XAML/BAML it is certainly high on our list.  In addition we are gearing up to launch an update release (4.6) which will accept a Silverlight XAP as a first class input so that you no longer need to work with the individual assemblies outside of the XAP.  We strive to provide a great out of the box obfuscation with numerous built in rules that detect various items that should not be renamed or removed and automatically exclulding them (Smart Obfuscation).

In addition, since the size of your XAP is always a concern Dotfuscator also provides Removal which will analyze your assemblies and remove any unused code from them in order to make them even smaller.

We do provide a free two week evaluation version so that you can try it out and see how it works.  If you are interested in the XAP processing just let us know and we'll set you up with an updated evaluation version as soon as it is publicly available.

Joe Kuemerle

11/1/2009 9:43:40 AM #

Joe,

Thanks for your comments. I am certainly interested in updating review to include your product.  Once I get a little bit of spare time, I will add Dotfuscator and Crypto Obfuscator to the review.  Please do keep me up-to-date with the version that will support XAPs directly.

...Stefan

StefanOlson

11/13/2009 9:17:24 AM #

As of this past Monday (November 9, 2009), PreEmptive Solutions released the 4.6.1005 version of Dotfuscator.  Dotfuscator now supports XAP files as first class inputs and will allow you to easily obfuscate your Silverlight applications since it will output an updated XAP file as it's output.

Joe Kuemerle

4/26/2010 7:00:18 AM #

Hi all,

The new CodeFort obfuscator, which was released last week (April 16, 2010), supports renaming of identifiers in XAML code, and is therefore at this moment the only Silverlight Obfuscator that is able to enforce renaming in an entire assembly.
Previously, when obfuscating Silverlight applications, you had to either manually or by using rules exclude types and member names that are being referenced in the XAML code. However, CodeFort eliminates the need to exclude names from the obfuscation, because it directly manipulates the XAML code to bring the XAML in sync with changes to names of namespaces, classes and their members.
This unique feature is coupled with strong protection schemes such as Reference Scrambling and Anti-Tampering, preventing attackers from altering the protected assembly. Of course, it also natively supports input and output of XAP packages.

You should take a look at the site and download the Free Edition:
http://codefort.org/

Hope this helps,

Christian
codefort.org

Christian Scheuer

5/20/2010 10:57:31 AM #

Pingback from 57.luna-atra.net

Relay 2 Cooling System Header Outlet Size, Relay 3 Replacement Pollution

57.luna-atra.net

8/8/2010 11:01:36 PM #

Great Site Stefan.

I am really anxious to find out about the difference in the CodeFort Obfuscator and how it compares. Please let us know!

I'll get into it too and have a look at their free edition, which I hope to find time to put onto my blog.

Thank you for the excellent post and information.

ZeroGravityChimp

8/9/2010 6:41:47 AM #

We gave CodeFort a shot a few months back after trying several commercial products and the ones in this review.  Initially I had some concerns as we have a large complex application and indeed CF did not successfully obfuscate our code - but to be fair, not a single product did so obviously we were doing something special!   I wrote to 3 commercial vendors and the guy that build eazobfusicator, and codefort were the only ones that look some real interest in fixing our apps problems (two said we should change our app..), and indeed Codeforts support is outstanding, they resolved the problems so we didn't have to change our application which saved a lot of debugging and hassle.  New features also seem to be coming out all the time, so they are actively working on it and not just milking the market.  The product works a treat for us, the only thing I wish for really is something an improvement that can do multiple xaps at once, as our app is quite large we had to build a custom module that downloads additional XAPS dynamically.

cheers
ewart - www.fitnessmentor.com

Ewart

11/10/2010 6:45:33 PM #

Logicnp says that Crypto Obfuscator : www.ssware.com/cryptoobfuscator/obfuscator-net.htm supports Silverlight assemblies, and does resoruce protection so that the resource files (XAML,BAML) cannot be viewed. Besides it also offers string encryption, overload renaming, control flow, anti-dissassembler, plus anti-tampering, anti-debug, etc.,can anyone comment on this?

Edward Hp

Add comment




biuquote
  • Comment
  • Preview
Loading



About the author

Stefan Olson is the Managing Director of Olson Software.  He has been developing software using Microsoft Technologies for nearly 20 years.

He is currently working on building the next generation Virtual Tour software in WPF and Silverlight for www.palacevirtualtours.com.