mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-28 16:59:50 +08:00
GP-3770: Fixing Mach-o PRELINK check
This commit is contained in:
@@ -90,7 +90,8 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
|||||||
|
|
||||||
// A Mach-O file may contain PRELINK information. If so, we use a special
|
// A Mach-O file may contain PRELINK information. If so, we use a special
|
||||||
// program builder that knows how to deal with it.
|
// program builder that knows how to deal with it.
|
||||||
if (MachoPrelinkUtils.isMachoPrelink(provider, true, monitor)) {
|
if (MachoPrelinkUtils.isMachoPrelink(provider, monitor) ||
|
||||||
|
MachoPrelinkUtils.isMachoFileset(provider)) {
|
||||||
MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes, log, monitor);
|
MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes, log, monitor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -37,23 +37,22 @@ import ghidra.util.task.TaskMonitor;
|
|||||||
public class MachoPrelinkUtils {
|
public class MachoPrelinkUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if the given {@link ByteProvider} is a Mach-O PRELINK binary
|
* Check to see if the given {@link ByteProvider} is a Mach-O PRELINK binary.
|
||||||
|
* <p>
|
||||||
|
* NOTE: This method will return false if the binary is a Mach-O file set.
|
||||||
*
|
*
|
||||||
* @param provider The {@link ByteProvider} to check
|
* @param provider The {@link ByteProvider} to check
|
||||||
* @param allowFileset True if Mach-O file sets should be considered a PRELINK binary;
|
|
||||||
* otherwise, false
|
|
||||||
* @param monitor A monitor
|
* @param monitor A monitor
|
||||||
* @return True if the given {@link ByteProvider} is a Mach-O PRELINK binary; otherwise, false
|
* @return True if the given {@link ByteProvider} is a Mach-O PRELINK binary; otherwise, false
|
||||||
*/
|
*/
|
||||||
public static boolean isMachoPrelink(ByteProvider provider, boolean allowFileset,
|
public static boolean isMachoPrelink(ByteProvider provider, TaskMonitor monitor) {
|
||||||
TaskMonitor monitor) {
|
|
||||||
try {
|
try {
|
||||||
MachHeader header = new MachHeader(provider);
|
MachHeader header = new MachHeader(provider);
|
||||||
boolean hasPrelinkSegment = new MachHeader(provider).parseSegments()
|
boolean hasPrelinkSegment = new MachHeader(provider).parseSegments()
|
||||||
.stream()
|
.stream()
|
||||||
.anyMatch(segment -> segment.getSegmentName().startsWith("__PRELINK"));
|
.anyMatch(segment -> segment.getSegmentName().startsWith("__PRELINK"));
|
||||||
boolean hasFileSet = header.parseAndCheck(LoadCommandTypes.LC_FILESET_ENTRY);
|
boolean hasFileSet = header.parseAndCheck(LoadCommandTypes.LC_FILESET_ENTRY);
|
||||||
return hasPrelinkSegment && allowFileset && hasFileSet;
|
return hasPrelinkSegment && !hasFileSet;
|
||||||
}
|
}
|
||||||
catch (MachException | IOException e) {
|
catch (MachException | IOException e) {
|
||||||
// Assume it's not a Mach-O PRELINK...fall through
|
// Assume it's not a Mach-O PRELINK...fall through
|
||||||
@@ -61,6 +60,22 @@ public class MachoPrelinkUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if the given {@link ByteProvider} is a Mach-O file set
|
||||||
|
*
|
||||||
|
* @param provider The {@link ByteProvider} to check
|
||||||
|
* @return True if the given {@link ByteProvider} is a Mach-O file set; otherwise, false
|
||||||
|
*/
|
||||||
|
public static boolean isMachoFileset(ByteProvider provider) {
|
||||||
|
try {
|
||||||
|
return new MachHeader(provider).parseAndCheck(LoadCommandTypes.LC_FILESET_ENTRY);
|
||||||
|
}
|
||||||
|
catch (MachException | IOException e) {
|
||||||
|
// Assume it's not a Mach-O file set...fall through
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the provider looking for PRELINK XML.
|
* Parses the provider looking for PRELINK XML.
|
||||||
*
|
*
|
||||||
|
|||||||
+2
-10
@@ -18,9 +18,7 @@ package ghidra.file.formats.ios.fileset;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.bin.format.macho.MachException;
|
import ghidra.app.util.opinion.MachoPrelinkUtils;
|
||||||
import ghidra.app.util.bin.format.macho.MachHeader;
|
|
||||||
import ghidra.app.util.bin.format.macho.commands.LoadCommandTypes;
|
|
||||||
import ghidra.formats.gfilesystem.FSRLRoot;
|
import ghidra.formats.gfilesystem.FSRLRoot;
|
||||||
import ghidra.formats.gfilesystem.FileSystemService;
|
import ghidra.formats.gfilesystem.FileSystemService;
|
||||||
import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider;
|
import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider;
|
||||||
@@ -46,12 +44,6 @@ public class MachoFileSetFileSystemFactory implements
|
|||||||
@Override
|
@Override
|
||||||
public boolean probe(ByteProvider byteProvider, FileSystemService fsService,
|
public boolean probe(ByteProvider byteProvider, FileSystemService fsService,
|
||||||
TaskMonitor monitor) throws IOException, CancelledException {
|
TaskMonitor monitor) throws IOException, CancelledException {
|
||||||
try {
|
return MachoPrelinkUtils.isMachoFileset(byteProvider);
|
||||||
return new MachHeader(byteProvider).parseAndCheck(LoadCommandTypes.LC_FILESET_ENTRY);
|
|
||||||
}
|
|
||||||
catch (MachException e) {
|
|
||||||
// Assume it's not a Mach-O...fall through
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@ public class MachoPrelinkFileSystem extends GFileSystemBase implements GFileSyst
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(TaskMonitor monitor) throws IOException {
|
public boolean isValid(TaskMonitor monitor) throws IOException {
|
||||||
return MachoPrelinkUtils.isMachoPrelink(provider, false, monitor);
|
return MachoPrelinkUtils.isMachoPrelink(provider, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user