Sunday, May 15, 2011

.NET decompilers–or “Attack of the (currently inferior) Clones”

RedGate’s Reflector tool has been ridiculously popular amongst .NET developers for a long time.  It has shed light on all kinds of dark .NET corners in both the shipped .NET assemblies and third party ones.  Heck, I’ve even used it to try to make sense of poorly obfuscated ones, with surprisingly positive results (DevArt dotConnect, I’m looking at you!).

But then we were all cast out of Eden.  Free Reflector no longer exists, and they want you to pony up $35 to get back in.  I tried to hold on to the old versions for as long as possible:

53df13017672394c64fd9ac9137001af

But eventually decided to have a look at Reflector 7, which I’ve now reached the end of the 14-day trial of:

22044c3cf7dc9872285180b33d162874

So let’s have a look at the contenders for the “.NET Decompiler King” crown, that have surfaced from the nerd rage that bathed the web after the announcement of the demise of free Reflector.

A good list of possibilities can be found in this StackOverflow discussion.

I’ll look at the, what appear to me, top 3 offerings:  ILSpy, which is open source,  JustDecompile from Telerik (free but closed), and dotPeek from JetBrains (free but closed):

 

ILSpy:

Interestingly, ILSpy lists .NET4 as a prerequisite.  Meh.  Whatever, I’m hoping it’s an indicator of use of more “interesting” coding patterns.

It’s a bit rough at the moment, but runs fast, and is pretty stable.  Navigation is not as fluid as in Reflector.

5534918e0a8a6c6915480c936739390b

Lambda support is as bad as it was in Reflector 6, but is clearly on the roadmap on the ILSpy website. 

9b8ba14fbfb13d67fcebe0d0ef4f7f86

This has promise, but is lacking in the usability department.

 

JustDecompile:

Overall, the look is very much like Reflector - types are hyperlinked, you can expand all members of a class etc.  Other assemblies are pulled in a needed if it can resolve them.  One annoying thing was that calls to "base" constructors weren't hyperlinked - something that's annoying if there are a lot of constuctor overloads.

Overall impression is one of extreme slowness.  Assemblies take ages to load, everything is quite painfully slow.  But then again, it’s a young product.

5173ac52f1ee58fc184076bdffad0ab4

Has nifty search, allowing to find usages.  A nice improvement that can already be seen is the ability to filter by only Read or Write usages.  Handy when you are trying to find possible culprits that are setting some member for example.  Although it didn't quite work as expected - as in, it didn't work for me.

At the moment, the product seems a very sluggish, and a fair few crashes.  Also, from the various errors and the presence of the DLL in the directory, we can tell that Mono.Cecil is being used.  Refreshingly, at least for the moment, the application does not seem to be obfuscated, like Reflector was.  Anyhow, the product has a long way to go.  Until I see refinements like bookmarks, ability to create deeper navigation trees (in Reflector you could do deep investigations of using "used by/called by" to visualise a deep call tree you're interested in, expanding more and more nodes to reveal a long chain of callers to establish a relationship between two modules).

Lambda handling is poor as well:

IEnumerable<DOCUMENT> dOCUMENTs = ParameterExpression[] parameterExpressionArray3 = new ParameterExpression[1].Where(Expression.Lambda(parameterExpressionArray3[0] = parameterExpression, parameterExpressionArray3));

As for Add-Ins, which in my opinion endeared Reflector to the community, I posted a question on the Telerik forums (which are already full of bug reports and feature requests, only a few days after release) and quickly got the response that "This is definitely an option that we'll target for the feature version of the product".  So their heart seems to be in the right place.

 

dotPeek:

JetBrains has just released a very early version of their dotPeek software, and it's a little, well, undercooked. They must be coming from the "release early, release often" school of development:

image

There appear to be various errors sprinkled through the code, and the treatment of lambdas is by far the least readable.  Navigation and search are very functional, as I expect they’re almost straight out of ReSharper.

Conclusion and musings:

Looking at these three, it seems to me that so far we're quite far off getting a decent replacement for Reflector.  Although the announcement of moving to a paid model has created this Cambrian explosion of .NET decompilers, the current offerings seem to indicate that it's quite difficult to get the level of polish that Reflector had.

An interesting differentiator in the near future for these products I think will be Lambda expressions - given how much more we're using Lambdas in day to day .NET development now, I'd say the final favourite decompiler will be the one that renders them properly, and so far it's a feature only available in Reflector 7 (even though it uses the "query" style syntax for rendering them):

Image(1)

We'll just have to wait and see what happens over the next few months.  All of the above tools are quite early on in their development, and I’m guessing they’re all shooting for mimicking Reflector’s abilities one to one, before adding their own flavour on top, but they’re not there yet.

In the meantime, is $35 all that much to spend on a decent tool?  My feelings towards this were quite mixed initially, first I thought, well $35 is fine for a trusted tool, but then the feeling of betrayal sets in, especially because there isn’t even a free “lite” version.  On the other hand, I think a lot of people would have happily donated the $35, so this should be no different.  For example, if work didn’t pay for ReSharper, I’d most likely buy my own license, so what’s $35?  It’s all these mixed feelings from suddenly having to pay for something that you had for free.  Of course all sins would be forgiven if only RedGate offered a free “lite” version.

It's illogical, Captain.