private SegmentMap MakeSegmentMap(IProcessorArchitecture arch) { var segs = new List <ImageSegment>(); foreach (var section in sections) { var addrBase = Address.Create(arch.PointerType, section.uAddrBase); if (!mems.TryGetLowerBoundIndex(addrBase, out var iSection)) { throw new BadImageFormatException($"Unable to find a memory area for section {section.name} at {section.uAddrBase:X4}."); } var addrMem = mems.Keys[iSection]; var bytes = mems.Values[iSection]; var mem = arch.CreateMemoryArea(addrMem, bytes.ToArray()); if (addrMem < addrBase) { var stubSeg = new ImageSegment($"seg{addrMem.ToLinear():X4}", addrMem, mem, AccessMode.ReadWriteExecute); segs.Add(stubSeg); var seg = new ImageSegment(section.name !, addrBase, mem, AccessMode.ReadWriteExecute); segs.Add(seg); } else { var seg = new ImageSegment(section.name !, mem, AccessMode.ReadWriteExecute); segs.Add(seg); } } var baseAddr = segs.Min(s => s.Address); return(new SegmentMap(baseAddr, segs.ToArray())); }
/// <summary> /// Loads the image into memory at the specified address, using the provided /// <seealso cref="IProcessorArchitecture"/> and <seealso cref="IPlatform"/>. /// Used when loading raw files; not all image loaders can support this. /// </summary> /// <param name="addrLoad">Loading address *IGNORED*.</param> /// <param name="arch">Processor architecture.</param> /// <param name="platform">Platform/operating environment.</param> /// <returns> /// A <see cref="Program"/> instance. /// </returns> public override Program LoadProgram(Address addrLoad, IProcessorArchitecture arch, IPlatform platform) { listener = Services.RequireService <DecompilerEventListener>(); var memChunks = new MemoryChunksList(); Address?addrEp = null; Address addrBase = MakeZeroAddress(arch); using (var rdr = new IntelHexReader(new MemoryStream(RawImage), addrBase)) { try { for (; ;) { if (!rdr.TryReadRecord(out Address address, out byte[] data)) { break; } if (data != null) { memChunks.AddData(address, data); continue; } } addrEp = rdr.StartAddress; } catch (IntelHexException ex) { listener.Error(ex.Message); return(null !); } } var segs = new SegmentMap(PreferredBaseAddress); // Generate the image segments with fake names. int i = 0; foreach (var mchk in memChunks) { var mem = arch.CreateMemoryArea(mchk.BaseAddress, mchk.Datum.ToArray()); var seg = new ImageSegment($"CODE_{i:d2}", mem, AccessMode.ReadExecute); ++i; segs.AddSegment(seg); } var program = new Program(segs, arch, platform); if (addrEp != null) { program.EntryPoints.Add(addrEp, ImageSymbol.Procedure(arch, addrEp)); } return(program); }
private void Disassemble() { try { if (this.arch is null) { return; } if (!arch.TryParseAddress(control.Address.Text, out var addr)) { return; } var bytes = BytePattern.FromHexBytes(control.HexBytes.Text).ToArray(); if (bytes.Length > 0) { var mem = arch.CreateMemoryArea(addr, bytes); var dumper = new Dumper(new Program()) { ShowAddresses = true, ShowCodeBytes = true, }; var sw = new StringWriter(); dumper.DumpAssembler(arch, mem, mem.BaseAddress, bytes.Length, new Core.Output.TextFormatter(sw)); control.Disassembly.Text = sw.ToString(); } else { control.Disassembly.Text = ""; } } catch (Exception ex) { var diagSvc = services.RequireService <IDiagnosticsService>(); diagSvc.Error(ex, "An error occurred during disassembly."); } }