mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-1574: Delaying fixing DyldCacheFileSystem slide pointers until the
first provider is requested
This commit is contained in:
@@ -23,6 +23,7 @@ import ghidra.app.util.bin.*;
|
|||||||
import ghidra.app.util.bin.format.macho.*;
|
import ghidra.app.util.bin.format.macho.*;
|
||||||
import ghidra.app.util.bin.format.macho.commands.*;
|
import ghidra.app.util.bin.format.macho.commands.*;
|
||||||
import ghidra.app.util.bin.format.macho.dyld.*;
|
import ghidra.app.util.bin.format.macho.dyld.*;
|
||||||
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.app.util.opinion.DyldCacheUtils.SplitDyldCache;
|
import ghidra.app.util.opinion.DyldCacheUtils.SplitDyldCache;
|
||||||
import ghidra.formats.gfilesystem.FSRL;
|
import ghidra.formats.gfilesystem.FSRL;
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
@@ -60,6 +61,42 @@ public class DyldCacheDylibExtractor {
|
|||||||
return packedSegments.getByteProvider(fsrl);
|
return packedSegments.getByteProvider(fsrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a {@link Map} of {DyldCacheSlideInfoCommon}s to their corresponding
|
||||||
|
* {@link DyldCacheSlideFixup}s
|
||||||
|
*
|
||||||
|
* @param splitDyldCache The {@link SplitDyldCache}
|
||||||
|
* @param monitor {@link TaskMonitor}
|
||||||
|
* @return A {@link Map} of {DyldCacheSlideInfoCommon}s to their corresponding
|
||||||
|
* {@link DyldCacheSlideFixup}s
|
||||||
|
* @throws CancelledException If the user cancelled the operation
|
||||||
|
* @throws IOException If there was an IO-related issue with getting the slide fixups
|
||||||
|
*/
|
||||||
|
public static Map<DyldCacheSlideInfoCommon, List<DyldCacheSlideFixup>> getSlideFixups(
|
||||||
|
SplitDyldCache splitDyldCache, TaskMonitor monitor)
|
||||||
|
throws CancelledException, IOException {
|
||||||
|
Map<DyldCacheSlideInfoCommon, List<DyldCacheSlideFixup>> slideFixupMap = new HashMap<>();
|
||||||
|
MessageLog log = new MessageLog();
|
||||||
|
|
||||||
|
for (int i = 0; i < splitDyldCache.size(); i++) {
|
||||||
|
DyldCacheHeader header = splitDyldCache.getDyldCacheHeader(i);
|
||||||
|
ByteProvider bp = splitDyldCache.getProvider(i);
|
||||||
|
DyldArchitecture arch = header.getArchitecture();
|
||||||
|
for (DyldCacheSlideInfoCommon slideInfo : header.getSlideInfos()) {
|
||||||
|
try (ByteProvider wrapper = new ByteProviderWrapper(bp,
|
||||||
|
slideInfo.getMappingFileOffset(), slideInfo.getMappingSize())) {
|
||||||
|
BinaryReader wrapperReader =
|
||||||
|
new BinaryReader(wrapper, !arch.getEndianness().isBigEndian());
|
||||||
|
List<DyldCacheSlideFixup> fixups = slideInfo.getSlideFixups(wrapperReader,
|
||||||
|
arch.is64bit() ? 8 : 4, log, monitor);
|
||||||
|
slideFixupMap.put(slideInfo, fixups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return slideFixupMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A packed DYLIB that was once living inside of a DYLD shared cache. The DYLIB is said to be
|
* A packed DYLIB that was once living inside of a DYLD shared cache. The DYLIB is said to be
|
||||||
* packed because its segment file bytes, which were not adjacent in its containing DYLD, are
|
* packed because its segment file bytes, which were not adjacent in its containing DYLD, are
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ package ghidra.file.formats.ios.dyldcache;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.util.bin.*;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.bin.format.macho.MachException;
|
import ghidra.app.util.bin.format.macho.MachException;
|
||||||
import ghidra.app.util.bin.format.macho.dyld.*;
|
import ghidra.app.util.bin.format.macho.dyld.*;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
@@ -45,7 +46,7 @@ public class DyldCacheFileSystem extends GFileSystemBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
slideFixupMap.clear();
|
slideFixupMap = null;
|
||||||
addrMap.clear();
|
addrMap.clear();
|
||||||
indexMap.clear();
|
indexMap.clear();
|
||||||
splitDyldCache.close();
|
splitDyldCache.close();
|
||||||
@@ -62,6 +63,11 @@ public class DyldCacheFileSystem extends GFileSystemBase {
|
|||||||
int index = indexMap.get(file);
|
int index = indexMap.get(file);
|
||||||
long machHeaderStartIndexInProvider =
|
long machHeaderStartIndexInProvider =
|
||||||
addr - splitDyldCache.getDyldCacheHeader(index).getBaseAddress();
|
addr - splitDyldCache.getDyldCacheHeader(index).getBaseAddress();
|
||||||
|
|
||||||
|
if (slideFixupMap == null) {
|
||||||
|
slideFixupMap = DyldCacheDylibExtractor.getSlideFixups(splitDyldCache, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DyldCacheDylibExtractor.extractDylib(machHeaderStartIndexInProvider,
|
return DyldCacheDylibExtractor.extractDylib(machHeaderStartIndexInProvider,
|
||||||
splitDyldCache, index, slideFixupMap, file.getFSRL(), monitor);
|
splitDyldCache, index, slideFixupMap, file.getFSRL(), monitor);
|
||||||
@@ -128,26 +134,6 @@ public class DyldCacheFileSystem extends GFileSystemBase {
|
|||||||
monitor.incrementProgress(1);
|
monitor.incrementProgress(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get slide fixups
|
|
||||||
slideFixupMap = new HashMap<>();
|
|
||||||
for (int i = 0; i < splitDyldCache.size(); i++) {
|
|
||||||
DyldCacheHeader header = splitDyldCache.getDyldCacheHeader(i);
|
|
||||||
ByteProvider bp = splitDyldCache.getProvider(i);
|
|
||||||
DyldArchitecture arch = header.getArchitecture();
|
|
||||||
for (DyldCacheSlideInfoCommon slideInfo : header.getSlideInfos()) {
|
|
||||||
try (ByteProvider wrapper = new ByteProviderWrapper(bp,
|
|
||||||
slideInfo.getMappingFileOffset(), slideInfo.getMappingSize())) {
|
|
||||||
BinaryReader wrapperReader =new BinaryReader(wrapper, !arch.getEndianness().isBigEndian());
|
|
||||||
List<DyldCacheSlideFixup> fixups = slideInfo.getSlideFixups(wrapperReader,
|
|
||||||
arch.is64bit() ? 8 : 4, log, monitor);
|
|
||||||
slideFixupMap.put(slideInfo, fixups);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeFile(GFile file, Long addr, Integer index) {
|
private void storeFile(GFile file, Long addr, Integer index) {
|
||||||
|
|||||||
Reference in New Issue
Block a user