Thursday, 27 January 2011

Obfuscating my code

Obfuscation. What a strange word, it's almost as if it's designed to obfuscate itself.

Anyway, when it came to obfuscating my code, I did what any .Net developer would do, and did a Google search for 'best free .Net Obfuscator', and after hours of trawling through the links and pages of answers on StackOverflow (and the myriad of annoying scraper sites), I came down to a choice of two, which receive great praise are and still active; Eazfuscator .Net and Babel .Net.

Eazfuscator is totally free, while Balel.Net offers three versions, one of which is free.

The free version of Babel is slightly cut down and offers a little less than Eazfuscator, but this wasn't a deal breaker to me, as I’m not interested in stopping some socially inept 14 year old from reversing engineering my code to see how to circumvent the licensing. What ever I do, if my app is popular enough, it will happen.

First impressions are that Babel is the more professional, but this is merely down to their fantastic looking website. The site is delicious and makes me want to click on the nearest download link, whereas the Eazfuscator site makes me wonder if I just clicked on a  conspiracy theory website. That aside, on closer inspection, it seems that Eazfuscator is more active going by the blog, Google groups and releases.

Anyway, I downloaded both versions and gave them a go with the default options, and after obfuscating my code, both versions created problems. With Eazfuscator, I drilled it down to one issue, and with Babel, I had two issues.

The first issue, which they shared, was with the method naming pattern of Reset<PropertyName> and ShouldSerialize<PropertyName>.
To keep intellisense uncluttered, I keep these methods private (as does Microsoft), but because they are private, the method names get obfuscated and become unsynchronized with the public property name which remains unchanged.

It was very simple to fix this, I just did a search for ‘Sub Reset’ and ‘Function ShouldSerialize’ and decorated each method with the attribute <Obfuscation(Feature:="renaming")>. This is a standard framework attribute and is recognised by both obfuscators.

The other issue, which caused Eazfuscator no problems, was the GetSortedActionItems method of a DesignerActionList class.
In this method, you define the menu items that appear when you right click a control on the design surface:


You tell the designer which property or method to invoke, using string literals:

Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection
    Dim items As New DesignerActionItemCollection
    items.Add(New DesignerActionPropertyItem("AutoSize", "Auto Size"...))
    items.Add(New DesignerActionPropertyItem("AutoSizeOffset", ...))
    ...
    Return items
End Function

Again, this was easy to fix by finding each method referred to and decorating it with the Obfuscation attribute: 

Reflection.Obfuscation(Feature:="renaming")> _
Public Property AutoSize() As Boolean

These were the only problems I came across but, based on those problems, I could see that problems could also occur any place a string literal was used to refer to a member name. For this reason, I also did a search for TypeDescriptor.GetProperties, .GetValue and .SetValue.

I then checked to see if they referenced any non-public members, which I would then need to decorate with the attribute. Thankfully, I didn’t find any.

In the end, I opted for Eazfuscator for the following reasons:
  • It created fewer problems
  • It appears to be more active
  • It has a feature whereby you can encrypt, with a password, the member renames. This means that if a customer sends you a stack trace, you can use your password to get it back to a legible state.
Having said that, I do have one problem with Eazfuscator; the latest version 3.0, requires your assembly to be compiled using the .Net 4.0 framework. Although I have 4.0, I target my assemblies to 2.0 to maximise the number of customers that can use them. For this reason, I had to download the previous 2.8 release. If it turns out that bug fixes will apply only to 3.0 onwards then I will have to switch to Babel.Net.

Update
I've heard from the author of Eazfuscator, and it seems that version 3.0 only requires .Net 4.0 to execute, but you can target your finally assembly to whatever version you like. I blame my poorly researched paragraph on a late night and switching between PCs with different versions of the .Net framework installed!

3 comments:

  1. Thank you for the great review!

    I just want to clarify one little thing if you don't mind. Eazfuscator.NET supports multi-targeting, so you can easily process .NET 2.0 assemblies by the latest versions of Eazfuscator (which use .NET 4.0 themselves) without any problems.

    Sometimes easy things are not so obvious, I know.

    ReplyDelete
  2. Thanks Oleksiy,

    I've just read your reply to my comment on your blog, and I'll update my post to reflect the new info.

    ReplyDelete
  3. The main advantage that ASP.NET provides over Java is that you are not really stuck with one language.

    .net obfuscators

    ReplyDelete