mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-26 07:16:57 +08:00
GP-3566: Adjusted MachoLoader and DyldCacheLoader options
This commit is contained in:
+3
-3
@@ -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) {
|
||||
|
||||
+3
-3
@@ -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,
|
||||
|
||||
+3
-3
@@ -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) {
|
||||
|
||||
+7
-4
@@ -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
|
||||
|
||||
+3
-2
@@ -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;
|
||||
}
|
||||
|
||||
+7
-4
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-13
@@ -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
|
||||
|
||||
+9
-6
@@ -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);
|
||||
|
||||
+1
-3
@@ -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) {
|
||||
}
|
||||
+46
-29
@@ -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.
|
||||
|
||||
+4
-10
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+8
-15
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 <true|false></typewriter></LI>
|
||||
<LI><typewriter>-loader-libraryLoadDepth <depth></typewriter></LI>
|
||||
<LI><typewriter>-loader-libraryDestinationFolder <project path></typewriter></LI>
|
||||
<LI><typewriter>-loader-addChainedFixupsRelocations <true|false></typewriter></LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<br>
|
||||
|
||||
Reference in New Issue
Block a user