NDepend

Improve your .NET code quality with NDepend

In the Jungle of .NET Decompilers

In the Jungle of .NET Decompilers

C#, VB.NET and F# code gets compiled to IL code. IL stands for Intermediate Language. IL code is intermediate in the sense it sits between high level language like C# and low-level assembly language executed by the CPU. Consequently IL is much less human-readable than C# code and much more human-readable than assembly code. This is why one needs a .NET Decompiler tool: to obtain readable C# code from compiled IL code.

In this article are listed all .NET Decompilers you might want to use along with their pros and cons. To ease comparison, for each decompiler a screenshot of the decompiled method ScreenToGif App_Startup() is provided. Also the title of each section highlights main fact: free/commercial, oss or not and which decompilation language target is supported.

Now let’s list the tools.

ILSpy for everyone   [free  OSS  C# IL  multi-platforms]

ILSpy is the de-facto .NET Decompiler. You can install it from the Microsoft Store.

  • It’s open-sourced on github.
  • It was started in 2011 and is nowadays fully mature,
  • It has all features you might wish when decompiling one or several assemblies: search a symbol, open a pre-saved list of assemblies, hyperlink navigation between symbols, assembly metadata explorer..
  • A console version, ilspycmd, can automate decompilation.
  • It can generate a PDB from an assembly. A PDB file, often referred as symbol file, is a bridge between an assembly’s IL code and its corresponding project’s source code. PDB is primarily used by debuggers to locate position in source code corresponding to the currently executed IL instruction. It means that with ILSpy PDB generation, one can debug the decompiled source code as explained in this stackoverflow answer.
  • It runs seamlessly on Mac and Linux thanks to AvaloniaILSpy. This is not the case for other decompilers listed after.
  • It integrates within Visual Studio and within VSCode (although the VS code version seems to have problems from the comments).

ILSpy is actually so mature that Visual Studio itself relies on it to generate source code from .NET assemblies while debugging. You can also read Decompilation of C# code made easy with Visual Studio. This is a great feature when you don’t have access to source code of a library that your code is consuming (the black-box syndroma). However it is not recommended to reference closed-source libraries as explained in the fifth lesson of 5x Lessons Learned from Migrating a Large Legacy to .NET 5/6.

ILSpy-Dotnet-Decompiler

dotPeek for convenient decompilation   [free  C# IL]

dotPeek is the free decompiler by Jetbrains. It runs as standalone and is also naturally integrated within Resharper and thus, within Visual Studio. It is the .NET Decompiler I regularly use. It has ILSpy features listed above. What makes it more convenient to me is:

  • ILSpy search and navigation are great but imagine having the Resharper super-polished search and navigation features on decompiled code. It’s what you get with dotPeek!
  • I find the IL Viewer panel (see the screenshot below) very useful. For each C# decompiled statement, the IL Viewer panel highlights the corresponding IL instructions. To us this is very useful because we include IL Offset into our production stack traces. Thus with the dotPeek IL Viewer we can quickly assess the culprit C# line from a production crash. Notice that ILSpy has a “IL with C#” decompilation mode, where each C# statement is shown as a comment preceding its corresponding group of IL instructions, but I find it less convenient than IL Viewer.
  • I like the dotPeek Process Explorer. It is quite convenient to spy any running process, list its .NET assemblies loaded and decompile any of those assemblies in a click.

dotPeek has a downside though: on my beefy machine it takes 9 seconds to start. I guess it shares a lot of DLLs with Resharper that notoriously slows down Visual Studio startup. On the same beefy machine Visual Studio 2022 takes 11 seconds to open the 160 projects & 4.200 classes of the OrchadCore solution. Despite this pesky slow-down dotpeek remains my regular .NET Decompiler.

dotPeek-Dotnet-Decompiler

dnSpy for gurus and hackers   [free  OSS  C# VB IL]

dnSpy is the .NET Decompiler used by .NET gurus and hackers that want to have a bit-perfect control over a .NET assembly. dnSpy is open-sourced on github and is now (November 2021) maintained under the dnSpyEx branch. Just download the latest release to try it straight.

The screenshot below shows all the assembly metadata tokens and offsets that the mere-mortal .NET developer don’t need. Actually dnSpy is much more than a decompiler. It can also run and debug a compiled assembly as shown by the screenshot below. The breakpoint I set with F9 is just hit 2 seconds after pressing F5 to start debugging. What’s impressing is that the PDB generation step explained above is implicit and very fast. Note that dnSpy can also attach to a running process and debug the decompiled code of its assemblies!

dnSpy-Dotnet-Decompiler

As if it was not enough dnSpy is also an assembly editor. Thus dnSpy supersedes the tool Reflexil developed by my friend Sébastien Lebreton for editing IL.

dnSpy-assembly-edition

The mysterious creator of dnSpy – wtfsck on github – is the Grigori Perelman of decompilation. He/She? is also authoring the x86 (16/32/64-bit) disassembler icedland/iced and also the tool de4net the .NET Deobfuscator. In short for those that protect their IP with a .NET Obfuscator tool, the tool de4net is here to “try its best to restore a packed and obfuscated assembly to almost the original assembly. Most of the obfuscation can be completely restored (eg. string encryption), but symbol renaming is impossible to restore since the original names aren’t (usually) part of the obfuscated assembly.”. This is why when it comes to securing your code, in addition to using an obfuscator I recommend to also have some serious in-house protection!

JustDecompile for everyone  [free  OSS  C# VB IL]  (continued as CodemerxDecompile)

JustDecompile is published by Telerik. JustDecompile is to Telerik what dotPeek is to Jetbrains: a free, powerful and polished .NET Decompiler tool made by a leading tools & components corporation. These companies invested in their free decompilers to build an appealing entry-point to their commercial products. The community benefits from the free tools with the maintenance level of large corporations.

JustDecompile is a polished and fast .NET Decompiler with most features mentioned in IL Spy and a plugins model. Its engine is open sourced on github but hasn’t’ been updated since 2018. Update 17 November 2021: The project has been forked to OSS CodemerxDecompile on github. Here is the official website of CodemerxDecompile where you can download the Windows, Mac and Linux version.

If you wish to decompile to VB.NET and you find the dnSpy tool daunting with all its guru features, then JustDecompile/CodemerxDecompile is the right tool. Also CodemerxDecompile claims being the fastest .NET decompiler (I didn’t verified) so if you need performance it might also be the right choice.

JustDecompile-Dotnet-Decompiler

IldAsm for nostalgia  [free IL]

IldAsm.exe is the first .NET Decompiler ever. It was provided by Microsoft since .NET 1.0. Actually it doesn’t decompile but just produces textual IL code from the binary IL code in a DLL. I used it extensively when I was learning in-depth .NET in the 2002-2003 years. I really felt some nostalgia when producing this screenshot 🙂

ildasm-Dotnet-Decompiler

.NET Reflector for history   [commercial unsupported  C# VB IL MC++]

.NET Reflector by Red-Gate is the only both commercial and unsupported .NET Decompiler in this list. With its Buy Now button on its main page it doesn’t look unsupported but in January 2021 I got this answer from the Red-Gate support: “.NET reflector is an unsupported tool. Support for .NET Reflector is limited to our help center and we encourage you to post on the Forum.”

Why mentioning .NET Reflector then since it cannot compete by any mean with the free, supported and powerful tools already listed? Because .NET Reflector is the father of all .NET Decompilers – and even dare I say – the father of most non Microsoft .NET tools. The short history of .NET Reflector is worth reading:

.NET Reflector was originally developed by Lutz Roeder as freeware. Its first version can be tracked back to July 2002, two decades ago during .NET infancy! Lutz is a seasoned Microsoft engineer and researcher that developed the tool on its spare time. .NET Reflector was a super popular tool and it was acquired by Red-Gate in August 2008. Reg-Gate is a leading DB tool vendor that also proposes tools for .NET developers. They promised “to continue to offer the tool for free to the community” and only charge for new features. Unfortunately they broke their promises: in February 2011 they ran into a storm of protest when charging for .NET Reflector. This led to the creation of several free alternatives, including dotPeek, JustDecompile and ILSpy.

Sad story that at least, led to a plethora of high-quality free decompilers which is great.

.NET-Reflector-Dotnet-Decompiler

NDepend to go beyond decompilation

I created NDepend in April 2004 as a small OSS project to compute some Robert C. Martin metrics on .NET projects to show clients when consulting. The tool was popular enough to create a commercial version in February 2007 and commit to it full-time. The tool evolved a lot and nowadays it is still fully supported and up-to-date with latest .NET technologies.

NDepend is not a decompiler like the ones presented above. Its main source of data are assemblies themselves but it can also read PDB files, source files, .csproj/.sln files and even code coverage files produced by various coverage technologies. The tool analysis all this data to build a rich and queryable model of your .NET assets. Based on this model numerous features and use-cases are proposed:

An NDepend full-featured trial can be download to assess your .NET code quality and structure or reverse-engineer any mysterious .NET DLL. Here the dependency diagram obtained in 7 seconds (analysis + graph layout) from the ScreenToGif.exe assembly.

ndepend-dotnet-decompiler

Conclusion

I hope this post was useful to you to decide which .NET Decompiler suits you best and maybe change your habits. Each tool is mature and has its enthusiast users. Probably you’ll end-up using ILSpy or dotPeek, or maybe dnSpy if you have a need for bit-level details. I explained why dotPeek is the .NET Decompiler tool I use regularly. This is genuine and I am not affiliated with Jetbrains, the editor of dotPeek, which is free anyway.

But, wait a minute…

Is decompiling legal?

The short answer is: Yes unless explicitly prohibited. For example the dotPeek License Agreement states that: “Before using dotpeek for decompilation purposes, you should make sure that decompilation of binary code is not prohibited by the applicable license agreement (except to the extent that you may be expressly permitted under applicable law) or that you have obtained permission to decompile the binary code from the copyright owner.”

This stackoverflow answer proposes a more liberal discourse:

“Decompiling is absolutely LEGAL, regardless of what the shills say. At most, you can be sued for unauthorized activity relating to software unless you’re redistributing it. Courts in the U.S. have always upheld the right of users to know exactly what code is being installed on their systems by programs they have legitimately obtained.

People REALLY need to quit saying “ILLEGAL” unless they know what they’re talking about. There is absolutely NO law in the U.S. that states you cannot copy for private purposes or decompile software. Companies have tried to sue to stop it, but; a) that’s only civil, not criminal, and therefore not ILLEGAL; and b) they’ve only won when the content was given to an outside party from whom the companies did not receive payment. IE the person has been shown to break the law.”

Nevertheless a comment on the same question says: “It is, however, illegal if you decode it, take all the source code, maybe change the graphics, package and some other things and try to pass it off as your own app. It is illegal redistribution of a copyrighted work.”

.NET Obfuscators exist since technically nothing prevents anyone to reverse-engineer your intellectual property. But understand that obfuscators and custom tricks cannot protect your IP from a determined hacker. At best, you can make the hacker’s life (much) more difficult. The only way to really protect your IP is to propose your services through a cloud or web-based approach, where your bits never leave your own server.

 

 

 

My dad being an early programmer in the 70's, I have been fortunate to switch from playing with Lego, to program my own micro-games, when I was still a kid. Since then I never stop programming.

I graduated in Mathematics and Software engineering. After a decade of C++ programming and consultancy, I got interested in the brand new .NET platform in 2002. I had the chance to write the best-seller book (in French) on .NET and C#, published by O'Reilly and also did manage some academic and professional courses on the platform and C#.

Over my consulting years I built an expertise about the architecture, the evolution and the maintenance challenges of large & complex real-world applications. It seemed like the spaghetti & entangled monolithic legacy concerned every sufficiently large team. As a consequence, I got interested in static code analysis and started the project NDepend.

Today, with more than 12.000 client companies, including many of the Fortune 500 ones, NDepend offers deeper insight and full control on their application to a wide range of professional users around the world.

I live with my wife and our twin kids Léna and Paul in the beautiful island of Mauritius in the Indian Ocean.

Comments:

  1. Nice article Patrick, very useful, thank you.
    Perhaps you have some ideas to share regarding to kinds of those custom protection tricks?

Leave a Reply

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