Decompiling .NET Applications

Posted by Filip Ekberg on February 14 2013 15 Comments

There are many reasons to why you might want to decompile an application after it’s been compiled. Compiling C# code “just” translates it into MS IL. The compiler of course does some magic and tweaks the code as much as possible. There’s no metadata stored after compilation which means that comments and such will not be available in the IL output.

The following image illustrates what happens when we compile something, we put the C# code into a basket and tell the compiler to give us a binary of this which is sort of a black box at the moment. We know that whenever we want to use this black box we have something behind the curtain that knows how to open it and use it properly (read: CLR).

Compiling C# Code

Let’s consider a basic variable instantiation and an equality check, when this is compiled it will output something partially readable. To me the output is readable but that’s just because I have a weird love for IL. When this basic snippet was compiled using LINQPad it generated some IL which you can see below.

Compiled C# Code

Imagine that you got a DLL from an old co-worker and the code is long gone but you need to make some changes to the code. What do you do? One option is to mimic the functionality if the application is not too big and create it from scratch but that is just cumbersome. Instead what we want to do is something like you can see illustrated below; we want to go back from IL to C#!

Decompiling C# Code

So how do we do this? By using a decompiler!

As I tend to do this quite often to understand how libraries work that I have no control over, I have tried some different tools for just this cause. Let’s take a look at four of the most common ones on the market. Don’t worry, there’s both free versions and paid ones out there!

Telerik JustDecompile

The first one that we’re looking at is a product from the Just* family created by Telerik. I do like the products from Telerik so this one should be quite interesting!

JustDecompile is completely free and available for download over at Teleriks website. One thing that I didn’t like thought was the installer, generally Telerik’s installers are pretty nice, but I don’t like being “guided” to install other stuff than what I’ve asked for.

Below is a screenshot of the installer and as you can see it advices you to install a lot of trials for other Telerik products.

JustDecompile Installer

After selecting only to install JustDecompile the installation will only take up 36MB. You’ll also need to create a Telerik account if you don’t already have one which can also be a hassle, but it’s free so why not!

I’ve setup a project that has the same variable declarations and the equality check from above and then compiled and opened the executable in JustDecompile. The result is quite similar to the original source as you can see in the following image.

Decompiling with JustDecompile

We can also select to show the result as IL instead of C# code!

Decompile with JustDecompile show IL

There are a couple of things that I didn’t find straight forward using JustDecompile.

Pros

  • It’s free!
  • It’s fast!
  • The UI is beautiful
  • It looks easy
  • Does what it should (partially)

Cons

  • There’s a button for creating a project, I expected it to be able to export my binary to a complete VS Solution but it’s grayed out and there’s no tooltip on why that is so.
  • Showing the source as VB instead of C# shows nothing at all, shouldn’t matter if the original code was C# or not.

JustDecompile Summary

Even though there are some cons; would I recommend you using it? Of course! If you haven’t installed it already go ahead and do so! It can only become better if more people support it and give them suggestions. There’s even a suggestion button where you can submit requests.

ILSpy

This one is interesting, ILSpy is an open source assembly browser and decompiler for .NET Applications! This means that if you don’t like what it does or if you have feature suggestions, “you can just” provide the fix yourself! The tool itself is equal to what JustDecompile offers but the installation process is much easier. You simply grab the binaries or source from the ILSpy website and unzip it wherever you want it!

ILSpy

I simply performed the same process as I did with JustDecompile; I started ILSpy and opened up my executable but this is where it gets interesting. The code that it decompiles to looks Exactly like the code that I wrote in Visual Studio as you can see in the following image.

ILSpy Decompile

Decompiling to VB also works right out of the box, this tool has what it takes!

ILSpy Decompile to VB

Now to the more interesting feature; Can we save/export this to a C# Project?

By the looks of it there’s a “Save Code” action in the File menu, selecting the assembly and then pressing ctrl+s or the “Save Code” action actually lets us save a csproj file! If you open up the location in your file explorer you will see that it actually generated a project file and the code file!

ILSpy Save project and Export Code files

I think we’ve looked enough at ILSpy to write up a pros and cons!

Pros

  • Free!
  • Open-Source, do I need to say more?
  • All features seem to work as they should
  • Easy to use interface
  • Fast!

Cons

  • The UI isn’t really that good lookig but it’s functional
  • The application seemed to freeze once but it just took a while to analyze a code file, I had to stretch for this one..

Summary

There really aren’t many bad parts regarding ILSpy, I like it but if I have to complain about something it’s the UI and that it felt like it froze once. I really recommend trying out ILSpy and looking over the code for it, it’s great for educational purposes and I have co-workers that use it all the time and like it a lot.

What are you waiting for, go download!

dotPeek

Just as the two mentioned above dotPeek is available for free, it’s not open source though. dotPeek comes from JetBrains and is available on their website where you can also find a lot of interesting information about how to use it.

Installing this is easy and doesn’t force you or ask you to install anything else than what you really want in this case.

