GP-3566: Adjusted MachoLoader and DyldCacheLoader options

This commit is contained in:
Ryan Kurtz
2023-06-22 07:42:43 -04:00
parent dea22bc2ba
commit 309be1eb05
18 changed files with 206 additions and 150 deletions
@@ -63,13 +63,13 @@ public class DataInCodeCommand extends LinkEditDataCommand {
}
@Override
public void markup(Program program, MachHeader header, Address addr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
public void markup(Program program, MachHeader header, Address addr, String source,
TaskMonitor monitor, MessageLog log) throws CancelledException {
if (addr == null || datasize == 0) {
return;
}
super.markup(program, header, addr, monitor, log);
super.markup(program, header, addr, source, monitor, log);
try {
for (DataInCodeEntry entry : entries) {
@@ -64,14 +64,14 @@ public class DyldChainedFixupsCommand extends LinkEditDataCommand {
}
@Override
public void markup(Program program, MachHeader header, Address addr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
public void markup(Program program, MachHeader header, Address addr, String source,
TaskMonitor monitor, MessageLog log) throws CancelledException {
if (addr == null || datasize == 0) {
return;
}
super.markup(program, header, addr, monitor, log);
super.markup(program, header, addr, source, monitor, log);
try {
DataUtilities.createData(program, addr, chainHeader.toDataType(), -1,
@@ -80,13 +80,13 @@ public class FunctionStartsCommand extends LinkEditDataCommand {
}
@Override
public void markup(Program program, MachHeader header, Address addr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
public void markup(Program program, MachHeader header, Address addr, String source,
TaskMonitor monitor, MessageLog log) throws CancelledException {
if (addr == null || datasize == 0) {
return;
}
super.markup(program, header, addr, monitor, log);
super.markup(program, header, addr, source, monitor, log);
SegmentCommand textSegment = header.getSegment(SegmentNames.SEG_TEXT);
if (textSegment == null) {
@@ -83,13 +83,16 @@ public class LinkEditDataCommand extends LoadCommand {
}
@Override
public void markup(Program program, MachHeader header, Address addr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
public void markup(Program program, MachHeader header, Address addr, String source,
TaskMonitor monitor, MessageLog log) throws CancelledException {
if (addr == null || datasize == 0) {
return;
}
String lcName = LoadCommandTypes.getLoadCommandName(getCommandType());
program.getListing().setComment(addr, CodeUnit.PLATE_COMMENT, lcName);
String name = LoadCommandTypes.getLoadCommandName(getCommandType());
if (source != null) {
name += " - " + source;
}
program.getListing().setComment(addr, CodeUnit.PLATE_COMMENT, name);
}
@Override
@@ -103,12 +103,13 @@ public abstract class LoadCommand implements StructConverter {
* @param program The {@link Program} to mark up
* @param header The Mach-O header
* @param addr The {@link Address} of the start of load command data (could be null if no data)
* @param source A name that represents where the header came from (could be null)
* @param monitor A cancellable task monitor
* @param log The log
* @throws CancelledException if the user cancelled the operation
*/
public void markup(Program program, MachHeader header, Address addr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
public void markup(Program program, MachHeader header, Address addr, String source,
TaskMonitor monitor, MessageLog log) throws CancelledException {
// Default is no markup
return;
}
@@ -167,7 +167,7 @@ public class SymbolTableCommand extends LoadCommand {
@Override
public void markup(Program program, MachHeader header, Address symbolTableAddr,
TaskMonitor monitor, MessageLog log) throws CancelledException {
String source, TaskMonitor monitor, MessageLog log) throws CancelledException {
if (symbolTableAddr == null) {
return;
}
@@ -175,9 +175,12 @@ public class SymbolTableCommand extends LoadCommand {
Listing listing = program.getListing();
ReferenceManager referenceManager = program.getReferenceManager();
String lcName = LoadCommandTypes.getLoadCommandName(getCommandType());
String name = LoadCommandTypes.getLoadCommandName(getCommandType());
if (source != null) {
name += " - " + source;
}
try {
listing.setComment(symbolTableAddr, CodeUnit.PLATE_COMMENT, lcName);
listing.setComment(symbolTableAddr, CodeUnit.PLATE_COMMENT, name);
for (int i = 0; i < nsyms; i++) {
NList nlist = symbols.get(i);
DataType dt = nlist.toDataType();
@@ -197,7 +200,7 @@ public class SymbolTableCommand extends LoadCommand {
}
catch (Exception e) {
log.appendMsg(SymbolTableCommand.class.getSimpleName(),
"Failed to markup %s.".formatted(lcName));
"Failed to markup %s.".formatted(name));
}
}
@@ -40,7 +40,6 @@ public class DyldChainedFixups {
private MachHeader machoHeader;
private Program program;
private boolean shouldAddChainedFixupsRelocations;
private MessageLog log;
private TaskMonitor monitor;
private Memory memory;
@@ -51,16 +50,13 @@ public class DyldChainedFixups {
*
* @param program The {@link Program}
* @param header The Mach-O header
* @param shouldAddChainedFixupsRelocations True if relocations should be added for chained
* fixups; otherwise, false
* @param log The log
* @param monitor A cancelable task monitor.
*/
public DyldChainedFixups(Program program, MachHeader header,
boolean shouldAddChainedFixupsRelocations, MessageLog log, TaskMonitor monitor) {
public DyldChainedFixups(Program program, MachHeader header, MessageLog log,
TaskMonitor monitor) {
this.program = program;
this.machoHeader = header;
this.shouldAddChainedFixupsRelocations = shouldAddChainedFixupsRelocations;
this.log = log;
this.monitor = monitor;
this.memory = program.getMemory();
@@ -306,13 +302,11 @@ public class DyldChainedFixups {
byteLength = result.byteLength();
}
finally {
if (shouldAddChainedFixupsRelocations) {
program.getRelocationTable()
.add(chainLoc, status,
(start ? 0x8000 : 0x4000) | (isAuthenticated ? 4 : 0) |
(isBound ? 2 : 0) | 1,
new long[] { newChainValue }, byteLength, symName);
}
program.getRelocationTable()
.add(chainLoc, status,
(start ? 0x8000 : 0x4000) | (isAuthenticated ? 4 : 0) |
(isBound ? 2 : 0) | 1,
new long[] { newChainValue }, byteLength, symName);
}
}
// delay creating data until after memory has been changed
@@ -359,19 +359,19 @@ public class DyldCacheHeader implements StructConverter {
/**
* Parses the structures referenced by this {@link DyldCacheHeader} from a file.
*
* @param parseSymbols True if symbols should be parsed (could be very slow); otherwise, false
* @param parseLocalSymbols True if local symbols should be parsed; otherwise, false
* @param log The log
* @param monitor A cancellable task monitor
* @throws CancelledException if the user cancelled the operation
*/
public void parseFromFile(boolean parseSymbols, MessageLog log, TaskMonitor monitor)
public void parseFromFile(boolean parseLocalSymbols, MessageLog log, TaskMonitor monitor)
throws CancelledException {
if (headerType >= 1) {
parseMappingInfo(log, monitor);
parseImageInfo(log, monitor);
}
if (headerType >= 3) {
if (parseSymbols) {
if (parseLocalSymbols) {
parseLocalSymbolsInfo(log, monitor);
}
}
@@ -454,13 +454,14 @@ public class DyldCacheHeader implements StructConverter {
* Marks up this {@link DyldCacheHeader} with data structures and comments.
*
* @param program The {@link Program} to mark up
* @param markupLocalSymbols True if the local symbols should be marked up; otherwise, false
* @param space The {@link Program}'s {@link AddressSpace}
* @param monitor A cancellable task monitor
* @param log The log
* @throws CancelledException if the user cancelled the operation
*/
public void markup(Program program, AddressSpace space, TaskMonitor monitor, MessageLog log)
throws CancelledException {
public void markup(Program program, boolean markupLocalSymbols, AddressSpace space,
TaskMonitor monitor, MessageLog log) throws CancelledException {
if (headerType >= 1) {
markupHeader(program, space, monitor, log);
markupMappingInfo(program, space, monitor, log);
@@ -471,7 +472,9 @@ public class DyldCacheHeader implements StructConverter {
markupSlideInfo(program, space, monitor, log);
}
if (headerType >= 3) {
markupLocalSymbolsInfo(program, space, monitor, log);
if (markupLocalSymbols) {
markupLocalSymbolsInfo(program, space, monitor, log);
}
}
if (headerType >= 6) {
markupBranchPools(program, space, monitor, log);
@@ -107,9 +107,7 @@ public class DyldCacheLocalSymbolsInfo implements StructConverter {
public void markup(Program program, Address localSymbolsInfoAddr, TaskMonitor monitor,
MessageLog log) throws CancelledException {
markupLocalSymbols(program, localSymbolsInfoAddr, monitor, log);
// TODO: This is slow and not too useful. Add an option for it.
//markupNList(program, localSymbolsInfoAddr, monitor, log);
markupNList(program, localSymbolsInfoAddr, monitor, log);
}
/**
@@ -36,19 +36,43 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
public final static String DYLD_CACHE_NAME = "DYLD Cache";
/** Loader option to process symbols*/
static final String PROCESS_SYMBOLS_OPTION_NAME = "Process symbols";
/** Loader option to process symbols */
static final String PROCESS_LOCAL_SYMBOLS_OPTION_NAME = "Process local symbols";
/** Default value for loader option to process symbols */
static final boolean PROCESS_SYMBOLS_OPTION_DEFAULT = true;
static final boolean PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT = true;
/** Loader option to add relocation entries for chained fixups */
/** Loader option to process exports */
static final String PROCESS_EXPORTS_OPTION_NAME = "Process exports";
/** Default value for loader option to process exports */
static final boolean PROCESS_EXPORTS_OPTION_DEFAULT = true;
/** Loader option to mark up symbols */
static final String MARKUP_LOCAL_SYMBOLS_OPTION_NAME = "Markup local symbol nlists (slow)";
/** Default value for loader option to mark up symbols */
static final boolean MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT = false;
/** Loader option to process chained fixups */
static final String PROCESS_CHAINED_FIXUPS_OPTION_NAME = "Process chained fixups";
/** Default value for loader option to process chained fixups */
static final boolean PROCESS_CHAINED_FIXUPS_OPTION_DEFAULT = true;
/** Loader option to add chained fixups to relocation table */
static final String ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME =
"Add relocation entries for chained fixups";
"Add chained fixups to relocation table";
/** Default value for loader option to add chained fixups relocation entries */
/** Default value for loader option to add chained fixups to relocation table */
static final boolean ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT = false;
/** Loader option to mark up Mach-O load command data */
static final String MARKUP_MACHO_LC_DATA_OPTION_NAME = "Markup Mach-O load command data (slow)";
/** Default value for loader option to mark up Mach-O load command data */
static final boolean MARKUP_MACHO_LC_DATA_OPTION_DEFAULT = false;
@Override
public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException {
List<LoadSpec> loadSpecs = new ArrayList<>();
@@ -87,8 +111,7 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
try {
DyldCacheProgramBuilder.buildProgram(program, provider,
MemoryBlockUtils.createFileBytes(program, provider, monitor),
shouldProcessSymbols(options), shouldAddChainedFixupsRelocations(options), log,
monitor);
getDyldCacheOptions(options), log, monitor);
}
catch (CancelledException e) {
return;
@@ -104,23 +127,44 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
List<Option> list =
super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram);
if (!loadIntoProgram) {
list.add(new Option(PROCESS_SYMBOLS_OPTION_NAME, PROCESS_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processSymbols"));
list.add(
new Option(PROCESS_LOCAL_SYMBOLS_OPTION_NAME, PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processLocalSymbols"));
list.add(
new Option(MARKUP_LOCAL_SYMBOLS_OPTION_NAME, MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-markupLocalSymbols"));
list.add(
new Option(PROCESS_EXPORTS_OPTION_NAME, PROCESS_EXPORTS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processExports"));
list.add(new Option(PROCESS_CHAINED_FIXUPS_OPTION_NAME,
PROCESS_CHAINED_FIXUPS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-processChainedFixups"));
list.add(new Option(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME,
ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-addChainedFixupsRelocations"));
list.add(new Option(MARKUP_MACHO_LC_DATA_OPTION_NAME,
MARKUP_MACHO_LC_DATA_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-markupMachoLoadCommandData"));
}
return list;
}
private boolean shouldProcessSymbols(List<Option> options) {
return OptionUtils.getOption(PROCESS_SYMBOLS_OPTION_NAME, options,
PROCESS_SYMBOLS_OPTION_DEFAULT);
}
private boolean shouldAddChainedFixupsRelocations(List<Option> options) {
return OptionUtils.getOption(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME, options,
ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT);
private DyldCacheOptions getDyldCacheOptions(List<Option> options) {
boolean processLocalSymbols = OptionUtils.getOption(PROCESS_LOCAL_SYMBOLS_OPTION_NAME,
options, PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT);
boolean markupLocalSymbols = OptionUtils.getOption(MARKUP_LOCAL_SYMBOLS_OPTION_NAME,
options, MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT);
boolean processExports = OptionUtils.getOption(PROCESS_EXPORTS_OPTION_NAME,
options, PROCESS_EXPORTS_OPTION_DEFAULT);
boolean processChainedFixups = OptionUtils.getOption(PROCESS_CHAINED_FIXUPS_OPTION_NAME,
options, PROCESS_CHAINED_FIXUPS_OPTION_DEFAULT);
boolean addChainedFixupsRelocations =
OptionUtils.getOption(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME, options,
ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT);
boolean markupMachoLoadCommandData = OptionUtils.getOption(MARKUP_MACHO_LC_DATA_OPTION_NAME,
options, MARKUP_MACHO_LC_DATA_OPTION_DEFAULT);
return new DyldCacheOptions(processLocalSymbols, markupLocalSymbols, processExports,
processChainedFixups, addChainedFixupsRelocations, markupMachoLoadCommandData);
}
@Override
@@ -0,0 +1,33 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.opinion;
/**
* Options from the {@link DyldCacheLoader}
*
* @param processLocalSymbols True if local symbols should be processes; otherwise, false
* @param markupLocalSymbols True if local symbols should be marked up; otherwise, false
* @param processExports True if exported symbols should be processed; otherwise, false
* @param processChainedFixups True if chained fixups should be processed; otherwise, false
* @param addChainedFixupsRelocations True if chained fixups should be added to the relocation
* table; otherwise false
* @param markupMachoLoadCommandData True if individual Mach-O load command data blocks should be
* marked up; otherwise, false
*/
public record DyldCacheOptions(boolean processLocalSymbols, boolean markupLocalSymbols,
boolean processExports, boolean processChainedFixups, boolean addChainedFixupsRelocations,
boolean markupMachoLoadCommandData) {
}
@@ -44,7 +44,7 @@ import ghidra.util.task.TaskMonitor;
*/
public class DyldCacheProgramBuilder extends MachoProgramBuilder {
private boolean shouldProcessSymbols;
private DyldCacheOptions options;
/**
* Creates a new {@link DyldCacheProgramBuilder} based on the given information.
@@ -52,18 +52,15 @@ 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 DYLD Cache's bytes came from
* @param shouldProcessSymbols True if symbols should be processed; otherwise, false
* @param shouldAddChainedFixupsRelocations True if relocations should be added for chained
* fixups; otherwise, false
* imported and combined into 1 program; otherwise, false
* @param options Options from the {@link DyldCacheLoader}
* @param log The log
* @param monitor A cancelable task monitor
*/
protected DyldCacheProgramBuilder(Program program, ByteProvider provider, FileBytes fileBytes,
boolean shouldProcessSymbols, boolean shouldAddChainedFixupsRelocations, MessageLog log,
DyldCacheOptions options, MessageLog log,
TaskMonitor monitor) {
super(program, provider, fileBytes, shouldAddChainedFixupsRelocations, log, monitor);
this.shouldProcessSymbols = shouldProcessSymbols;
super(program, provider, fileBytes, log, monitor);
this.options = options;
}
/**
@@ -72,19 +69,15 @@ 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 shouldAddChainedFixupsRelocations True if relocations should be added for chained
* fixups; otherwise, false
* @param options Options from the {@link DyldCacheLoader}
* @param log The log
* @param monitor A cancelable task monitor
* @throws Exception if a problem occurs
*/
public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes,
boolean shouldProcessSymbols, boolean shouldAddChainedFixupsRelocations, MessageLog log,
TaskMonitor monitor) throws Exception {
DyldCacheOptions options, MessageLog log, TaskMonitor monitor) throws Exception {
DyldCacheProgramBuilder dyldCacheProgramBuilder = new DyldCacheProgramBuilder(program,
provider, fileBytes, shouldProcessSymbols, shouldAddChainedFixupsRelocations, log,
monitor);
provider, fileBytes, options, log, monitor);
dyldCacheProgramBuilder.build();
}
@@ -92,7 +85,7 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
protected void build() throws Exception {
try (SplitDyldCache splitDyldCache =
new SplitDyldCache(provider, shouldProcessSymbols, log, monitor)) {
new SplitDyldCache(provider, options.processLocalSymbols(), log, monitor)) {
// Set image base
setDyldCacheImageBase(splitDyldCache.getDyldCacheHeader(0));
@@ -197,7 +190,7 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
monitor.setMessage("Marking up DYLD headers...");
monitor.initialize(1);
dyldCacheHeader.parseFromMemory(program, space, log, monitor);
dyldCacheHeader.markup(program, space, monitor, log);
dyldCacheHeader.markup(program, options.markupLocalSymbols(), space, monitor, log);
monitor.incrementProgress(1);
}
@@ -233,7 +226,7 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
* @throws Exception if there was a problem creating the local symbols
*/
private void createLocalSymbols(DyldCacheHeader dyldCacheHeader) throws Exception {
if (!shouldProcessSymbols) {
if (!options.processLocalSymbols()) {
return;
}
DyldCacheLocalSymbolsInfo localSymbolsInfo = dyldCacheHeader.getLocalSymbolsInfo();
@@ -269,13 +262,17 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
*/
private void fixPageChains(DyldCacheHeader dyldCacheHeader)
throws MemoryAccessException, CancelledException {
if (!options.processChainedFixups()) {
return;
}
// locate slide Info
List<DyldCacheSlideInfoCommon> slideInfos = dyldCacheHeader.getSlideInfos();
for (DyldCacheSlideInfoCommon info : slideInfos) {
int version = info.getVersion();
log.appendMsg("Fixing page chains version: " + version);
info.fixPageChains(program, dyldCacheHeader, shouldAddChainedFixupsRelocations, log,
info.fixPageChains(program, dyldCacheHeader, options.addChainedFixupsRelocations(), log,
monitor);
}
}
@@ -312,21 +309,23 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
}
// Create Exports
monitor.setMessage("Creating DYLIB exports...");
monitor.initialize(infoSet.size());
boolean exportsCreated = false;
for (DyldCacheMachoInfo info : infoSet) {
info.createExports();
monitor.checkCancelled();
monitor.incrementProgress(1);
if (options.processExports()) {
monitor.setMessage("Creating DYLIB exports...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
exportsCreated = info.createExports();
monitor.checkCancelled();
monitor.incrementProgress(1);
}
}
// Create DyldCache Mach-O symbols if local symbols are not present
if (shouldProcessSymbols && !localSymbolsPresent) {
if (options.processLocalSymbols() && !localSymbolsPresent) {
monitor.setMessage("Creating DYLIB symbols...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.createSymbols(exportsCreated);
info.createSymbols(options.processExports() && !exportsCreated);
monitor.checkCancelled();
monitor.incrementProgress(1);
}
@@ -341,6 +340,17 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
monitor.incrementProgress(1);
}
// Markup DyldCache Mach-O headers
if (options.markupMachoLoadCommandData()) {
monitor.setMessage("Marking up DYLIB load command data...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.markupLoadCommandData();
monitor.checkCancelled();
monitor.incrementProgress(1);
}
}
// Add DyldCache Mach-O's to program tree
monitor.setMessage("Adding DYLIB's to program tree...");
monitor.initialize(infoSet.size());
@@ -441,9 +451,16 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
if (!name.isEmpty()) {
listing.setComment(headerAddr, CodeUnit.PLATE_COMMENT, path);
}
}
// TODO: This can be slow. Add an option for it.
//DyldCacheProgramBuilder.this.markupLoadCommandData(header);
/**
* Marks up the Mach-O load command data.
*
* @throws Exception If there was a problem marking up the Mach-O's load command data
* @see DyldCacheProgramBuilder#markupLoadCommandData(MachHeader, String)
*/
public void markupLoadCommandData() throws Exception {
DyldCacheProgramBuilder.this.markupLoadCommandData(header, name);
}
/**
@@ -111,20 +111,21 @@ public class DyldCacheUtils {
* Creates a new {@link SplitDyldCache}
*
* @param baseProvider The {@link ByteProvider} of the "base" DYLD Cache file
* @param shouldProcessSymbols True if symbols should be processed; otherwise, false
* @param shouldProcessLocalSymbols True if local symbols should be processed; otherwise,
* false
* @param log The log
* @param monitor A cancelable task monitor
* @throws IOException If there was an IO-related issue with processing the split DYLD Cache
* @throws CancelledException If the user canceled the operation
*/
public SplitDyldCache(ByteProvider baseProvider, boolean shouldProcessSymbols,
public SplitDyldCache(ByteProvider baseProvider, boolean shouldProcessLocalSymbols,
MessageLog log, TaskMonitor monitor) throws IOException, CancelledException {
// Setup "base" DYLD Cache
monitor.setMessage("Parsing " + baseProvider.getName() + " headers...");
providers.add(baseProvider);
DyldCacheHeader baseHeader = new DyldCacheHeader(new BinaryReader(baseProvider, true));
baseHeader.parseFromFile(shouldProcessSymbols, log, monitor);
baseHeader.parseFromFile(shouldProcessLocalSymbols, log, monitor);
headers.add(baseHeader);
names.add(baseProvider.getName());
@@ -145,7 +146,7 @@ public class DyldCacheUtils {
providers.add(splitProvider);
DyldCacheHeader splitHeader =
new DyldCacheHeader(new BinaryReader(splitProvider, true));
splitHeader.parseFromFile(shouldProcessSymbols, log, monitor);
splitHeader.parseFromFile(shouldProcessLocalSymbols, log, monitor);
headers.add(splitHeader);
names.add(splitFSRL.getName());
uuidToFileMap.put(splitHeader.getUUID(), splitFSRL);
@@ -20,13 +20,13 @@ import java.io.IOException;
import java.nio.file.AccessMode;
import java.util.*;
import ghidra.app.util.*;
import ghidra.app.util.MemoryBlockUtils;
import ghidra.app.util.Option;
import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.macho.*;
import ghidra.app.util.bin.format.ubi.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.formats.gfilesystem.FileSystemService;
import ghidra.framework.model.DomainObject;
import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.listing.Program;
import ghidra.util.LittleEndianDataConverter;
@@ -41,13 +41,6 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
public final static String MACH_O_NAME = "Mac OS X Mach-O";
private static final long MIN_BYTE_LENGTH = 4;
/** Loader option to add relocation entries for chained fixups */
static final String ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME =
"Add relocation entries for chained fixups";
/** Default value for loader option add chained fixups relocation entries */
static final boolean ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT = true;
@Override
public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException {
List<LoadSpec> loadSpecs = new ArrayList<>();
@@ -91,12 +84,10 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
// A Mach-O file may contain PRELINK information. If so, we use a special
// program builder that knows how to deal with it.
if (MachoPrelinkUtils.isMachoPrelink(provider, monitor)) {
MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes,
shouldAddChainedFixupsRelocations(options), log, monitor);
MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes, log, monitor);
}
else {
MachoProgramBuilder.buildProgram(program, provider, fileBytes,
shouldAddChainedFixupsRelocations(options), log, monitor);
MachoProgramBuilder.buildProgram(program, provider, fileBytes, log, monitor);
}
}
catch (CancelledException e) {
@@ -115,24 +106,6 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
return MACH_O_NAME;
}
@Override
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
DomainObject domainObject, boolean loadIntoProgram) {
List<Option> list =
super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram);
if (!loadIntoProgram) {
list.add(new Option(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME,
ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-addChainedFixupsRelocations"));
}
return list;
}
private boolean shouldAddChainedFixupsRelocations(List<Option> options) {
return OptionUtils.getOption(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME, options,
ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT);
}
/**
* Overrides the default implementation to account for Universal Binary (UBI) files.
* These must be specially parsed to find the internal file matching the current architecture.
@@ -46,16 +46,13 @@ 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 shouldAddChainedFixupsRelocations True if relocations should be added for chained
* fixups; otherwise, false.
* @param log The log.
* @param monitor A cancelable task monitor.
* @throws Exception if a problem occurs.
*/
protected MachoPrelinkProgramBuilder(Program program, ByteProvider provider,
FileBytes fileBytes, boolean shouldAddChainedFixupsRelocations, MessageLog log,
TaskMonitor monitor) throws Exception {
super(program, provider, fileBytes, shouldAddChainedFixupsRelocations, log, monitor);
FileBytes fileBytes, MessageLog log, TaskMonitor monitor) throws Exception {
super(program, provider, fileBytes, log, monitor);
}
/**
@@ -64,17 +61,14 @@ 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 addChainedFixupsRelocations True if relocations should be added for chained fixups;
* otherwise, false.
* @param log The log.
* @param monitor A cancelable task monitor.
* @throws Exception if a problem occurs.
*/
public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes,
boolean addChainedFixupsRelocations, MessageLog log, TaskMonitor monitor)
throws Exception {
MessageLog log, TaskMonitor monitor) throws Exception {
MachoPrelinkProgramBuilder machoPrelinkProgramBuilder = new MachoPrelinkProgramBuilder(
program, provider, fileBytes, addChainedFixupsRelocations, log, monitor);
program, provider, fileBytes, log, monitor);
machoPrelinkProgramBuilder.build();
}
@@ -63,7 +63,6 @@ public class MachoProgramBuilder {
protected Program program;
protected ByteProvider provider;
protected FileBytes fileBytes;
protected boolean shouldAddChainedFixupsRelocations;
protected MessageLog log;
protected TaskMonitor monitor;
protected Memory memory;
@@ -76,17 +75,14 @@ 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 shouldAddChainedFixupsRelocations True if relocations should be added for chained
* fixups; otherwise, false.
* @param log The log.
* @param monitor A cancelable task monitor.
*/
protected MachoProgramBuilder(Program program, ByteProvider provider, FileBytes fileBytes,
boolean shouldAddChainedFixupsRelocations, MessageLog log, TaskMonitor monitor) {
MessageLog log, TaskMonitor monitor) {
this.program = program;
this.provider = provider;
this.fileBytes = fileBytes;
this.shouldAddChainedFixupsRelocations = shouldAddChainedFixupsRelocations;
this.log = log;
this.monitor = monitor;
this.memory = program.getMemory();
@@ -100,17 +96,14 @@ 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 addChainedFixupsRelocations True if relocations should be added for chained fixups;
* otherwise, false.
* @param log The log.
* @param monitor A cancelable task monitor.
* @throws Exception if a problem occurs.
*/
public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes,
boolean addChainedFixupsRelocations, MessageLog log, TaskMonitor monitor)
throws Exception {
MessageLog log, TaskMonitor monitor) throws Exception {
MachoProgramBuilder machoProgramBuilder = new MachoProgramBuilder(program, provider,
fileBytes, addChainedFixupsRelocations, log, monitor);
fileBytes, log, monitor);
machoProgramBuilder.build();
}
@@ -146,7 +139,7 @@ public class MachoProgramBuilder {
// Markup structures
markupHeaders(machoHeader, setupHeaderAddr(machoHeader.getAllSegments()));
markupSections();
markupLoadCommandData(machoHeader);
markupLoadCommandData(machoHeader, null);
markupChainedFixups(machoHeader, chainedFixups);
markupProgramVars();
@@ -763,8 +756,7 @@ public class MachoProgramBuilder {
}
public List<Address> processChainedFixups(MachHeader header) throws Exception {
DyldChainedFixups dyldChainedFixups =
new DyldChainedFixups(program, header, shouldAddChainedFixupsRelocations, log, monitor);
DyldChainedFixups dyldChainedFixups = new DyldChainedFixups(program, header, log, monitor);
return dyldChainedFixups.processChainedFixups();
}
@@ -1250,13 +1242,14 @@ public class MachoProgramBuilder {
* Marks up {@link LoadCommand} dadta
*
* @param header The Mach-O header
* @param source A name that represents where the header came from (could be null)
* @throws Exception If there was a problem performing the markup
*/
protected void markupLoadCommandData(MachHeader header) throws Exception {
protected void markupLoadCommandData(MachHeader header, String source) throws Exception {
for (LoadCommand cmd : header.getLoadCommands()) {
Address dataAddr = cmd.getDataAddress(header, space);
if (dataAddr != null) {
cmd.markup(program, header, dataAddr, monitor, log);
cmd.markup(program, header, dataAddr, source, monitor, log);
}
}
}
@@ -181,7 +181,7 @@ public class MachoPrelinkFileSystem extends GFileSystemBase implements GFileSyst
provider.length() - offset, monitor);
ByteProvider providerWrapper =
new ByteProviderWrapper(provider, offset, provider.length() - offset);
MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, false,
MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes,
new MessageLog(), monitor);
AbstractProgramLoader.setProgramProperties(program, providerWrapper,
@@ -626,7 +626,6 @@ The Headless Analyzer uses the command-line parameters discussed below. See <a h
<LI><typewriter>-loader-loadSystemLibraries &lt;true|false&gt;</typewriter></LI>
<LI><typewriter>-loader-libraryLoadDepth &lt;depth&gt;</typewriter></LI>
<LI><typewriter>-loader-libraryDestinationFolder &lt;project path&gt;</typewriter></LI>
<LI><typewriter>-loader-addChainedFixupsRelocations &lt;true|false&gt;</typewriter></LI>
</UL>
</UL>
<br>