C # IL code editing - maintain stack integrity

This question is about static analysis of stacks of custom C # IL code and how to create opcodes to satisfy the compiler.

I have code that modifies existing C # methods by adding my own code to it. To avoid the original method, return to my code, it replaces all the code RET symbol BR endlabel and adds this mark the end of the source code. Then I add more code and finally RET.

Everything works fine, but it doesn’t work on certain methods. Here is a simple example:

public static string SomeMethod(int val)
{
    switch (val)
    {
        case 0:
            return "string1".convert();
        case 1:
            return "string2".convert();
        case 2:
            return "string3".convert();
        // ...
    }
    return "";
}

which is represented by this IL code:

.method public hidebysig static string SomeMethod(int32 val) cil managed
{
    .maxstack 1
    .locals val ([0] int32 num)
    L_0000: ldarg.0 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: switch (L_002e, L_004f, L_0044, ...)
    L_002c: br.s L_0091
    L_002e: ldstr "string1"
    L_0033: call string Foo::convert(string)
    L_0038: ret 
    L_0039: ldstr "string2"
    L_003e: call string Foo::convert(string)
    L_0043: ret 
    L_0044: ldstr "string3"
    L_0049: call string Foo::convert(string)
    L_004e: ret 
    ... 
    L_0091: ldstr ""
    L_0096: ret 
}

After changing my program, the code looks like this:

.method public hidebysig static string SomeMethod(int32 val) cil managed
{
    .maxstack 1
    .locals val ([0] int32 num)
    L_0000: ldarg.0 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: switch (L_002e, L_004f, L_0044, ...)
    L_002c: br.s L_0091
    L_002e: ldstr "string1"
    L_0033: call string Foo::convert(string)
    L_0038: br L_009b // was ret 
    L_0039: ldstr "string2"
    L_003e: call string Foo::convert(string)
    L_0043: br L_009b // was ret 
    L_0044: ldstr "string3"
    L_0049: call string Foo::convert(string)
    L_004e: br L_009b // was ret 
    ... 
    L_0091: ldstr ""
    L_0096: br L_009b // was ret
    L_009b: my code here
    ...
    L_0200: ret
}

and I get a compilation error:

post-long-event. : System.TypeInitializationException: FooBar --- > System.InvalidProgramException: IL ( -) Foo: SomeMethod (int): IL_0000: ldnull

RET ?

+6
1

, , BR RET .

, , "_S" . :

+3

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


All Articles