Dynamically replace the contents of a C# method?

后端 未结 10 2472
面向向阳花
面向向阳花 2020-11-22 16:09

What I want to do is change how a C# method executes when it is called, so that I can write something like this:

[Distributed]
public DTask Solve         


        
10条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-22 16:20

    You CAN modify a method's content at runtime. But you're not supposed to, and it's strongly recommended to keep that for test purposes.

    Just have a look at:

    http://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time

    Basically, you can:

    1. Get IL method content via MethodInfo.GetMethodBody().GetILAsByteArray()
    2. Mess with these bytes.

      If you just wish to prepend or append some code, then just preprend/append opcodes you want (be careful about leaving stack clean, though)

      Here are some tips to "uncompile" existing IL:

      • Bytes returned are a sequence of IL instructions, followed by their arguments (if they have some - for instance, '.call' has one argument: the called method token, and '.pop' has none)
      • Correspondence between IL codes and bytes you find in the returned array may be found using OpCodes.YourOpCode.Value (which is the real opcode byte value as saved in your assembly)
      • Arguments appended after IL codes may have different sizes (from one to several bytes), depending on opcode called
      • You may find tokens that theses arguments are referring to via appropriate methods. For instance, if your IL contains ".call 354354" (coded as 28 00 05 68 32 in hexa, 28h=40 being '.call' opcode and 56832h=354354), corresponding called method can be found using MethodBase.GetMethodFromHandle(354354)
    3. Once modified, you IL byte array can be reinjected via InjectionHelper.UpdateILCodes(MethodInfo method, byte[] ilCodes) - see link mentioned above

      This is the "unsafe" part... It works well, but this consists in hacking internal CLR mechanisms...

提交回复
热议问题