Looking to reverse engineer or disassemble some .NET code? Then learning how to decompile .NET assemblies is a an essential skill for any .NET developer or security engineer. Fortunately, there are many .NET decompiling tools available.
This article lists all .NET Decompilers along with their pros and cons to help you choose the best one that meets your needs. 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.
- ILSpy for everyone [free OSS C# IL multi-platforms]
- dotPeek for convenient decompilation [free C# IL]
- dnSpy for gurus, security and hackers [free OSS C# VB IL]
- JustDecompile for everyone [free OSS C# VB IL] (continued as CodemerxDecompile)
- IldAsm for nostalgia [free IL]
- .NET Reflector for history [paid unsupported C# VB IL MC++]
- NDepend to go beyond decompilation
What does it mean to decompile .NET code?
C#, VB.NET and F# code gets compiled to IL code. A DLL file is produced by the compilation of a .NET project (csproj, vbproj…). A DLL file is a binary file that contains IL code compiled with an efficient binary format. IL stands for Intermediate Language. IL code is intermediate in the sense it sits between high level language like C# and low-level native code executed by the CPU. Consequently IL is much less human-readable than C# code and much more human-readable than native code.
When you write code in C#, VB.NET, or F#, it gets compiled into IL code, which stands for Intermediate Language. This IL code is then stored in a DLL file. A DLL is a binary file that contains the IL code compiled in an efficient binary format. While IL is less human-readable than C# code, it’s still more human-readable than the low-level native code that the CPU executes.
At runtime the the IL code within the DLLs is compiled by the JIT compiler to native code. The native code is then directly executed by the CPU. JIT stands for Just-In-Time: JIT compiling means that the IL code of a method is compiled to native code only when the method is called for the first time at runtime.
Here is the .NET compilation process illustrated:
The .NET Decompilation process is the reverse of C# Compilation. This is why one needs a .NET Decompiler tool: to obtain readable C# source code from compiled IL code.
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).
- Since ILSpy version 8 it runs on .NET 6.0 compared to .NET Framework 4.7.2 for previous versions.
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 syndrome). However it is not recommended to reference closed-source libraries from your code as explained in the fifth lesson of 5x Lessons Learned from Migrating a Large Legacy to .NET 5/6.
Later in the present article we explain how NDepend and ILSpy can collaborate to achieve powerful decompilation actions like:
- Decompiling an entire assembly
- Decompiling two versions of an assembly and diff the results
- Generate dependency graph directly from the ILSpy element right-click menu
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 has ILSpy features listed above plus:
- 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!
- IL Viewer panel (see the screenshot below) is quite 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 10 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.
On a personal note, dotPeek used to be the .NET decompiler I used regularly. But the slow startup led me to use more and more ILSpy that is quite fast, not only for the startup but for decompilation as well. It is also reactive on all commands and has lightweight and convenient redistribution (3MB zipped to xcopy). Now I mostly use ILSpy and keep dotPeek for its Process Explorer and C# + IL Viewer features when needed.
dnSpy for gurus, security and hackers [free OSS C# VB IL]
dnSpy is the .NET Decompiler used by .NET gurus, experts in security and hackers that want to have a bit-perfect control over a .NET assembly. dnSpy is open-sourced on github and is now (March 2023) 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!
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.
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 2019. In 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.
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 🙂
.NET Reflector for history [paid 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 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, fortunate consequences: it led to a plethora of high-quality free decompilers which is great.
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 and IL code 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:
- dependency analysis and code visualization
- quality gate, ruling and technical-debt estimation
- reporting and CI/CD and DevOps integration
- Visual Studio extension and command line tool
- progression against a baseline
- code metrics
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 5 seconds (analysis + graph layout) from the ScreenToGif.exe assembly.
NDepend and ILSpy collaboration: .NET decompilation on steroid
Since version 2022.1.0 NDepend proposes an ILSpy plugin. This way the tools are collaborating both ways:
From NDepend to ILSpy: Just right click any assembly, namespace, class, method or field in NDepend or Visual Studio (with the NDepend extension installed). There are 3 new menus to:
- Select the code element in ILSpy
- Decompile the code element with ILSpy (Target languages: C# and IL)
- Decompile and Compare: the code element is decompiled from both the baseline assembly and the current assembly and both text files obtained are compared. It is possible to decompile large namespaces or even assemblies. This is especially useful to diff two versions of an assembly. If several classes are decompiled, they are aggregated in the text file in a consitent order, which makes the code review of changes possible.
Let’s precise that to compare two sets of assemblies – older bits and newer bits – in order to use the Decompile and Compare menu, just click the Compare 2 versions of a code base link from the NDepend start page. A dialog will let you specify both assemblies sets to compare.
ILSpy is a fast decompiler but C# decompilation of dozens or hundreds of classes can take a few seconds or minutes thus a progress dialog is shown with an Abort button.
From ILSpy to NDepend it is possible to:
- Show any code element on the NDepend dependency graph or matrix
- Analyze with NDepend one or several assemblies selected
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 ILSpy is the .NET Decompiler tool I use regularly and keep dotPeek at hand when needed. This is genuine and I am not affiliated with the ILSpy team nor 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.
Nice article Patrick, very useful, thank you.
Perhaps you have some ideas to share regarding to kinds of those custom protection tricks?
Glad you find the article useful Sergio!
>Perhaps you have some ideas to share regarding to kinds of those custom protection tricks?
I wrote about that in this post. The best you can do is to multiply your in-house & tricky DLL integrity checks to discourage most crackers to lose their time. I wrote about this here:
https://blog.ndepend.com/dont-rely-on-someone-else-to-protect-your-software/
Red Gate got greedy when it charged money for Reflector. I am glad we have free and better alternatives.
Hi Patrick, great writeup! How did you come to know that Grigori Perelman is the creator of dnspy? Dnspy is a perfect production debugger where you can debug any .NET application without source code. I was shocked to see that it was archived but as you pointed out work seems to continue now.
Hi Alois, the reference to Grigori Perelman…
“The mysterious creator of dnSpy – wtfsck on github – is the Grigori Perelman of decompilation.”
… is because I found this project absolutely impressive by ay mean size, feature, performance… and it is free & OSS!!
It reminded me the work done by GP that rejected the prize of one million dollars offered by the Clay institute for having demonstrated the Poincaré conjecture https://en.wikipedia.org/wiki/Grigori_Perelman