简体   繁体   中英

Mono.Cecil: cannot see child class

Say I have a class B that derives from the class A

B : A

When reading from the assembly using Mono.Cecil I can see A (the parent class) but I cannot see B.

 AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(pathfile);
foreach (TypeDefinition type in assembly.MainModule.Types)
        {   
            foreach (MethodDefinition method in type.Methods)
            {
                Mono.Cecil.Cil.MethodBody mybody = method.Body;

                if (mybody != null)
                {
                    foreach (Mono.Cecil.Cil.Instruction ins in mybody.Instructions)
                    { // do stuff
}}}}

My test program output is then pathfile - in the above code - and looks like this:

    static void Main(string[] args)
    {
        using (var aes = System.Security.Cryptography.AesManaged.Create())
        {
            aes.GenerateKey();
        }
    }

In that example, I can see the class AES (parent class), but not the AESManaged one (child class). https://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged(v=vs.110).aspx

Your specific question should really be why this piece of code:

static void Main(string[] args)
{
    using (var aes = System.Security.Cryptography.AesManaged.Create())
    {
        aes.GenerateKey();
    }
}

Compiles to the following IL:

IL_0000:  call        System.Security.Cryptography.Aes.Create
IL_0005:  stloc.0     // aes
IL_0006:  ldloc.0     // aes
IL_0007:  callvirt    System.Security.Cryptography.SymmetricAlgorithm.GenerateKey
IL_000C:  leave.s     IL_0018
IL_000E:  ldloc.0     // aes
IL_000F:  brfalse.s   IL_0017
IL_0011:  ldloc.0     // aes
IL_0012:  callvirt    System.IDisposable.Dispose
IL_0017:  endfinally  
IL_0018:  ret         

(Note: no mention of AesManaged anywhere.)

This happens because AesManaged doesn't have a static method named Create , Aes does. The C# compiler lets you call this method by referencing the derived class, but on the IL level, the method is part of Aes and Aes only. For the same reason, aes.GenerateKey() is compiled as a call to the method SymmetricAlgorithm.GenerateKey , since that's where the method's actually defined. (This is true even though AesManaged overrides this method.)

Now, what you want do to do with this depends on your scenario. If your objective is to get the class references as they are actually used by the IL, then your existing code does what you want. If, on the other hand, you want to get the references as they are in the source code, you'll have to use another method (like analyzing it with Roslyn).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM