public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) { PEFile module = method.ParentModule.PEFile; R2RReaderCacheEntry r2rReaderCacheEntry = GetReader(module.GetLoadedAssembly(), module); if (r2rReaderCacheEntry.r2rReader == null) { WriteCommentLine(output, r2rReaderCacheEntry.failureReason); } else { R2RReader reader = r2rReaderCacheEntry.r2rReader; int bitness = -1; if (reader.Machine == Machine.Amd64) { bitness = 64; } else { Debug.Assert(reader.Machine == Machine.I386); bitness = 32; } foreach (var m in reader.R2RMethods) { if (m.MethodHandle == method.MetadataToken) { // TODO: Indexing foreach (RuntimeFunction runtimeFunction in m.RuntimeFunctions) { WriteCommentLine(output, m.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.GetPEFileOrNull(); R2RReaderCacheEntry r2rReaderCacheEntry = GetReader(assembly, module); if (r2rReaderCacheEntry.r2rReader == null) { WriteCommentLine(output, r2rReaderCacheEntry.failureReason); } else { R2RReader reader = r2rReaderCacheEntry.r2rReader; WriteCommentLine(output, "TODO - display ready to run information"); // TODO: display other header information foreach (var method in reader.R2RMethods) { WriteCommentLine(output, method.SignatureString); } } return(base.DecompileAssembly(assembly, output, options)); }
private R2RReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module) { R2RReaderCacheEntry result; lock (r2rReaders) { if (!r2rReaders.TryGetValue(module, out result)) { result = new R2RReaderCacheEntry(); try { // TODO: avoid eager parsing result.r2rReader = new R2RReader(new R2RAssemblyResolver(assembly), module.Metadata, module.Reader, module.FileName); if (result.r2rReader.Machine != Machine.Amd64 && result.r2rReader.Machine != Machine.I386) { result.failureReason = $"Architecture {result.r2rReader.Machine} is not currently supported."; result.r2rReader = null; } } catch (BadImageFormatException e) { result.failureReason = e.Message; } r2rReaders.Add(module, result); } } return(result); }