Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a decompiled assembly not look exactly like the C# used to compile it? [closed]

Tags:

c#

I lost the original project containing my code, but I still had the assembly so I decided to decompile it using DotPeek. The following code resulting from that caught my eye:

int num1 = 1;
saveFileDialog1.OverwritePrompt = num1 != 0;

Why does it use that convoluted code instead of this?

saveFileDialog1.OverwritePrompt = true;
like image 456
HyunMi Avatar asked May 27 '16 21:05

HyunMi


1 Answers

   What you show here is just an artifact of using dotPeek to decompile the MSIL code in the assembly back into C#. Certain language constructs within C# get re-written by the compiler into something completely different upon compilation, often involving goto statements (foreach loops and LINQ statements, for example). If a decompiler program were to just translate the MSIL into C# verbatim, the resulting C# code would often be unrecognizable. Therefore, any decent, or non-trivial, decompiler will recognize these constructs and, instead of providing the literal translation, will instead replace, say a loop using goto's, with a foreach loop or the LINQ equivalent instead, in order to produce something a lot closer to the original C# code that produced that IL.

   This is no easy task! The number of cases that must be accounted for is quite numerous, and ever-growing as Microsoft adds new classes to the framework. Its quite impressive that these things do as good of a job as they do, considering. You will get different mileage in this respect from different decompilers, and different decompilers will produce different C# code given the same IL. However (in theory), they should all produce code that is the same, functionally.

   The single best (free) decompiler I have come across (by a long shot) thus far is ILSpy (available at ILSpy.net). This tool is open source (!), and was written (I believe) by the same person who wrote SharpDevelop (an open source IDE that is an alternative to Visual Studio). ILSpy goes a long way to reversing MSIL into the original C# constructs that we are all familiar with, including most LINQ statements. The number of cases ILSpy handles is breathtaking, considering the development is (assumably) done by just one person. ILSpy also can go from MSIL to VB .NET, but I believe most of the magical translations from generated IL code back to the original VB .NET code constructs that would produce such IL code remain unimplemented. There is only one time I have ever seen ILSpy do the wrong thing (really deeply nested if statements leading to insane arrow code, I'm talking hundreds of if statements deep), and I have no idea what the original C# code was that produced such a mess (it was some maths/drawing code that came from the game Terraria that I was decompiling).

   You can read on his blog about how he implemented some of the ILSpy features.

   I encourage you to try ILSpy and see if that doesn't produce more sensible code for you. Even still, you almost certainly will find some code that you wish to alter or rewrite after decompilation, so that you are happy with it. I had to decompile a module after a terrible visual studio bug ate the original code, a situation that could have been avoided by checking in my code more frequently. I definitely remember having to go through and clean up the code a bit, remove redundancies and make changes to the code that made most sense to me. In addition, you may find that you like the way different decompilers handler different sections of code, and may end up using a blend of different debugger's output to achieve a version of the code that you are comfortable with.

like image 189
Adam White Avatar answered Oct 21 '22 12:10

Adam White