// 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); }
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); } } } } } } }
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); } } }