public override RelocationResults Relocate(Program program, Address addrLoad) { SegmentMap imageMap = segmentMap; EndianImageReader rdr = new LeImageReader(exe.RawImage, exe.e_lfaRelocations); var relocations = imgLoaded.Relocations; int i = exe.e_cRelocations; var segments = new Dictionary <Address, ushort>(); var linBase = addrLoad.ToLinear(); while (i != 0) { uint offset = rdr.ReadLeUInt16(); ushort segOffset = rdr.ReadLeUInt16(); offset += segOffset * 0x0010u; ushort seg = (ushort)(imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value); imgLoaded.WriteLeUInt16(offset, seg); relocations.AddSegmentReference(offset + linBase, seg); var segment = new ImageSegment( seg.ToString("X4"), Address.SegPtr(seg, 0), imgLoaded, AccessMode.ReadWriteExecute); segment = segmentMap.AddSegment(segment); segments[segment.Address] = seg; --i; } // Create an identifier for each segment. foreach (var de in segments) { var tmp = new TemporaryStorage( string.Format("seg{0:X4}", de.Value), 0, PrimitiveType.SegmentSelector); segmentMap.Segments[de.Key].Identifier = new Identifier( tmp.Name, PrimitiveType.SegmentSelector, tmp); } // Found the start address. Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip); segmentMap.AddSegment(new ImageSegment( addrStart.Selector.Value.ToString("X4"), Address.SegPtr(addrStart.Selector.Value, 0), imgLoaded, AccessMode.ReadWriteExecute)); DumpSegments(imageMap); var ep = ImageSymbol.Procedure(arch, addrStart, state: arch.CreateProcessorState()); var sym = platform.FindMainProcedure(program, addrStart); var results = new RelocationResults( new List <ImageSymbol> { ep }, new SortedList <Address, ImageSymbol> { { ep.Address, ep } }); if (sym != null) { results.Symbols[sym.Address] = sym; ep.NoDecompile = true; } try { LoadDebugSymbols(results.Symbols, addrLoad); } catch (Exception ex) { var listener = Services.RequireService <DecompilerEventListener>(); listener.Error( new NullCodeLocation(Filename), ex, "Detected debug symbols but failed to load them."); } return(results); }
/// <summary> /// Give the relocator a chance to adjust the image symbol. /// </summary> /// <remarks> /// This is helpful when adjust ARM Thumb symbols, which will have /// their least significant bit set to 1. /// </remarks> public virtual ImageSymbol AdjustImageSymbol(ImageSymbol sym) { return(sym); }
public void EnqueueImageSymbol(ImageSymbol sym, bool isEntryPoint) { throw new NotImplementedException(); }
public override Program Load(Address addrLoad, IProcessorArchitecture arch, IPlatform platform) { BeImageReader rdr = new BeImageReader(this.RawImage, 0); try { this.hdr = new DolHeader(new StructureReader <DolStructure>(rdr).Read()); } catch (Exception ex) { throw new BadImageFormatException("Invalid DOL header. " + ex.Message); } var segments = new List <ImageSegment>(); // Create code segments for (uint i = 0, snum = 1; i < 7; i++, snum++) { if (hdr.addressText[i] == Address32.NULL) { continue; } segments.Add(new ImageSegment( string.Format("Text{0}", snum), hdr.addressText[i], hdr.sizeText[i], AccessMode.ReadExecute )); } // Create all data segments for (uint i = 0, snum = 1; i < 11; i++, snum++) { if (hdr.addressData[i] == Address32.NULL) { continue; } segments.Add(new ImageSegment( string.Format("Data{0}", snum), hdr.addressData[i], hdr.sizeData[i], AccessMode.ReadWrite )); } if (hdr.addressBSS != Address32.NULL) { segments.Add(new ImageSegment( ".bss", hdr.addressBSS, hdr.sizeBSS, AccessMode.ReadWrite )); } var segmentMap = new SegmentMap(addrLoad, segments.ToArray()); var entryPoint = new ImageSymbol(this.hdr.entrypoint) { Type = SymbolType.Procedure }; var program = new Program( segmentMap, arch, platform) { ImageSymbols = { { this.hdr.entrypoint, entryPoint } }, EntryPoints = { { this.hdr.entrypoint, entryPoint } } }; return(program); }