Why is it so easy to decompile .NET IL-code into source code, compared to decompiling native x86 binaries? (Reflector produces quite good source code most of the time, while dec
I think you've got the most important bits already.
There are a number of things that make reverse engineering il fairly easy.
Type information. This is massive. In x86 assembler, you have to infer the types of variables based on how they are used.
structure. Information on the structure of the application is more available in il disassemblies. This, combined with type information, gives you an amazing amount of data. You're working at a pretty high level at this point (relative to x86 assembler). In native assembler, you have to infer the structure layouts (and even the fact that they are structures) based on how the data is used. Not impossible, but much more time consuming.
names. Knowing the names of things can be useful.
These things, combined, means you have quite a lot of data about the executable. Il is basically working at a level much closer to the source than a compiler of native code would be. The higher level the bytecode works at, the easier reverse engineering is, generally speaking.
Extending Brian's correct answer
If you think all IL is easily decompilable, I suggest writing a non-trivial F# program and attempting to decompile that code. F# does a lot of code transformations and hence has a very poor mapping from the actual emitted IL and the original code base. IMHO, it is significantly more difficult to look at decompiled F# code and get back the original program than it is for C# or VB.Net.
C# and IL nearly map one-to-one. (This is less so with some newer C# 3.0 features.) The closeness of the mapping (and the lack of an optimizer in the C# compiler) makes things so 'reversible'.