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