GP-3566: Tweaking DyldCacheLoader options

This commit is contained in:
Ryan Kurtz
2023-06-29 12:02:19 -04:00
parent 24dbe4d6c7
commit c9a86de1b0
3 changed files with 146 additions and 103 deletions
@@ -36,24 +36,6 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
public final static String DYLD_CACHE_NAME = "DYLD Cache";
/** 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_LOCAL_SYMBOLS_OPTION_DEFAULT = true;
/** 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";
@@ -67,11 +49,47 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
/** 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)";
/** Loader option to process symbols */
static final String PROCESS_LOCAL_SYMBOLS_OPTION_NAME = "Process local symbols";
/** Default value for loader option to mark up Mach-O load command data */
static final boolean MARKUP_MACHO_LC_DATA_OPTION_DEFAULT = false;
/** Default value for loader option to process symbols */
static final boolean PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT = true;
/** Loader option to mark up symbols */
static final String MARKUP_LOCAL_SYMBOLS_OPTION_NAME = "Markup local symbol nlists";
/** Default value for loader option to mark up symbols */
static final boolean MARKUP_LOCAL_SYMBOLS_OPTION_DEFAULT = false;
/** Loader option to process individual dylib's memory */
static final String PROCESS_DYLIB_MEMORY_OPTION_NAME = "Process dylib memory";
/** Loader option to process individual dylib's memory */
static final boolean PROCESS_DYLIB_MEMORY_OPTION_DEFAULT = true;
/** Loader option to process dylib symbols */
static final String PROCESS_DYLIB_SYMBOLS_OPTION_NAME = "Process dylib symbols";
/** Default value for loader option to process dylib symbols */
static final boolean PROCESS_DYLIB_SYMBOLS_OPTION_DEFAULT = true;
/** Loader option to process dylib exports */
static final String PROCESS_DYLIB_EXPORTS_OPTION_NAME = "Process dylib exports";
/** Default value for loader option to process dylib exports */
static final boolean PROCESS_DYLIB_EXPORTS_OPTION_DEFAULT = true;
/** Loader option to mark up dylib load command data */
static final String MARKUP_DYLIB_LC_DATA_OPTION_NAME = "Markup dylib load command data";
/** Default value for loader option to mark up dylib load command data */
static final boolean MARKUP_DYLIB_LC_DATA_OPTION_DEFAULT = false;
/** Loader option to process libobjc */
static final String PROCESS_DYLIB_LIBOBJC_OPTION_NAME = "Process libobjc";
/** Default value for loader option to process libobjc */
static final boolean PROCESS_DYLIB_LIBOBJC_OPTION_DEFAULT = true;
@Override
public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException {
@@ -127,6 +145,12 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
List<Option> list =
super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram);
if (!loadIntoProgram) {
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(PROCESS_LOCAL_SYMBOLS_OPTION_NAME, PROCESS_LOCAL_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processLocalSymbols"));
@@ -134,37 +158,47 @@ public class DyldCacheLoader extends AbstractProgramWrapperLoader {
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"));
new Option(PROCESS_DYLIB_MEMORY_OPTION_NAME, PROCESS_DYLIB_MEMORY_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibMemory"));
list.add(
new Option(PROCESS_DYLIB_SYMBOLS_OPTION_NAME, PROCESS_DYLIB_SYMBOLS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibSymbols"));
list.add(
new Option(PROCESS_DYLIB_EXPORTS_OPTION_NAME, PROCESS_DYLIB_EXPORTS_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processDylibExports"));
list.add(new Option(MARKUP_DYLIB_LC_DATA_OPTION_NAME,
MARKUP_DYLIB_LC_DATA_OPTION_DEFAULT, Boolean.class,
Loader.COMMAND_LINE_ARG_PREFIX + "-markupDylibLoadCommandData"));
list.add(
new Option(PROCESS_DYLIB_LIBOBJC_OPTION_NAME, PROCESS_DYLIB_LIBOBJC_OPTION_DEFAULT,
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-processLibobjc"));
}
return list;
}
private DyldCacheOptions getDyldCacheOptions(List<Option> options) {
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 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);
boolean processDylibMemory = OptionUtils.getOption(PROCESS_DYLIB_MEMORY_OPTION_NAME,
options, PROCESS_DYLIB_MEMORY_OPTION_DEFAULT);
boolean processDylibSymbols = OptionUtils.getOption(PROCESS_DYLIB_SYMBOLS_OPTION_NAME,
options, PROCESS_DYLIB_SYMBOLS_OPTION_DEFAULT);
boolean processDylibExports = OptionUtils.getOption(PROCESS_DYLIB_EXPORTS_OPTION_NAME,
options, PROCESS_DYLIB_EXPORTS_OPTION_DEFAULT);
boolean markupDylibLoadCommandData = OptionUtils.getOption(MARKUP_DYLIB_LC_DATA_OPTION_NAME,
options, MARKUP_DYLIB_LC_DATA_OPTION_DEFAULT);
boolean processLibobjc = OptionUtils.getOption(PROCESS_DYLIB_LIBOBJC_OPTION_NAME,
options, PROCESS_DYLIB_LIBOBJC_OPTION_DEFAULT);
return new DyldCacheOptions(processChainedFixups, addChainedFixupsRelocations,
processLocalSymbols, markupLocalSymbols, processDylibMemory, processDylibSymbols,
processDylibExports, markupDylibLoadCommandData, processLibobjc);
}
@Override
@@ -18,16 +18,20 @@ 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
* @param processLocalSymbols True if local symbols should be processes; otherwise, false
* @param markupLocalSymbols True if local symbols should be marked up; otherwise, false
* @param processDylibMemory True if individual dylib memory should be processed; otherwise, false
* @param processDylibSymbols True if individual dylib symbols should be processed; otherwise, false
* @param processDylibExports True if individual dylib exports should be processed; otherwise, false
* @param markupDylibLoadCommandData True if individual dylib load command data blocks should be
* marked up; otherwise, false
* @param processLibobjc True if special libobjc should occur; otherwise, false
*/
public record DyldCacheOptions(boolean processLocalSymbols, boolean markupLocalSymbols,
boolean processExports, boolean processChainedFixups, boolean addChainedFixupsRelocations,
boolean markupMachoLoadCommandData) {
public record DyldCacheOptions(boolean processChainedFixups, boolean addChainedFixupsRelocations,
boolean processLocalSymbols, boolean markupLocalSymbols, boolean processDylibMemory,
boolean processDylibSymbols, boolean processDylibExports,
boolean markupDylibLoadCommandData, boolean processLibobjc) {
}
@@ -297,6 +297,8 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
List<DyldCacheImage> mappedImages = dyldCacheHeader.getMappedImages();
monitor.initialize(mappedImages.size());
for (DyldCacheImage mappedImage : mappedImages) {
monitor.checkCancelled();
monitor.incrementProgress(1);
DyldCacheMachoInfo info = new DyldCacheMachoInfo(splitDyldCache, bp,
mappedImage.getAddress() - dyldCacheHeader.getBaseAddress(),
space.getAddress(mappedImage.getAddress()), mappedImage.getPath());
@@ -304,79 +306,82 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
if (libobjcInfo == null && info.name.contains("libobjc.")) {
libobjcInfo = info;
}
monitor.checkCancelled();
monitor.incrementProgress(1);
}
// Create Exports
boolean exportsCreated = false;
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 (options.processLocalSymbols() && !localSymbolsPresent) {
monitor.setMessage("Creating DYLIB symbols...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.createSymbols(options.processExports() && !exportsCreated);
monitor.checkCancelled();
monitor.incrementProgress(1);
}
}
// Markup DyldCache Mach-O headers
// Markup DyldCache DYLIB headers
monitor.setMessage("Marking up DYLIB headers...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.markupHeaders();
monitor.checkCancelled();
monitor.incrementProgress(1);
info.markupHeaders();
}
// Markup DyldCache Mach-O headers
if (options.markupMachoLoadCommandData()) {
if (options.processDylibMemory()) {
// Process DyldCache DYLIB memory blocks
monitor.setMessage("Processing DYLIB memory blocks...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
monitor.checkCancelled();
monitor.incrementProgress(1);
info.processMemoryBlocks();
}
// Add DyldCache Mach-O's to program tree
monitor.setMessage("Adding DYLIB's to program tree...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
monitor.checkCancelled();
monitor.incrementProgress(1);
info.addToProgramTree();
}
}
// Markup DyldCache DYLIB load command data
if (options.markupDylibLoadCommandData()) {
monitor.setMessage("Marking up DYLIB load command data...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
monitor.checkCancelled();
monitor.incrementProgress(1);
info.markupLoadCommandData();
}
}
// Create DYLIB symbols
if (options.processDylibSymbols()) {
monitor.setMessage("Creating DYLIB symbols...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.createSymbols(false);
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());
for (DyldCacheMachoInfo info : infoSet) {
info.addToProgramTree();
monitor.checkCancelled();
monitor.incrementProgress(1);
}
// Process DyldCache DYLIB memory blocks
monitor.setMessage("Processing DYLIB memory blocks...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.processMemoryBlocks();
monitor.checkCancelled();
monitor.incrementProgress(1);
// Create DYLIB Exports
if (options.processDylibExports()) {
monitor.setMessage("Creating DYLIB exports...");
monitor.initialize(infoSet.size());
for (DyldCacheMachoInfo info : infoSet) {
info.createExports();
monitor.checkCancelled();
monitor.incrementProgress(1);
}
}
// Process and markup the libobjc DYLIB
monitor.setMessage("Processing libobjc...");
DyldCacheMachoInfo libObjcInfo =
infoSet.stream().filter(e -> e.name.contains("libobjc.")).findAny().orElse(null);
if (libObjcInfo != null) {
LibObjcDylib libObjcDylib =
new LibObjcDylib(libObjcInfo.header, program, space, log, monitor);
libObjcDylib.markup();
if (options.processLibobjc()) {
monitor.setMessage("Processing libobjc...");
DyldCacheMachoInfo libObjcInfo =
infoSet.stream().filter(e -> e.name.contains("libobjc.")).findAny().orElse(null);
if (libObjcInfo != null) {
LibObjcDylib libObjcDylib =
new LibObjcDylib(libObjcInfo.header, program, space, log, monitor);
libObjcDylib.markup();
}
}
}