mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 03:45:33 +08:00
GP-3566: Tweaking DyldCacheLoader options
This commit is contained in:
@@ -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) {
|
||||
}
|
||||
|
||||
+57
-52
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user