Writing a Simple Decompiler for .NET, Part 1
codeandux.com
codeandux.com
ILSpy: https://github.com/icsharpcode/ilspy
JustDecompile: https://github.com/telerik/JustDecompileEngine/
Both are based on the same library that is used in the post: Mono.Cecil (https://github.com/jbevain/cecil).
ldc.i4.4
ldarg.0
call System.Int32 Test1.AwesomeClass::c()
starg.s b
starg.s a
The right way to decompile a stack-based language requires keeping track of what's on the stack, building expressions instead of evaluating values.That InstructionHelper class also looks like it could be rewritten more clearly...
There's also no discussion of type inferencing for variables, parenthesizing expression DAGs properly. I suspect properly decompiling control flow would be in part 2, but I'd be surprised if that were anywhere near robust, based on the quality demonstrated so far. Which is sad because this sort of decompilation has been practically demonstrated and solved for, oh, 10-20 years.
Haha, yep I do agree that I did not cover all important aspects of writing a decompiler. Neither did I use a stack based solution to tackle the problem.
A reminder though, the idea behind this post was to cover a little bit of everything, just trying to make it as simple as possible. This is not a fully fledged decompiler and will not decompile everything. It is to give an idea on how CIL works, how to use Mono.Cecil, and just hacking away!
Next part of the tutorial DO actually manage the stack to try and create a more complex solution. Together with code refactoring and more.
And I'm sorry for any information that I've might have forgotten and/or for any poorly written code. I will try and do better next time. Yet I hope you still like the article.
/zerratar
It also pays well to have distinct basic blocks - loop analysis is much easier then.
Again this is more about my lack of confidence about fully grokking the implications of SSA; I'm not nerd-sniping.
Another thing you'll get for free from an SSA - nice ternary expressions reconstructed (even if the original code was using ifs).