diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java index 068a50292f..f28ea0823f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/BinaryLoader.java @@ -330,7 +330,7 @@ public class BinaryLoader extends AbstractProgramLoader { block.setWrite(isOverlay ? false : true); block.setExecute(isOverlay ? false : true); block.setSourceName("Binary Loader"); - MemoryBlockUtil.adjustFragment(prog.getListing(), block.getStart(), blockName); + MemoryBlockUtils.adjustFragment(prog, block.getStart(), blockName); } catch (LockException | MemoryConflictException e) { Msg.error(this, "Unexpected exception creating memory block", e); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java index dc6c40d180..1146a1e0cd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java @@ -18,6 +18,7 @@ package ghidra.app.util.opinion; import java.io.IOException; import java.util.*; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.Option; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.ByteProvider; @@ -44,8 +45,7 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { static final boolean PROCESS_SYMBOLS_OPTION_DEFAULT = true; /** Loader option to create memory blocks for DYLIB sections */ - static final String CREATE_DYLIB_SECTIONS_OPTION_NAME = - "Create DYLIB section memory blocks (slow!)"; + static final String CREATE_DYLIB_SECTIONS_OPTION_NAME = "Create DYLIB section memory blocks"; /** Default value for loader option to create memory blocks for DYLIB sections */ static final boolean CREATE_DYLIB_SECTIONS_OPTION_DEFAULT = false; @@ -85,8 +85,9 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { throws IOException { try { - DyldCacheProgramBuilder.buildProgram(program, provider, shouldProcessSymbols(options), - shouldCreateDylibSections(options), log, handler, monitor); + DyldCacheProgramBuilder.buildProgram(program, provider, + MemoryBlockUtils.createFileBytes(program, provider), shouldProcessSymbols(options), + shouldCreateDylibSections(options), log, monitor); } catch (CancelledException e) { return; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheProgramBuilder.java index 96bbe03678..671ab9282c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheProgramBuilder.java @@ -19,13 +19,16 @@ import java.io.File; import java.io.IOException; import java.util.*; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.format.macho.MachException; import ghidra.app.util.bin.format.macho.MachHeader; import ghidra.app.util.bin.format.macho.commands.NList; import ghidra.app.util.bin.format.macho.dyld.*; -import ghidra.app.util.importer.*; +import ghidra.app.util.importer.MessageLog; +import ghidra.app.util.importer.MessageLogContinuesFactory; +import ghidra.program.database.mem.FileBytes; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.*; @@ -47,17 +50,17 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { * * @param program The {@link Program} to build up * @param provider The {@link ByteProvider} that contains the DYLD Cache bytes + * @param fileBytes Where the Mach-O's bytes came from * @param shouldProcessSymbols True if symbols should be processed; otherwise, false * @param shouldCreateDylibSections True if memory blocks should be created for DYLIB sections; * otherwise, false * @param log The log - * @param memoryConflictHandler How to handle memory conflicts that may occur * @param monitor A cancelable task monitor */ - protected DyldCacheProgramBuilder(Program program, ByteProvider provider, + protected DyldCacheProgramBuilder(Program program, ByteProvider provider, FileBytes fileBytes, boolean shouldProcessSymbols, boolean shouldCreateDylibSections, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) { - super(program, provider, log, memoryConflictHandler, monitor); + TaskMonitor monitor) { + super(program, provider, fileBytes, log, monitor); this.shouldProcessSymbols = shouldProcessSymbols; this.shouldCreateDylibSections = shouldCreateDylibSections; } @@ -67,20 +70,19 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { * * @param program The {@link Program} to build up * @param provider The {@link ByteProvider} that contains the DYLD Cache's bytes + * @param fileBytes Where the Mach-O's bytes came from * @param shouldProcessSymbols True if symbols should be processed; otherwise, false * @param shouldCreateDylibSections True if memory blocks should be created for DYLIB sections; * otherwise, false * @param log The log - * @param memoryConflictHandler How to handle memory conflicts that may occur * @param monitor A cancelable task monitor * @throws Exception if a problem occurs */ - public static void buildProgram(Program program, ByteProvider provider, + public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes, boolean shouldProcessSymbols, boolean shouldCreateDylibSections, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) throws Exception { + TaskMonitor monitor) throws Exception { DyldCacheProgramBuilder dyldCacheProgramBuilder = new DyldCacheProgramBuilder(program, - provider, shouldProcessSymbols, shouldCreateDylibSections, log, memoryConflictHandler, - monitor); + provider, fileBytes, shouldProcessSymbols, shouldCreateDylibSections, log, monitor); dyldCacheProgramBuilder.build(); } @@ -93,20 +95,12 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { dyldCacheHeader.parseFromFile(shouldProcessSymbols, log, monitor); monitor.incrementProgress(1); - try { - setDyldCacheImageBase(); - processDyldCacheMemoryBlocks(); - markupHeaders(); - markupBranchIslands(); - createSymbols(); - processDylibs(); - } - finally { - if (mbu != null) { - mbu.dispose(); - mbu = null; - } - } + setDyldCacheImageBase(); + processDyldCacheMemoryBlocks(); + markupHeaders(); + markupBranchIslands(); + createSymbols(); + processDylibs(); } /** @@ -135,9 +129,9 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { for (DyldCacheMappingInfo mappingInfo : mappingInfos) { long offset = mappingInfo.getFileOffset(); long size = mappingInfo.getSize(); - mbu.createInitializedBlock("DYLD", space.getAddress(mappingInfo.getAddress()), - provider.getInputStream(offset), size, "", "", mappingInfo.isRead(), - mappingInfo.isWrite(), mappingInfo.isExecute(), monitor); + MemoryBlockUtils.createInitializedBlock(program, false, "DYLD", + space.getAddress(mappingInfo.getAddress()), fileBytes, offset, size, "", "", + mappingInfo.isRead(), mappingInfo.isWrite(), mappingInfo.isExecute(), log); if (offset + size > endOfMappedOffset) { endOfMappedOffset = offset + size; } @@ -147,9 +141,10 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { if (endOfMappedOffset < provider.length()) { monitor.setMessage("Processing DYLD unmapped memory block..."); - mbu.createOverlayBlock("FILE", AddressSpace.OTHER_SPACE.getAddress(endOfMappedOffset), - provider.getInputStream(endOfMappedOffset), provider.length() - endOfMappedOffset, - "Useful bytes that don't get mapped into memory", "", false, false, false, monitor); + MemoryBlockUtils.createInitializedBlock(program, true, "FILE", + AddressSpace.OTHER_SPACE.getAddress(endOfMappedOffset), fileBytes, + endOfMappedOffset, provider.length() - endOfMappedOffset, + "Useful bytes that don't get mapped into memory", "", false, false, false, log); } } @@ -228,10 +223,9 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { // easier monitor.setMessage("Parsing DYLIB's..."); monitor.initialize(dyldCacheHeader.getImageInfos().size()); - TreeSet dyldCacheMachoInfoSet = - new TreeSet<>((a, b) -> a.headerAddr.compareTo(b.headerAddr)); + List infoList = new ArrayList<>(dyldCacheHeader.getImageInfos().size()); for (DyldCacheImageInfo dyldCacheImageInfo : dyldCacheHeader.getImageInfos()) { - dyldCacheMachoInfoSet.add(new DyldCacheMachoInfo(provider, + infoList.add(new DyldCacheMachoInfo(provider, dyldCacheImageInfo.getAddress() - dyldCacheHeader.getBaseAddress(), space.getAddress(dyldCacheImageInfo.getAddress()), dyldCacheImageInfo.getPath())); monitor.checkCanceled(); @@ -240,8 +234,8 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { // Markup DyldCache Mach-O headers monitor.setMessage("Marking up DYLIB headers..."); - monitor.initialize(dyldCacheMachoInfoSet.size()); - for (DyldCacheMachoInfo info : dyldCacheMachoInfoSet) { + monitor.initialize(infoList.size()); + for (DyldCacheMachoInfo info : infoList) { info.markupHeaders(); monitor.checkCanceled(); monitor.incrementProgress(1); @@ -249,8 +243,8 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { // Add DyldCache Mach-O's to program tree monitor.setMessage("Adding DYLIB's to program tree..."); - monitor.initialize(dyldCacheMachoInfoSet.size()); - Iterator iter = dyldCacheMachoInfoSet.iterator(); + monitor.initialize(infoList.size()); + Iterator iter = infoList.iterator(); if (iter.hasNext()) { DyldCacheMachoInfo curr = iter.next(); do { @@ -263,13 +257,11 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder { while (iter.hasNext()); } - // Process DyldCache DYLIB memory blocks. Need to do it in descending (reverse) order or - // the memory block splitting will be way too slow. + // Process DyldCache DYLIB memory blocks. monitor.setMessage("Processing DYLIB memory blocks..."); - monitor.initialize(dyldCacheMachoInfoSet.size()); - Iterator descendingIter = dyldCacheMachoInfoSet.descendingIterator(); - while (descendingIter.hasNext()) { - descendingIter.next().processMemoryBlocks(); + monitor.initialize(infoList.size()); + for (DyldCacheMachoInfo info : infoList) { + info.processMemoryBlocks(); monitor.checkCanceled(); monitor.incrementProgress(1); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java index 49afbe3f91..9458774be3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.*; import generic.continues.RethrowContinuesFactory; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.Option; import ghidra.app.util.bin.*; import ghidra.app.util.bin.format.macho.*; @@ -28,6 +29,7 @@ import ghidra.app.util.bin.format.ubi.*; import ghidra.app.util.importer.MemoryConflictHandler; import ghidra.app.util.importer.MessageLog; import ghidra.framework.model.DomainFolder; +import ghidra.program.database.mem.FileBytes; import ghidra.program.model.listing.Program; import ghidra.util.LittleEndianDataConverter; import ghidra.util.exception.CancelledException; @@ -81,15 +83,18 @@ public class MachoLoader extends AbstractLibrarySupportLoader { throws IOException { try { + FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider); + // A Mach-O file may contain PRELINK information. If so, we use a special // program builder that knows how to deal with it. List prelinkList = MachoPrelinkUtils.parsePrelinkXml(provider, monitor); if (!prelinkList.isEmpty()) { - MachoPrelinkProgramBuilder.buildProgram(program, provider, prelinkList, log, handler, - monitor); + MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes, prelinkList, + log, monitor); } else { - MachoProgramBuilder.buildProgram(program, provider, log, handler, monitor); + MachoProgramBuilder.buildProgram(program, provider, fileBytes, log, handler, + monitor); } } catch (Exception e) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoPrelinkProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoPrelinkProgramBuilder.java index 02576a8e76..30b5f3899e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoPrelinkProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoPrelinkProgramBuilder.java @@ -25,7 +25,9 @@ import ghidra.app.util.bin.format.macho.MachHeader; import ghidra.app.util.bin.format.macho.Section; import ghidra.app.util.bin.format.macho.commands.SegmentNames; import ghidra.app.util.bin.format.macho.prelink.PrelinkMap; -import ghidra.app.util.importer.*; +import ghidra.app.util.importer.MessageLog; +import ghidra.app.util.importer.MessageLogContinuesFactory; +import ghidra.program.database.mem.FileBytes; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataUtilities; import ghidra.program.model.data.Pointer64DataType; @@ -48,15 +50,15 @@ public class MachoPrelinkProgramBuilder extends MachoProgramBuilder { * * @param program The {@link Program} to build up. * @param provider The {@link ByteProvider} that contains the Mach-O's bytes. + * @param fileBytes Where the Mach-O's bytes came from. * @param prelinkList Parsed {@link PrelinkMap PRELINK} information. * @param log The log. - * @param memoryConflictHandler How to handle memory conflicts that may occur. * @param monitor A cancelable task monitor. */ protected MachoPrelinkProgramBuilder(Program program, ByteProvider provider, - List prelinkList, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) { - super(program, provider, log, memoryConflictHandler, monitor); + FileBytes fileBytes, List prelinkList, MessageLog log, + TaskMonitor monitor) { + super(program, provider, fileBytes, log, monitor); this.prelinkList = prelinkList; } @@ -65,17 +67,16 @@ public class MachoPrelinkProgramBuilder extends MachoProgramBuilder { * * @param program The {@link Program} to build up. * @param provider The {@link ByteProvider} that contains the Mach-O's bytes. + * @param fileBytes Where the Mach-O's bytes came from. * @param prelinkList Parsed {@link PrelinkMap PRELINK} information. * @param log The log. - * @param memoryConflictHandler How to handle memory conflicts that may occur. * @param monitor A cancelable task monitor. * @throws Exception if a problem occurs. */ - public static void buildProgram(Program program, ByteProvider provider, - List prelinkList, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) throws Exception { + public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes, + List prelinkList, MessageLog log, TaskMonitor monitor) throws Exception { MachoPrelinkProgramBuilder machoPrelinkProgramBuilder = new MachoPrelinkProgramBuilder( - program, provider, prelinkList, log, memoryConflictHandler, monitor); + program, provider, fileBytes, prelinkList, log, monitor); machoPrelinkProgramBuilder.build(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java index 3ef0dd371b..5edf324b4f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import ghidra.app.util.MemoryBlockUtil; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.StructConverter; import ghidra.app.util.bin.format.macho.*; @@ -30,6 +30,7 @@ import ghidra.app.util.bin.format.objectiveC.ObjectiveC1_Constants; import ghidra.app.util.importer.*; import ghidra.framework.options.Options; import ghidra.program.database.function.OverlappingFunctionException; +import ghidra.program.database.mem.FileBytes; import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.lang.Processor; @@ -55,32 +56,32 @@ public class MachoProgramBuilder { protected Program program; protected ByteProvider provider; + protected FileBytes fileBytes; protected MessageLog log; protected TaskMonitor monitor; protected Memory memory; protected Listing listing; protected AddressSpace space; - protected MemoryBlockUtil mbu; /** * Creates a new {@link MachoProgramBuilder} based on the given information. * * @param program The {@link Program} to build up. * @param provider The {@link ByteProvider} that contains the Mach-O's bytes. + * @param fileBytes Where the Mach-O's bytes came from. * @param log The log. - * @param memoryConflictHandler How to handle memory conflicts that may occur. * @param monitor A cancelable task monitor. */ - protected MachoProgramBuilder(Program program, ByteProvider provider, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) { + protected MachoProgramBuilder(Program program, ByteProvider provider, FileBytes fileBytes, + MessageLog log, TaskMonitor monitor) { this.program = program; this.provider = provider; + this.fileBytes = fileBytes; this.log = log; this.monitor = monitor; this.memory = program.getMemory(); this.listing = program.getListing(); this.space = program.getAddressFactory().getDefaultAddressSpace(); - this.mbu = new MemoryBlockUtil(program, memoryConflictHandler); } /** @@ -88,15 +89,17 @@ public class MachoProgramBuilder { * * @param program The {@link Program} to build up. * @param provider The {@link ByteProvider} that contains the Mach-O's bytes. + * @param fileBytes Where the Mach-O's bytes came from. * @param log The log. * @param memoryConflictHandler How to handle memory conflicts that may occur. * @param monitor A cancelable task monitor. * @throws Exception if a problem occurs. */ - public static void buildProgram(Program program, ByteProvider provider, MessageLog log, - MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) throws Exception { + public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes, + MessageLog log, MemoryConflictHandler memoryConflictHandler, TaskMonitor monitor) + throws Exception { MachoProgramBuilder machoProgramBuilder = - new MachoProgramBuilder(program, provider, log, memoryConflictHandler, monitor); + new MachoProgramBuilder(program, provider, fileBytes, log, monitor); machoProgramBuilder.build(); } @@ -115,33 +118,25 @@ public class MachoProgramBuilder { } monitor.setCancelEnabled(true); - try { - setImageBase(); - processEntryPoint(); - processMemoryBlocks(machoHeader, provider.getName(), true, true); - processUnsupportedLoadCommands(); - processSymbolTables(); - processIndirectSymbols(); - setRelocatableProperty(); - processLibraries(); - processProgramDescription(); - renameObjMsgSendRtpSymbol(); - processUndefinedSymbols(); - processAbsoluteSymbols(); - processDyldInfo(); - markupHeaders(machoHeader, headerAddr); - markupSections(); - processProgramVars(); - loadSectionRelocations(); - loadExternalRelocations(); - loadLocalRelocations(); - } - finally { - if (mbu != null) { - mbu.dispose(); - mbu = null; - } - } + setImageBase(); + processEntryPoint(); + processMemoryBlocks(machoHeader, provider.getName(), true, true); + processUnsupportedLoadCommands(); + processSymbolTables(); + processIndirectSymbols(); + setRelocatableProperty(); + processLibraries(); + processProgramDescription(); + renameObjMsgSendRtpSymbol(); + processUndefinedSymbols(); + processAbsoluteSymbols(); + processDyldInfo(); + markupHeaders(machoHeader, headerAddr); + markupSections(); + processProgramVars(); + loadSectionRelocations(); + loadExternalRelocations(); + loadLocalRelocations(); } private void setImageBase() throws Exception { @@ -219,12 +214,8 @@ public class MachoProgramBuilder { return; } - // Create memory blocks for segments. Create them in reverse order so the splitting - // is more efficient. - List segments = header.getAllSegments(); - segments.sort((SegmentCommand a, SegmentCommand b) -> Long.compare(b.getVMaddress(), - a.getVMaddress())); - for (SegmentCommand segment : segments) { + // Create memory blocks for segments. + for (SegmentCommand segment : header.getAllSegments()) { if (monitor.isCancelled()) { break; } @@ -256,12 +247,9 @@ public class MachoProgramBuilder { } // Create memory blocks for sections. They will be in the segments we just created, so the - // segment blocks will be split and possibly replaced. Create them in reverse order so - // the splitting is more efficient. + // segment blocks will be split and possibly replaced. if (processSections) { - List
sections = header.getAllSections(); - sections.sort((Section a, Section b) -> Long.compare(b.getAddress(), a.getAddress())); - for (Section section : sections) { + for (Section section : header.getAllSections()) { if (monitor.isCancelled()) { break; } @@ -331,12 +319,12 @@ public class MachoProgramBuilder { if (intersectingBlocks.isEmpty()) { if (zeroFill) { // Treat zero-fill blocks as uninitialized to save space - return mbu.createUninitializedBlock(false, name, start, dataLength, comment, source, - r, w, x); + return MemoryBlockUtils.createUninitializedBlock(program, false, name, start, + dataLength, comment, source, r, w, x, log); } - return mbu.createInitializedBlock(name, start, provider.getInputStream(dataOffset), - dataLength, comment, source, r, w, x, monitor); + return MemoryBlockUtils.createInitializedBlock(program, false, name, start, fileBytes, + dataOffset, dataLength, comment, source, r, w, x, log); } // Split the starting block (if necessary). Splitting is not necessary if the start of our @@ -363,9 +351,7 @@ public class MachoProgramBuilder { for (MemoryBlock block : memory.getBlocks()) { if (range.intersects(block.getStart(), block.getEnd())) { block.setName(name); - block.setRead(r); - block.setWrite(w); - block.setExecute(x); + block.setPermissions(r, w, x); block.setSourceName(source); block.setComment(comment); } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/prelink/PrelinkFileSystem.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/prelink/PrelinkFileSystem.java index e4cc35001c..83b17120a9 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/prelink/PrelinkFileSystem.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/prelink/PrelinkFileSystem.java @@ -23,6 +23,7 @@ import org.apache.commons.collections4.BidiMap; import org.jdom.JDOMException; import generic.continues.RethrowContinuesFactory; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.bin.*; import ghidra.app.util.bin.format.macho.*; import ghidra.app.util.bin.format.macho.commands.*; @@ -37,6 +38,7 @@ import ghidra.formats.gfilesystem.factory.GFileSystemBaseFactory; import ghidra.framework.store.local.LocalFileSystem; import ghidra.macosx.MacosxLanguageHelper; import ghidra.program.database.ProgramDB; +import ghidra.program.database.mem.FileBytes; import ghidra.program.model.address.Address; import ghidra.program.model.lang.LanguageCompilerSpecPair; import ghidra.program.model.lang.LanguageService; @@ -185,9 +187,12 @@ public class PrelinkFileSystem extends GFileSystemBase implements GFileSystemPro int id = program.startTransaction(getName()); boolean success = false; try { - MachoProgramBuilder.buildProgram(program, - new ByteProviderWrapper(provider, offset, provider.length() - offset), - new MessageLog(), MemoryConflictHandler.NEVER_OVERWRITE, monitor); + FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, offset, + provider.length() - offset); + ByteProvider providerWrapper = + new ByteProviderWrapper(provider, offset, provider.length() - offset); + MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, new MessageLog(), + MemoryConflictHandler.NEVER_OVERWRITE, monitor); program.setExecutableFormat(MachoLoader.MACH_O_NAME); program.setExecutablePath(file.getPath());