19 Jun 2015

Weirdness of C# compiler

I've been quite busy lately. I made OMF file template I promised few weeks ago, found a remote code execution vulnerability in One Big Company's product and spent some time breaking keygenme by li0nsar3c00l. I'll make a blog post about most of these findings sooner or later.

But today I want to show you something that made me go WTF..

I needed to see how the loop "while true do nothing" looks like in IL. Since C# compiler and .NET JIT compiler are quite smart and optimize code that's certainly an eternal loop, I needed to get creative:

Nothing fancy, but C# & JIT compiler don't track param values, so they both generate proper code..

Well, I thought it's a proper code, until I looked at generated MSIL:

WTF WTF WTF? Can anyone explain to me why there are 2 ceq instructions?

I could understand extra nop and stloc/ldloc instructions, but that ceq completely blows my mind.. And it's the same for .NET 2.0 and 4.5 compilers.

4 thoughts on “Weirdness of C# compiler

  1. Just my comment, nothing fo prooving this. I assume, the concept behind is:
    IL_0005: ldarg.0
    IL_0006: ldc.i4.0
    IL_0007: ceq
    this is your comparison, as written in code.

    (stack)
    IL_0009: ldc.i4.0
    IL_000a: ceq
    this is the boolean comparison for the loop, to make sure eigher 0 or 1 is on stack. The storing of the result is quite unnecessary.

    i dont understand eigher, why the whole code haven't been optimized.

  2. Well, the entire 2nd part is unnecessary. MSIL has a wonderful "brfalse" opcode, I really don't understand why it's not used here.. ;) Something like this:

Leave a Reply

  • Be nice to me and everyone else.
  • If you are reporting a problem in my tool, please upload the file which causes the problem.
    I can`t help you without seeing the file.
  • Links in comments are visible only to me. Other visitors cannot see them.

Your email address will not be published.

 +  six  =  eight