mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-5429: Reexport fix for Mach-O object files where header is not at
imagebase
This commit is contained in:
parent
69a66e0eec
commit
1345dbb192
6 changed files with 63 additions and 46 deletions
|
@ -159,7 +159,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
||||||
LoadSpec loadSpec, List<Option> options, MessageLog messageLog, TaskMonitor monitor)
|
LoadSpec loadSpec, List<Option> options, MessageLog log, TaskMonitor monitor)
|
||||||
throws CancelledException, IOException {
|
throws CancelledException, IOException {
|
||||||
if (loadedPrograms.isEmpty() ||
|
if (loadedPrograms.isEmpty() ||
|
||||||
(!isLinkExistingLibraries(options) && !isLoadLibraries(options))) {
|
(!isLinkExistingLibraries(options) && !isLoadLibraries(options))) {
|
||||||
|
@ -167,10 +167,10 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DomainFolder> searchFolders =
|
List<DomainFolder> searchFolders =
|
||||||
getLibrarySearchFolders(loadedPrograms, project, options);
|
getLibrarySearchFolders(loadedPrograms, project, options, log);
|
||||||
|
|
||||||
List<LibrarySearchPath> searchPaths = getLibrarySearchPaths(
|
List<LibrarySearchPath> searchPaths = getLibrarySearchPaths(
|
||||||
loadedPrograms.getFirst().getDomainObject(), loadSpec, options, messageLog, monitor);
|
loadedPrograms.getFirst().getDomainObject(), loadSpec, options, log, monitor);
|
||||||
|
|
||||||
List<Loaded<Program>> saveablePrograms =
|
List<Loaded<Program>> saveablePrograms =
|
||||||
loadedPrograms.stream().filter(Predicate.not(Loaded::shouldDiscard)).toList();
|
loadedPrograms.stream().filter(Predicate.not(Loaded::shouldDiscard)).toList();
|
||||||
|
@ -191,7 +191,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
int id = program.startTransaction("Resolving external references");
|
int id = program.startTransaction("Resolving external references");
|
||||||
try {
|
try {
|
||||||
resolveExternalLibraries(program, saveablePrograms, searchFolders, searchPaths,
|
resolveExternalLibraries(program, saveablePrograms, searchFolders, searchPaths,
|
||||||
options, monitor, messageLog);
|
options, monitor, log);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
program.endTransaction(id, true);
|
program.endTransaction(id, true);
|
||||||
|
@ -286,12 +286,13 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
* @param projectFolderPath The project folder path the program will get saved to. Could be null
|
* @param projectFolderPath The project folder path the program will get saved to. Could be null
|
||||||
* if the program is not getting saved to the project.
|
* if the program is not getting saved to the project.
|
||||||
* @param options a {@link List} of {@link Option}s
|
* @param options a {@link List} of {@link Option}s
|
||||||
|
* @param log The log
|
||||||
* @return The path of the project folder to search for existing libraries, or null if no
|
* @return The path of the project folder to search for existing libraries, or null if no
|
||||||
* project folders can be or should be searched
|
* project folders can be or should be searched
|
||||||
*/
|
*/
|
||||||
protected DomainFolder getLinkSearchFolder(Project project, Program program,
|
protected DomainFolder getLinkSearchFolder(Project project, Program program,
|
||||||
String projectFolderPath, List<Option> options) {
|
String projectFolderPath, List<Option> options, MessageLog log) {
|
||||||
if (!shouldSearchAllPaths(program, options) && !isLinkExistingLibraries(options)) {
|
if (!shouldSearchAllPaths(program, options, log) && !isLinkExistingLibraries(options)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (project == null) {
|
if (project == null) {
|
||||||
|
@ -401,18 +402,19 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
* @param loadedPrograms the list of {@link Loaded} {@link Program}s
|
* @param loadedPrograms the list of {@link Loaded} {@link Program}s
|
||||||
* @param project The {@link Project} to load into. Could be null if there is no project.
|
* @param project The {@link Project} to load into. Could be null if there is no project.
|
||||||
* @param options The {@link List} of {@link Option}s
|
* @param options The {@link List} of {@link Option}s
|
||||||
|
* @param log The log
|
||||||
* @return A {@link List} of library search {@link DomainFolder folders} based on the current
|
* @return A {@link List} of library search {@link DomainFolder folders} based on the current
|
||||||
* options
|
* options
|
||||||
*/
|
*/
|
||||||
protected List<DomainFolder> getLibrarySearchFolders(List<Loaded<Program>> loadedPrograms,
|
protected List<DomainFolder> getLibrarySearchFolders(List<Loaded<Program>> loadedPrograms,
|
||||||
Project project, List<Option> options) {
|
Project project, List<Option> options, MessageLog log) {
|
||||||
List<DomainFolder> searchFolders = new ArrayList<>();
|
List<DomainFolder> searchFolders = new ArrayList<>();
|
||||||
String projectFolderPath = loadedPrograms.get(0).getProjectFolderPath();
|
String projectFolderPath = loadedPrograms.get(0).getProjectFolderPath();
|
||||||
String destPath = getLibraryDestinationFolderPath(project, projectFolderPath, options);
|
String destPath = getLibraryDestinationFolderPath(project, projectFolderPath, options);
|
||||||
DomainFolder destSearchFolder =
|
DomainFolder destSearchFolder =
|
||||||
getLibraryDestinationSearchFolder(project, destPath, options);
|
getLibraryDestinationSearchFolder(project, destPath, options);
|
||||||
DomainFolder linkSearchFolder = getLinkSearchFolder(project,
|
DomainFolder linkSearchFolder = getLinkSearchFolder(project,
|
||||||
loadedPrograms.getFirst().getDomainObject(), projectFolderPath, options);
|
loadedPrograms.getFirst().getDomainObject(), projectFolderPath, options, log);
|
||||||
Optional.ofNullable(destSearchFolder).ifPresent(searchFolders::add);
|
Optional.ofNullable(destSearchFolder).ifPresent(searchFolders::add);
|
||||||
Optional.ofNullable(linkSearchFolder).ifPresent(searchFolders::add);
|
Optional.ofNullable(linkSearchFolder).ifPresent(searchFolders::add);
|
||||||
return searchFolders;
|
return searchFolders;
|
||||||
|
@ -424,9 +426,10 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
*
|
*
|
||||||
* @param program The {@link Program} being loaded
|
* @param program The {@link Program} being loaded
|
||||||
* @param options a {@link List} of {@link Option}s
|
* @param options a {@link List} of {@link Option}s
|
||||||
|
* @param log The log
|
||||||
* @return True if all possible search paths should be used, regardless of what options are set
|
* @return True if all possible search paths should be used, regardless of what options are set
|
||||||
*/
|
*/
|
||||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options) {
|
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,7 +530,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
List<LibrarySearchPath> searchPaths =
|
List<LibrarySearchPath> searchPaths =
|
||||||
getLibrarySearchPaths(program, desiredLoadSpec, options, log, monitor);
|
getLibrarySearchPaths(program, desiredLoadSpec, options, log, monitor);
|
||||||
DomainFolder linkSearchFolder =
|
DomainFolder linkSearchFolder =
|
||||||
getLinkSearchFolder(project, program, projectFolderPath, options);
|
getLinkSearchFolder(project, program, projectFolderPath, options, log);
|
||||||
String libraryDestFolderPath =
|
String libraryDestFolderPath =
|
||||||
getLibraryDestinationFolderPath(project, projectFolderPath, options);
|
getLibraryDestinationFolderPath(project, projectFolderPath, options);
|
||||||
DomainFolder libraryDestFolder =
|
DomainFolder libraryDestFolder =
|
||||||
|
@ -554,7 +557,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
log.appendMsg("Found %s in %s...".formatted(library, linkSearchFolder));
|
log.appendMsg("Found %s in %s...".formatted(library, linkSearchFolder));
|
||||||
log.appendMsg("------------------------------------------------\n");
|
log.appendMsg("------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
else if (isLoadLibraries(options) || shouldSearchAllPaths(program, options)) {
|
else if (isLoadLibraries(options) || shouldSearchAllPaths(program, options, log)) {
|
||||||
Loaded<Program> loadedLibrary = loadLibraryFromSearchPaths(library, provider,
|
Loaded<Program> loadedLibrary = loadLibraryFromSearchPaths(library, provider,
|
||||||
customSearchPaths, libraryDestFolderPath, unprocessed, depth,
|
customSearchPaths, libraryDestFolderPath, unprocessed, depth,
|
||||||
desiredLoadSpec, options, log, consumer, monitor);
|
desiredLoadSpec, options, log, consumer, monitor);
|
||||||
|
@ -894,12 +897,11 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
|
|
||||||
private void resolveExternalLibraries(Program program, List<Loaded<Program>> loadedPrograms,
|
private void resolveExternalLibraries(Program program, List<Loaded<Program>> loadedPrograms,
|
||||||
List<DomainFolder> searchFolders, List<LibrarySearchPath> fsSearchPaths,
|
List<DomainFolder> searchFolders, List<LibrarySearchPath> fsSearchPaths,
|
||||||
List<Option> options, TaskMonitor monitor, MessageLog messageLog)
|
List<Option> options, TaskMonitor monitor, MessageLog log)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
ExternalManager extManager = program.getExternalManager();
|
ExternalManager extManager = program.getExternalManager();
|
||||||
String[] extLibNames = extManager.getExternalLibraryNames();
|
String[] extLibNames = extManager.getExternalLibraryNames();
|
||||||
messageLog.appendMsg(
|
log.appendMsg("Linking the External Programs of '%s' to imported libraries..."
|
||||||
"Linking the External Programs of '%s' to imported libraries..."
|
|
||||||
.formatted(program.getName()));
|
.formatted(program.getName()));
|
||||||
for (String externalLibName : extLibNames) {
|
for (String externalLibName : extLibNames) {
|
||||||
if (Library.UNKNOWN.equals(externalLibName)) {
|
if (Library.UNKNOWN.equals(externalLibName)) {
|
||||||
|
@ -911,7 +913,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
String path = match.getProjectFolderPath() + match.getName();
|
String path = match.getProjectFolderPath() + match.getName();
|
||||||
extManager.setExternalPath(externalLibName, path, false);
|
extManager.setExternalPath(externalLibName, path, false);
|
||||||
messageLog.appendMsg(" [" + externalLibName + "] -> [" + path + "]");
|
log.appendMsg(" [" + externalLibName + "] -> [" + path + "]");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
@ -921,14 +923,14 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
if (alreadyImportedLib != null) {
|
if (alreadyImportedLib != null) {
|
||||||
extManager.setExternalPath(externalLibName,
|
extManager.setExternalPath(externalLibName,
|
||||||
alreadyImportedLib.getPathname(), false);
|
alreadyImportedLib.getPathname(), false);
|
||||||
messageLog.appendMsg(" [" + externalLibName + "] -> [" +
|
log.appendMsg(" [" + externalLibName + "] -> [" +
|
||||||
alreadyImportedLib.getPathname() + "] (previously imported)");
|
alreadyImportedLib.getPathname() + "] (previously imported)");
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
messageLog.appendMsg(" [" + externalLibName + "] -> not found in project");
|
log.appendMsg(" [" + externalLibName + "] -> not found in project");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,7 +938,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
Msg.error(this, "Bad library name: " + externalLibName, e);
|
Msg.error(this, "Bad library name: " + externalLibName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
messageLog.appendMsg("------------------------------------------------\n");
|
log.appendMsg("------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1023,7 +1025,7 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||||
*/
|
*/
|
||||||
protected List<LibrarySearchPath> getLibrarySearchPaths(Program program, LoadSpec loadSpec,
|
protected List<LibrarySearchPath> getLibrarySearchPaths(Program program, LoadSpec loadSpec,
|
||||||
List<Option> options, MessageLog log, TaskMonitor monitor) throws CancelledException {
|
List<Option> options, MessageLog log, TaskMonitor monitor) throws CancelledException {
|
||||||
if (!isLoadLibraries(options) && !shouldSearchAllPaths(program, options)) {
|
if (!isLoadLibraries(options) && !shouldSearchAllPaths(program, options, log)) {
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ public abstract class AbstractOrdinalSupportLoader extends AbstractLibrarySuppor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options) {
|
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||||
return shouldPerformOrdinalLookup(options);
|
return shouldPerformOrdinalLookup(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.util.LittleEndianDataConverter;
|
import ghidra.util.LittleEndianDataConverter;
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
@ -310,20 +309,25 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
* set and the Mach-O actually has {@code LC_REEXPORT_DYLIB} entries.
|
* set and the Mach-O actually has {@code LC_REEXPORT_DYLIB} entries.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options) {
|
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||||
if (super.shouldSearchAllPaths(program, options)) {
|
if (super.shouldSearchAllPaths(program, options, log)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (shouldPerformReexports(options)) {
|
if (shouldPerformReexports(options)) {
|
||||||
try {
|
try {
|
||||||
ByteProvider provider = new MemoryByteProvider(program.getMemory(),
|
Symbol header =
|
||||||
program.getImageBase());
|
program.getSymbolTable().getSymbols(MachoProgramBuilder.HEADER_SYMBOL).next();
|
||||||
if (new MachHeader(provider).parseAndCheck(LoadCommandTypes.LC_REEXPORT_DYLIB)) {
|
if (header == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ByteProvider p = new MemoryByteProvider(program.getMemory(), header.getAddress());
|
||||||
|
if (new MachHeader(p).parseAndCheck(LoadCommandTypes.LC_REEXPORT_DYLIB)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException | MachException e) {
|
catch (Exception e) {
|
||||||
Msg.error(this, "Failed to parse Mach-O header for: " + program.getName());
|
log.appendMsg("Failed to parse Mach-O header for: '%s': %s"
|
||||||
|
.formatted(program.getName(), e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -348,7 +352,7 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (String path : getReexportPaths(lib)) {
|
for (String path : getReexportPaths(lib, log)) {
|
||||||
unprocessed.add(new UnprocessedLibrary(path, depth, depth == 1));
|
unprocessed.add(new UnprocessedLibrary(path, depth, depth == 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,12 +365,21 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
* Gets a {@link List} of reexport library paths from the given {@link Program}
|
* Gets a {@link List} of reexport library paths from the given {@link Program}
|
||||||
*
|
*
|
||||||
* @param program The {@link Program}
|
* @param program The {@link Program}
|
||||||
|
* @param log The log
|
||||||
* @return A {@link List} of reexport library paths from the given {@link Program}
|
* @return A {@link List} of reexport library paths from the given {@link Program}
|
||||||
* @throws MachException if there was a problem parsing the Mach-O {@link Program}
|
* @throws MachException if there was a problem parsing the Mach-O {@link Program}
|
||||||
* @throws IOException if there was an IO-related error
|
* @throws IOException if there was an IO-related error
|
||||||
*/
|
*/
|
||||||
private List<String> getReexportPaths(Program program) throws MachException, IOException {
|
private List<String> getReexportPaths(Program program, MessageLog log)
|
||||||
ByteProvider p = new MemoryByteProvider(program.getMemory(), program.getImageBase());
|
throws MachException, IOException {
|
||||||
|
Symbol header =
|
||||||
|
program.getSymbolTable().getSymbols(MachoProgramBuilder.HEADER_SYMBOL).next();
|
||||||
|
if (header == null) {
|
||||||
|
log.appendMsg("Failed to lookup reexport paths...couldn't find '%s' symbol"
|
||||||
|
.formatted(MachoProgramBuilder.HEADER_SYMBOL));
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
ByteProvider p = new MemoryByteProvider(program.getMemory(), header.getAddress());
|
||||||
return new MachHeader(p).parseReexports()
|
return new MachHeader(p).parseReexports()
|
||||||
.stream()
|
.stream()
|
||||||
.map(DynamicLibraryCommand::getDynamicLibrary)
|
.map(DynamicLibraryCommand::getDynamicLibrary)
|
||||||
|
@ -382,17 +395,16 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
protected void postLoadProgramFixups(List<Loaded<Program>> loadedPrograms, Project project,
|
||||||
LoadSpec loadSpec, List<Option> options, MessageLog messageLog, TaskMonitor monitor)
|
LoadSpec loadSpec, List<Option> options, MessageLog log, TaskMonitor monitor)
|
||||||
throws CancelledException, IOException {
|
throws CancelledException, IOException {
|
||||||
|
|
||||||
if (shouldPerformReexports(options)) {
|
if (shouldPerformReexports(options)) {
|
||||||
|
|
||||||
List<DomainFolder> searchFolders =
|
List<DomainFolder> searchFolders =
|
||||||
getLibrarySearchFolders(loadedPrograms, project, options);
|
getLibrarySearchFolders(loadedPrograms, project, options, log);
|
||||||
|
|
||||||
List<LibrarySearchPath> searchPaths =
|
List<LibrarySearchPath> searchPaths = getLibrarySearchPaths(
|
||||||
getLibrarySearchPaths(loadedPrograms.getFirst().getDomainObject(), loadSpec,
|
loadedPrograms.getFirst().getDomainObject(), loadSpec, options, log, monitor);
|
||||||
options, messageLog, monitor);
|
|
||||||
|
|
||||||
monitor.initialize(loadedPrograms.size());
|
monitor.initialize(loadedPrograms.size());
|
||||||
for (Loaded<Program> loadedProgram : loadedPrograms) {
|
for (Loaded<Program> loadedProgram : loadedPrograms) {
|
||||||
|
@ -402,10 +414,10 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
int id = program.startTransaction("Reexporting");
|
int id = program.startTransaction("Reexporting");
|
||||||
try {
|
try {
|
||||||
reexport(program, loadedPrograms, searchFolders, searchPaths, options, monitor,
|
reexport(program, loadedPrograms, searchFolders, searchPaths, options, monitor,
|
||||||
messageLog);
|
log);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
messageLog.appendException(e);
|
log.appendException(e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
program.endTransaction(id, true);
|
program.endTransaction(id, true);
|
||||||
|
@ -413,7 +425,7 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.postLoadProgramFixups(loadedPrograms, project, loadSpec, options, messageLog,
|
super.postLoadProgramFixups(loadedPrograms, project, loadSpec, options, log,
|
||||||
monitor);
|
monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,16 +440,16 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
* @param searchPaths A {@link List} of file system search paths that will be searched
|
* @param searchPaths A {@link List} of file system search paths that will be searched
|
||||||
* @param options The load options
|
* @param options The load options
|
||||||
* @param monitor A cancelable task monitor
|
* @param monitor A cancelable task monitor
|
||||||
* @param messageLog The log
|
* @param log The log
|
||||||
* @throws CancelledException if the user cancelled the load operation
|
* @throws CancelledException if the user cancelled the load operation
|
||||||
* @throws IOException if there was an IO-related error during the load
|
* @throws IOException if there was an IO-related error during the load
|
||||||
*/
|
*/
|
||||||
private void reexport(Program program, List<Loaded<Program>> loadedPrograms,
|
private void reexport(Program program, List<Loaded<Program>> loadedPrograms,
|
||||||
List<DomainFolder> searchFolders, List<LibrarySearchPath> searchPaths,
|
List<DomainFolder> searchFolders, List<LibrarySearchPath> searchPaths,
|
||||||
List<Option> options, TaskMonitor monitor, MessageLog messageLog)
|
List<Option> options, TaskMonitor monitor, MessageLog log)
|
||||||
throws CancelledException, Exception {
|
throws CancelledException, Exception {
|
||||||
|
|
||||||
for (String path : getReexportPaths(program)) {
|
for (String path : getReexportPaths(program, log)) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
Program programToRelease = null;
|
Program programToRelease = null;
|
||||||
try {
|
try {
|
||||||
|
@ -469,7 +481,7 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.toList();
|
.toList();
|
||||||
Address addr = MachoProgramUtils.addExternalBlock(program,
|
Address addr = MachoProgramUtils.addExternalBlock(program,
|
||||||
reexportedSymbols.size() * 8, messageLog);
|
reexportedSymbols.size() * 8, log);
|
||||||
monitor.initialize(reexportedSymbols.size(), "Reexporting symbols...");
|
monitor.initialize(reexportedSymbols.size(), "Reexporting symbols...");
|
||||||
for (Symbol symbol : reexportedSymbols) {
|
for (Symbol symbol : reexportedSymbols) {
|
||||||
monitor.increment();
|
monitor.increment();
|
||||||
|
|
|
@ -66,6 +66,8 @@ import ghidra.util.task.TaskMonitor;
|
||||||
*/
|
*/
|
||||||
public class MachoProgramBuilder {
|
public class MachoProgramBuilder {
|
||||||
|
|
||||||
|
public static final String HEADER_SYMBOL = "MACH_HEADER";
|
||||||
|
|
||||||
protected MachHeader machoHeader;
|
protected MachHeader machoHeader;
|
||||||
protected Program program;
|
protected Program program;
|
||||||
protected ByteProvider provider;
|
protected ByteProvider provider;
|
||||||
|
@ -975,6 +977,7 @@ public class MachoProgramBuilder {
|
||||||
try {
|
try {
|
||||||
DataUtilities.createData(program, headerAddr, header.toDataType(), -1,
|
DataUtilities.createData(program, headerAddr, header.toDataType(), -1,
|
||||||
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
||||||
|
program.getSymbolTable().createLabel(headerAddr, HEADER_SYMBOL, SourceType.IMPORTED);
|
||||||
|
|
||||||
monitor.initialize(header.getLoadCommands().size(), "Marking up header...");
|
monitor.initialize(header.getLoadCommands().size(), "Marking up header...");
|
||||||
for (LoadCommand loadCommand : header.getLoadCommands()) {
|
for (LoadCommand loadCommand : header.getLoadCommands()) {
|
||||||
|
|
|
@ -169,7 +169,7 @@ public class DyldCacheExtractLoader extends MachoLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options) {
|
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class MachoFileSetExtractLoader extends MachoLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldSearchAllPaths(Program program, List<Option> options) {
|
protected boolean shouldSearchAllPaths(Program program, List<Option> options, MessageLog log) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue