samedi 12 mai 2018

Can I access method bodies (e.g. IL byte array) using Assembly.TryGetRawMetadata and System.Reflection.Metadata?

.NET Core 2's FCL includes an extension method Assembly.TryGetRawMetadata which one can use to inspect a loaded assembly's metadata using System.Reflection.Metadata.

I'd like to use these facilities to inspect method bodies (like I would with regular Reflection's MethodBody), but that doesn't appear to be possible.

using System.Reflection;
using System.Reflection.Metadata;

class Program
{
    unsafe static void Main()
    {
        var thisAssembly = Assembly.GetExecutingAssembly();
        if (thisAssembly.TryGetRawMetadata(out byte* rawMetadata, out int rawMetadataLength) == false)
        {
            return;
        }

        var metadata = new MetadataReader(rawMetadata, rawMetadataLength);

        foreach (var methodDefinitionHandle in metadata.MethodDefinitions)
        {
            var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle);
            var methodRVA = methodDefinition.RelativeVirtualAddress;
            … // Question: Is there any way to get to the method body from `methodRVA`? 
        }
    }
}

I can get at methods' RVAs, but since I have no way of finding out what RVA the rawMetadata pointer corresponds to, I appear to have no way of dereferencing these RVAs.

AFAIK, Assembly.TryGetRawMetadata returns only a data blob starting at the metadata root (BSJB) and including the metadata streams and heaps, but method bodies are actually stored outside of this data.

Of course I could just start by inspecting the whole assembly file (whose path is given in thisAssembly.Location), but that would require re-loading it into memory a second time.

Does Assembly.TryGetRawMetadata really not allow me to get at the method bodies, or am I overlooking something?






Aucun commentaire:

Enregistrer un commentaire