0

I need to enumerate all methods in a .NET module and check if they have tiny or fat header. I decided to use the powerful dnlib .NET modules handling library.

There is a dnlib.DotNet.Writer.MethodBody class that indicates the tiny/fat method header (see IsTiny() and IsFat()). However, I have no idea how to access this class.

The class is located in the Writer namespace - let's use the Writer Listener:

    public void OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt)
    {

Note that it's easy to enumerate all methods and get the other MethodBody, the one in Emit namespace:

        foreach (TypeDef type in module.GetTypes())
        {
            foreach (MethodDef method in type.Methods)
            {
                dnlib.DotNet.Emit.MethodBody body = method.MethodBody;
            }
        }
    }

Unfortunately this class doesn't reveal anything useful. I believe something similar to the following pseudocode should work:

    public void OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt)
    {
        foreach (TypeDef type in module.?)
        {
            foreach (? method in type.?)
            {
                dnlib.DotNet.Writer.MethodBody body = method.?;
            }
        }
    }
MazeGen
  • 180
  • 3
  • 14
  • I am genuinely curious why do you even need this? – Andrey Jul 03 '15 at 11:31
  • @Andrey It's something quite unusual: As a part of an advanced obfuscator, I need to rewrite instructions in the methods so that they run only with a customized .NET runtime. Because I'm used to dnlib, and because dnlib doesn't know my instructions, and because it would be too complicated to implement my own instructions to dnlib, I decided to do this at the binary level. To get offset of first instruction in a method, the length of method body header must be known. Since the length is not available, I need to know the type of the header. – MazeGen Jul 03 '15 at 12:02
  • @Andrey Did you delete your answer? I believe it might be useful for someone... – MazeGen Jul 03 '15 at 12:07
  • yeah I deleted it because it was wrong, because build-in .net reflection can only return method body and no way to get header out of it. – Andrey Jul 03 '15 at 12:12
  • To answer your question you need to fiddle with dnlib, I couldn't find any meaningful documentation how to get method header. But I saw it in the sources, so it is there somewhere. – Andrey Jul 03 '15 at 12:13

1 Answers1

0

After fiddling with dnlib I figured that they don't really expose method headers, flags or raw method bytes. Using their own code I managed to read the header myself:

class MainClass
{
    public static void TestMethod() {
        return;
    }

    public static void Main (string[] args)
    {
        // Load mscorlib.dll
        string filename = typeof(void).Module.FullyQualifiedName;
        ModuleDefMD mod = ModuleDefMD.Load(Assembly.GetExecutingAssembly().Location);

        foreach (TypeDef type in mod.GetTypes()) {
            Console.WriteLine("Type: {0}", type.FullName);

            foreach (var method in type.Methods) {
                using (var reader =  mod.MetaData.PEImage.CreateFullStream()) {
                    reader.Position = (long)mod.MetaData.PEImage.ToFileOffset(method.RVA);
                    var flags = reader.ReadByte ();
                    Console.WriteLine (" Method: {0}, Tiny: {1}", method.Name, (flags & 3) == 2);
                }
            }
        }
        Console.WriteLine();
    }
}
Andrey
  • 59,039
  • 12
  • 119
  • 163