MSIL methods that do not require ret

I recently played with MSIL and compiled it with ilasm when I noticed that this method requires the ret command to return from the end of the method; For example, I should write code like this:

.method static void Main() { .entrypoint ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string) ret //I am returning properly } 

However, if I omit ret, the code still works and displays "Hello World!". perfectly. At first, I thought it might be specific to the entrypoint method, but ilasm happily compiles this code without warnings and errors:

 .assembly Program{} .assembly extern mscorlib{} .method static void Main() { .entrypoint ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string) ldstr "Foo returned: {0}!" call int32 Foo() box int32 call void [mscorlib]System.Console::WriteLine(string, object) } .method static int32 Foo() { ldstr "Hello from Foo!" call void [mscorlib]System.Console::WriteLine(string) ldstr "GoodBye!" call void [mscorlib]System.Console::WriteLine(string) ldc.i4 42 } 

Note that neither Main () nor Foo () have return statements. Foo () even has a return value! When this code compiles and runs, I get the following output:

Hello World! Hello from Foo! Goodbye! Foo is back: 42!

The program also exits normally. Then I thought that perhaps ilasm automatically inserts ret statements, but after viewing the program using ildasm, the methods were identical with the code above ie without returning.

Curiously, when I tried to decompile the method using DotPeek, it refused to replace both bodies of the method with // ISSUE: unable to decompile the method.

If I add ret statements and recompile DotPeek, both methods can be decompiled without problems.

Can someone explain what is going on here?

+6
source share
1 answer

I think this is due to the fact that the CLR sometimes accepts an IL that is invalid, and only when it encounters an IL that it cannot actually execute does it throw an InvalidProgramException . I assume this is done for performance reasons: checking that the IL follows all the rules will be too slow.

If you want to verify that your IL is valid, you must use PEVerify on it.

And when you have the wrong code, it is not surprising that some tools, such as DotPeek, cannot handle it.

+5
source

Source: https://habr.com/ru/post/951949/


All Articles