Search code examples
c#reflectionsystem.reflectionmono.cecil

Mono.Cecil - simple example how to get method body


I have been searching for a newbie question, but can't find a simple example. Can anyone give me a simple example how to get MethodBody into most available string result? Like:

using Mono.Cecil;
using Mono.Cecil.Cil;

namespace my
{
    public class Main
    {
        public Main()
        {
             // phseudo code, but doesnt work
            Console.Write(    getMethod("HelloWorld").GetMethodBody().ToString()   );
        }

        public void HelloWorld(){
             MessageBox.Show("Hiiiiiiiiii");
        }
    }
}

Solution

  • Start with reading your assembly:

    var path = "... path to your assembly ...";
    var assembly = AssemblyDefinition.ReadAssembly(path);
    

    You can use System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName as path if you want to open running process

    Now get all types and methods wich you want to inspect

    var toInspect = assembly.MainModule
      .GetTypes()
      .SelectMany(t => t.Methods
          .Where(m => m.HasBody)
          .Select(m => new {t, m}))
      
    

    If you already knew type and method names you can modify your query something like this:

    toInspect = toInspect.Where(x => x.t.Name.EndsWith("Main") && x.m.Name == "HelloWorld");
    

    After that just iterate over that collection:

    foreach (var method in toInspect)
    {
        Console.WriteLine($"\tType = {method.t.Name}\n\t\tMethod = {method.m.Name}");
        foreach (var instruction in method.m.Body.Instructions)
            Console.WriteLine($"{instruction.OpCode} \"{instruction.Operand}\"");
    }
    

    Output will be

    Type = Main
      Method = HelloWorld
    
    ldstr "Hiiiiiiiiii"
    call "System.Windows.Forms.DialogResult System.Windows.Forms.MessageBox::Show(System.String)"
    pop ""
    ret ""