コード例 #1
0
ファイル: PortablePdbWriter.cs プロジェクト: haagenson/ILSpy
        public static void WritePdb(PEFile file, CSharpDecompiler decompiler, DecompilerSettings settings, Stream targetStream)
        {
            MetadataBuilder metadata         = new MetadataBuilder();
            MetadataReader  reader           = file.Metadata;
            var             entrypointHandle = MetadataTokens.MethodDefinitionHandle(file.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);

            var hasher             = SHA256.Create();
            var sequencePointBlobs = new Dictionary <MethodDefinitionHandle, (DocumentHandle Document, BlobHandle SequencePoints)>();
            var importScopeBlobs   = new Dictionary <MethodDefinitionHandle, (DocumentHandle Document, BlobHandle ImportScope)>();
            var emptyList          = new List <SequencePoint>();

            foreach (var handle in reader.GetTopLevelTypeDefinitions())
            {
                var type = reader.GetTypeDefinition(handle);
                var name = metadata.GetOrAddDocumentName("ILSpy_Generated_" + type.GetFullTypeName(reader) + "_" + Guid.NewGuid() + ".cs");
                var ast  = decompiler.DecompileTypes(new[] { handle });
                ast.InsertChildAfter(null, new Comment(" PDB and source generated by ICSharpCode.Decompiler " + decompilerVersion.FileVersion), Roles.Comment);
                var sourceText     = SyntaxTreeToString(ast, settings);
                var sequencePoints = decompiler.CreateSequencePoints(ast).ToDictionary(sp => (MethodDefinitionHandle)sp.Key.Method.MetadataToken, sp => sp.Value);
                var sourceCheckSum = hasher.ComputeHash(Encoding.UTF8.GetBytes(sourceText));
                var sourceBlob     = WriteSourceToBlob(metadata, sourceText);

                var document = metadata.AddDocument(name,
                                                    hashAlgorithm: metadata.GetOrAddGuid(HashAlgorithmSHA256),
                                                    hash: metadata.GetOrAddBlob(sourceCheckSum),
                                                    language: metadata.GetOrAddGuid(CSharpLanguageGuid));

                metadata.AddCustomDebugInformation(document, metadata.GetOrAddGuid(DebugInfoEmbeddedSource), sourceBlob);

                foreach (var method in type.GetMethods())
                {
                    var methodDef = reader.GetMethodDefinition(method);
                    if (!sequencePoints.TryGetValue(method, out var points))
                    {
                        points = emptyList;
                    }
                    int             localSignatureRowId;
                    MethodBodyBlock methodBody;
                    if (methodDef.RelativeVirtualAddress != 0)
                    {
                        methodBody          = file.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
                        localSignatureRowId = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetRowNumber(methodBody.LocalSignature);
                    }
                    else
                    {
                        methodBody          = null;
                        localSignatureRowId = 0;
                    }
                    if (points.Count == 0)
                    {
                        sequencePointBlobs.Add(method, (default, default));
コード例 #2
0
ファイル: WholeProjectDecompiler.cs プロジェクト: zer/ILSpy
        IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(Metadata.PEFile module, CancellationToken cancellationToken)
        {
            var metadata = module.Metadata;
            var files    = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td)).GroupBy(
                delegate(TypeDefinitionHandle h) {
                var type    = metadata.GetTypeDefinition(h);
                string file = CleanUpFileName(metadata.GetString(type.Name)) + ".cs";
                if (string.IsNullOrEmpty(metadata.GetString(type.Namespace)))
                {
                    return(file);
                }
                else
                {
                    string dir = CleanUpFileName(metadata.GetString(type.Namespace));
                    if (directories.Add(dir))
                    {
                        Directory.CreateDirectory(Path.Combine(targetDirectory, dir));
                    }
                    return(Path.Combine(dir, file));
                }
            }, StringComparer.OrdinalIgnoreCase).ToList();
            int total               = files.Count;
            var progress            = this.ProgressIndicator;
            DecompilerTypeSystem ts = new DecompilerTypeSystem(module, AssemblyResolver, settings);

            Parallel.ForEach(
                files,
                new ParallelOptions {
                MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
                CancellationToken      = cancellationToken
            },
                delegate(IGrouping <string, TypeDefinitionHandle> file) {
                using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) {
                    try {
                        CSharpDecompiler decompiler  = CreateDecompiler(ts);
                        decompiler.CancellationToken = cancellationToken;
                        var syntaxTree = decompiler.DecompileTypes(file.ToArray());
                        syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions));
                    } catch (Exception innerException) when(!(innerException is OperationCanceledException || innerException is DecompilerException))
                    {
                        throw new DecompilerException(module, $"Error decompiling for '{file.Key}'", innerException);
                    }
                }
                progress?.Report(new DecompilationProgress(total, file.Key));
            });
            return(files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken)));
        }
コード例 #3
0
        static void Decompile(string assemblyFileName, TextWriter output, string typeName = null)
        {
            ModuleDefinition module     = LoadModule(assemblyFileName);
            var typeSystem              = new DecompilerTypeSystem(module);
            CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, new DecompilerSettings());

            decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
            SyntaxTree syntaxTree;

            if (typeName == null)
            {
                syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
            }
            else
            {
                syntaxTree = decompiler.DecompileTypes(module.GetTypes().Where(td => string.Equals(td.FullName, typeName, StringComparison.OrdinalIgnoreCase)));
            }

            var visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());

            syntaxTree.AcceptVisitor(visitor);
        }
コード例 #4
0
        IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(ModuleDefinition module, CancellationToken cancellationToken)
        {
            var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy(
                delegate(TypeDefinition type) {
                string file = CleanUpFileName(type.Name) + ".cs";
                if (string.IsNullOrEmpty(type.Namespace))
                {
                    return(file);
                }
                else
                {
                    string dir = CleanUpFileName(type.Namespace);
                    if (directories.Add(dir))
                    {
                        Directory.CreateDirectory(Path.Combine(targetDirectory, dir));
                    }
                    return(Path.Combine(dir, file));
                }
            }, StringComparer.OrdinalIgnoreCase).ToList();
            DecompilerTypeSystem ts = new DecompilerTypeSystem(module);

            Parallel.ForEach(
                files,
                new ParallelOptions {
                MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
                CancellationToken      = cancellationToken
            },
                delegate(IGrouping <string, TypeDefinition> file) {
                using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) {
                    CSharpDecompiler decompiler  = CreateDecompiler(ts);
                    decompiler.CancellationToken = cancellationToken;
                    var syntaxTree = decompiler.DecompileTypes(file.ToArray());
                    syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions));
                }
            });
            return(files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken)));
        }