dotPeek

If you are familiar with ReSharper (R#) which is also a product from JetBrains, the keyboard shortcuts will be something of value to you. In fact dotPeek uses the same navigation as you might be used to from using ReSharper!

Let’s have a look at what dotPeek thinks of our executable. When opening up dotPeek you’re meet with a beautiful interface that feels like it’s a part of the Visual Studio family (except for the very colorful icons). Opening up the executable and looking at the code you can see that it didn’t really give us the same result as any of the other decompilers we’ve looked at.

dotPeek looking at the code

So instead of actually displaying what the IL tells us, it analyzes the IL and optimizes the code for us which is really not what we want to do. There’s also no way of swapping between C#, VB.NET, F# or IL. So in this case we are “stuck” with looking at some C# code without knowing what IL it comes from.

What is also a downside to this is that you cannot export the code that you are looking at, which means that this is a pure code browser.

Pros

  • Beautiful UI
  • Fast
  • Code inspection and navigation that you might be used to from ReSharper
  • Supports plugins just like ReSharper

Cons

  • Lack features such as show code in different ways; swapping between VB.NET, F# and IL
  • Doesn’t resemble the actual code that was compiled
  • Doesn’t support exporting code or projects
  • The application itself seem to be very light-weight and lacking configuration possibilities

Summary

While I like JetBrains products in general, this one feels like there’s something missing. Personally when I use a decompiler I want it to be able to show me the output code in different ways and give me options to export it. But if you are looking for an assembly browser that decompiles to C# and just does that, this is perfect. Even better if you are used to ReSharper, you will certainly find the keyboard shortcuts for navigation handy.

.NET Reflector

Last but not least, my personal choice .NET Reflector! I’m not really sure why this is my personal favorite but keep on reading and you might find that it’s because the mixture of good functionality with a common and easy to use UI.

.NET Reflector is available by RedGate but costs money which is maybe why it’s “better” than the alternatives. This wasn’t always the case though once upon a time it was available for free. I was lucky enough to win a free license a while back so I’ve been able to use it quite a lot. You can buy it or grab a free trial over at RedGate’s website.

The installation is easy and doesn’t try to force you to install a lot of other things that you don’t expect. .NET Reflector comes with a Visual Studio extension that will let you use the features in Visual Studio instead of starting a new instance of .NET Reflector.

Just as with JustDecompile and ILSpy I opened up the executable that we looked at before and as expected it shows the same result as ILSpy does!

.NET Reflector

As you can see here the UI is quite minimal and easy to understand. What is interesting here is that it also allows us to view the code as F# code as you can see in the following image.

.NET Reflector F#

If we want to export the code that we have just as we did with ILSpy we can right click the assembly and select “Export source code” this then asks us where to store it and gives us information about the exported files. As you can see in the two following images it exported more files than ILSpy did.

.NET Reflector Export Code

.NET Reflector Export Code Window

And the resulted files look exactly as we expect them to, the code file has the same code as we did in the original source code.

Pros

  • Easy to use
  • Everything is intuitive
  • Everything work as intended
  • Exports more code than alternatives
  • Fast
  • Beautiful UI
  • Cons

  • It costs $368 + tax if you want the VS Extension and this is quite expensive when good alternatives are completely free
  • Summary

    The costs is the only downside that I’ve found during my time using it which means that if .NET Reflector was free tool for Decompiling .NET Applications it would be the number 1 choice. It isn’t free and the cost must be factored in when comparing the value of the product.

    Conclusion

    If I hadn’t won a free license for .NET Reflector I probably would have used JustDecompile or ILSpy as both of them are very good tools for Decompiling .NET Applications!

    We’ve looked at how we can decompile applications and browse the code in different ways when only having the executable available. This also works with libraries in the global assembly cache.

    Looking around in the .NET Framework to see how they’ve done certain implementations can be great for educational purposes but using this at work to understand how someone implements a certain feature can be priceless.

    I hope you’ve found this read interesting and that you’ll be digging deeper with tools for Decompiling .NET Applications. Let me know which one is your favorite or if you’ve used another tool than the four mentioned above!

    Vote on HN

    15 Responses to Decompiling .NET Applications

    1. DmitryNo Gravatar says:

      Thank you for the comparison. You can add dotPeek from JetBrains(team behind the R#). It has nice code navigation features from R# built in and its free. If you need it to be built into the Visual Studio – R# contains it, so you can go to decompiled sources on F12 in VS.

    2. ShmuelieNo Gravatar says:

      That installation process for JustDecompile is very different than what I have, its a simple one product installer and the Export as Project works….hmmm

    3. Pingback: Cheatsheet: 2013 02.01 ~ 02.15 - gOODiDEA.NET

    4. VladiNo Gravatar says:

      Hi Filip,

      Thank you for the review of JustDecompile. Your observations are quite right but I just want to clarify some of your points hoping that they will be useful for you and your readers.

      - About the installation – once you install JustDecompile the way you describe, you’ll be able to update to the next version in several other ways: by using the auto update feature, or by installing one of our other installation packages (MSI or ZIP) that can be downloaded from here: http://www.telerik.com/account/your-products/freeproducts.aspx

      - About “There’s a button for creating a project, I expected it to be able to export my binary to a complete VS Solution but it’s grayed out and there’s no tooltip on why that is so.” – Actually the Create Project from decompiled assembly feature now works only for C#. I guess you’ve tried it with some of the other types of decompiled code like MSIL or VB.NET.

      - About “Showing the source as VB instead of C# shows nothing at all, shouldn’t matter if the original code was C# or not.” – we found the issue and will fix it. Thanks for pointing this to us.

      If you have any other feedback, I’ll be happy to answer you.

      Kind regards,
      Vladi
      The Telerik team

    5. Pingback: Dew Drop – February 15, 2013 (#1,499) | Alvin Ashcraft's Morning Dew

    6. MightymukeNo Gravatar says:

      Interesting post – I was especially surprised about the limitations of dotPeek as I use this often, but generally only on my C# code to see what changes have been applied by tools I use such as Code Contracts, ILMerge, etc. Therefore it’s suited me perfectly till now, and I haven’t needed to stress it with the other options you mentioned. I should point out that if you change the dropdown in dotPeek to one of the PDB options, then it will attempt to locate your source and display that. Unfortunately if you’ve since modified your source, what is displayed wont match the binary you’re trying to decompile. This seems a bit lazy to me.

      Based on your review I installed ILSpy to check it out and it seemed to work as well as you suggested. But as you’re such an awesome Pokemon trainer, I wanted to see if I could trip you up and added the line

      var z = 5;

      to your demo code to see how ILSpy would handle it. This was included correctly in the IL, but was optimised out of both the C# and VB code. Also the refresh seemed to be broken as I had to restart the application every time I recompiled otherwise the changes weren’t picked up.

      Since I was on a roll I installed JustDecompile. This was just as you had described, except that it said it needed 56M on my Win7 machine, and it installed the Telerik Control Panel which I didn’t ask for. I did like the text in OK button as well as the “May the source be with you!” quote during the install (its the small things that count). Again the redundant code above had been optimised out of the C# and VB code, but was correctly included in the IL. It also monitored the binary, and asked me if I wanted to reload it after a rebuild.

      Another big plus for Telerik is that because of this post, they’ve already found an issue with the app and have promised a fix (which I’m assuming has already been applied as the VB display worked fine for me). That’s pretty fast turn-around.

      I didn’t bother with .NET Reflector as its price puts it way above my interest level.

      So it looks like I’ll be changing to JustDecompile (which makes me feel guilty because I’m a HUGE JetBrains fan).

    7. Pingback: The Daily Six Pack: February 18, 2013 | Dirk Strauss

    8. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1297

    9. Jim RadenNo Gravatar says:

      This is a great review, but I have a couple of observations.

      For one, you’ll never get 100% fidelity between decompiled source code and IL for a number of reasons — including the fact that the compiler does things like creating temporary variables — so the ability of a decompiler to reproduce the original source code isn’t as important as its ability to produce source code that’s understandable. I would also think that the decompiled source code should compile to the same IL as the original, or, barring that, that the code should be 100% semantically the same, that is, unit tests written against the decompiled source would pass.

      Also, in my opinion the code example you have should have included lambdas, LINQ code, and/or functions containing “yield” statements. That is truly where the decompilers shine — or not — and where the real differences lie. I have all of the decompilers you’ve mentioned, and have purchased the $80 version of Reflector. I have found that none of them always works in all cases: sometimes ILSpy will work better on a bit of complex code than Reflector; sometimes dotPeek comes out on top. This is because the compiler does a lot of black magic under the hood for lambdas, LINQ code, etc., and it’s impossible to deterministically come up with the original source in those cases. What you want in those cases is something understandable, and sometimes looking at the output of more than one decompiler is what’s necessary in those circumstances.

    10. Pingback: Friday Links #243 | Blue Onion Software *

    11. Pingback: F# Weekly #8, 2013 | Sergey Tihon's Blog

    12. Filip EkbergNo Gravatar says:

      Thanks for all the great comments!

      If you haven’t seen it already the article is now updated with information about dotPeek as well. If you know of any other tools for decompiling .NET applications which should be in the post, let me know.

      Telerik,

      Thank you for taking the time to comment on this and for fixing the issues. Looking forward to try the future releases of JustDecompile.

    13. ArekNo Gravatar says:

      Nice article,
      i’ve been for comparison of decompilers for quite some time.

      my conclusion from reading this article is that, except for ability to export decompiled code, any of them will do and its a matter of personal preference

      BTW, Devexpress introduced decompiler as part of CodeRush in v12.2.

    14. Pingback: Interesting Things Circa March 2013 - Jon Galloway

    15. Pingback: Decompiling .NET Applications | Sriramjithendra Nidumolu

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>