private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module)
        {
            ReadyToRunReaderCacheEntry result;

            lock (readyToRunReaders)
            {
                if (!readyToRunReaders.TryGetValue(module, out result))
                {
                    result = new ReadyToRunReaderCacheEntry();
                    try
                    {
                        result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName);
                        if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386)
                        {
                            result.failureReason    = $"Architecture {result.readyToRunReader.Machine} is not currently supported.";
                            result.readyToRunReader = null;
                        }
                    }
                    catch (BadImageFormatException e)
                    {
                        result.failureReason = e.Message;
                    }
                    readyToRunReaders.Add(module, result);
                }
            }
            return(result);
        }
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                if (cacheEntry.methodMap == null)
                {
                    cacheEntry.methodMap = reader.Methods.ToList()
                                           .GroupBy(m => m.MethodHandle)
                                           .ToDictionary(g => g.Key, g => g.ToArray());
                }
                bool showMetadataTokens         = ILSpy.Options.DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens;
                bool showMetadataTokensInBase10 = ILSpy.Options.DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokensInBase10;
#if STRESS
                ITextOutput originalOutput = output;
                output = new DummyOutput();
                {
                    foreach (var readyToRunMethod in reader.Methods)
                    {
#else
                if (cacheEntry.methodMap.TryGetValue(method.MetadataToken, out var methods))
                {
                    foreach (var readyToRunMethod in methods)
                    {
#endif
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            new ReadyToRunDisassembler(output, reader, runtimeFunction).Disassemble(method.ParentModule.PEFile, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
                        }
                    }
                }
#if STRESS
                output = originalOutput;
                output.WriteLine("Passed");
#endif
            }
        }
Exemple #3
0
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                foreach (ReadyToRunMethod readyToRunMethod in reader.Methods)
                {
                    if (readyToRunMethod.MethodHandle == method.MetadataToken)
                    {
                        // TODO: Indexing
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            WriteCommentLine(output, readyToRunMethod.SignatureString);
                            byte[] code = new byte[runtimeFunction.Size];
                            for (int i = 0; i < runtimeFunction.Size; i++)
                            {
                                code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
                            }
                            Disassemble(output, code, bitness, (ulong)runtimeFunction.StartAddress);
                            output.WriteLine();
                        }
                    }
                }
            }
        }
        public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = assembly.GetPEFileAsync().GetAwaiter().GetResult();
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                WriteCommentLine(output, reader.Machine.ToString());
                WriteCommentLine(output, reader.OperatingSystem.ToString());
                WriteCommentLine(output, reader.CompilerIdentifier);
                WriteCommentLine(output, "TODO - display more header information");
            }

            return(base.DecompileAssembly(assembly, output, options));
        }
Exemple #5
0
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                if (cacheEntry.methodMap == null)
                {
                    cacheEntry.methodMap = reader.Methods.Values
                                           .SelectMany(m => m)
                                           .GroupBy(m => m.MethodHandle)
                                           .ToDictionary(g => g.Key, g => g.ToArray());
                }
                if (cacheEntry.methodMap.TryGetValue(method.MetadataToken, out var methods))
                {
                    foreach (var readyToRunMethod in methods)
                    {
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            Disassemble(output, reader, readyToRunMethod, runtimeFunction, bitness, (ulong)runtimeFunction.StartAddress);
                        }
                    }
                }
            }
        }