// Run the decompiler on the given type.
        private IRClass DecompileClass(TypeDefinition type)
        {
            // Proceed to next type if it's already known.
            IRClass reconstructed;

            _classCache.TryGetValue(type, out reconstructed);
            if (reconstructed != null)
            {
                return(reconstructed);
            }

            var decompiler = new ILDecompiler(type);

            // Create a list to keep track of all referenced types.
            List <TypeDefinition> references;

            decompiler.Decompile(out references);
            // Store all references to analyze them later.
            _referencedTypes.AddRange(references);

            // Retrieve the reconstructed IR.
            reconstructed = decompiler.ConstructIRClass();

            // Add the IR class to the cache.
            // This must happen BEFORE decompiling private types and references,
            // because otherwise causes (possibly) an infinite loop.
            _classCache[type] = reconstructed;

            // Also handle the private types of the subject.
            DecompilePrivateTypes(type, type);

            return(reconstructed);
        }
        // Run the decompiler on the given type.
        private IREnum DecompileEnum(TypeDefinition type)
        {
            IREnum reconstructed;

            _enumCache.TryGetValue(type, out reconstructed);
            if (reconstructed != null)
            {
                return(reconstructed);
            }

            // Decompile the enum..
            ILDecompiler decompiler = new ILDecompiler(type);

            List <TypeDefinition> references;

            decompiler.Decompile(out references);
            // An enum does NOT make references to other types.

            // Retrieve the reconstructed IR.
            reconstructed = decompiler.ConstructIREnum();

            // Add IR enum to the cache
            _enumCache[type] = reconstructed;

            return(reconstructed);
        }
Пример #3
0
 private void GatherTypesFrom(MethodBase method)
 {
     if (this.assemblies.Contains(method.DeclaringType.Assembly))     // only consider methods we've build ourselves
     {
         MethodBody methodBody = method.GetMethodBody();
         if (methodBody != null)
         {
             // Handle local variables
             foreach (var local in methodBody.LocalVariables)
             {
                 EnsureType(local.LocalType);
             }
             // Handle method body
             var il = methodBody.GetILAsByteArray();
             if (il != null)
             {
                 foreach (var oper in ILDecompiler.Decompile(method, il))
                 {
                     if (oper.Operand is MemberInfo)
                     {
                         foreach (var type in HandleMember((MemberInfo)oper.Operand))
                         {
                             EnsureType(type);
                         }
                     }
                 }
             }
         }
     }
 }
Пример #4
0
        private void AnalyzeAssembly(AssemblyDefinition assembly)
        {
            // All analyzable types can be found at the main module of the assembly.
            var module = assembly.MainModule;
            // Fetch all analyzable types.
            var types = module.Types.Where(t => ILDecompiler.MatchDecompilableClasses(t) || this.MatchIncludedEnum(t));

            // Sort all types in ascending order.
            // This forces parent types to always be processed before nested types!
            types.OrderBy(x => x.FullName);
            // Decompile all types.
            foreach (var type in types)
            {
                // Decompile the type to IR, see DecompileClass(..).
                if (type.IsEnum)
                {
                    DecompileEnum(type);
                }
                else
                {
                    DecompileClass(type);
                }
            }
        }