mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-3728: Libraries extracted from the dyld_shared_cache filesystem now
contain local symbol information, which reduces the occurrence of "<redacted>" primary symbols
This commit is contained in:
parent
3938a7f97f
commit
0e3e3cccbf
8 changed files with 121 additions and 27 deletions
|
@ -152,6 +152,9 @@ public class DyldCacheDylibExtractor {
|
|||
// the DYLIB we are extracting, resulting in a significantly smaller file.
|
||||
if (segment == linkEditSegment) {
|
||||
for (LoadCommand cmd : machoHeader.getLoadCommands()) {
|
||||
if (cmd instanceof SymbolTableCommand symbolTable) {
|
||||
symbolTable.addSymbols(getLocalSymbols(splitDyldCache));
|
||||
}
|
||||
int offset = cmd.getLinkerDataOffset();
|
||||
int size = cmd.getLinkerDataSize();
|
||||
if (offset == 0 || size == 0) {
|
||||
|
@ -217,6 +220,31 @@ public class DyldCacheDylibExtractor {
|
|||
return new ByteArrayProvider(packed, fsrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link List} of local {@link NList symbol}s
|
||||
*
|
||||
* @param splitDyldCache The {@link SplitDyldCache}
|
||||
* @return A {@link List} of local {@link NList symbol}s (could be empty)
|
||||
*/
|
||||
private List<NList> getLocalSymbols(SplitDyldCache splitDyldCache) {
|
||||
long base = splitDyldCache.getDyldCacheHeader(0).getBaseAddress();
|
||||
for (int i = 0; i < splitDyldCache.size(); i++) {
|
||||
DyldCacheHeader header = splitDyldCache.getDyldCacheHeader(i);
|
||||
DyldCacheLocalSymbolsInfo info = header.getLocalSymbolsInfo();
|
||||
if (info == null) {
|
||||
continue;
|
||||
}
|
||||
for (DyldCacheLocalSymbolsEntry entry : info.getLocalSymbolsEntries()) {
|
||||
int index = entry.getNListStartIndex();
|
||||
int count = entry.getNListCount();
|
||||
if (base + entry.getDylibOffset() == textSegment.getVMaddress() && count > 0) {
|
||||
return info.getNList().subList(index, index + count);
|
||||
}
|
||||
}
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a packed __LINKEDIT segment array
|
||||
*
|
||||
|
@ -233,16 +261,14 @@ public class DyldCacheDylibExtractor {
|
|||
for (LoadCommand cmd : packedLinkEditDataStarts.keySet()) {
|
||||
if (cmd instanceof SymbolTableCommand symbolTable &&
|
||||
symbolTable.getNumberOfSymbols() > 0) {
|
||||
byte[] packedSymbolStringTable = new byte[cmd.getLinkerDataSize()];
|
||||
List<NList> symbols = symbolTable.getSymbols();
|
||||
byte[] packedSymbolStringTable = new byte[NList.getSize(symbols)];
|
||||
int nlistIndex = 0;
|
||||
int stringIndex = symbols.get(0).getSize() * symbols.size();
|
||||
int stringIndexOrig = stringIndex;
|
||||
for (NList nlist : symbols) {
|
||||
byte[] nlistArray = nlistToArray(nlist, stringIndex);
|
||||
byte[] nlistArray = nlistToArray(nlist, stringIndex - stringIndexOrig);
|
||||
byte[] stringArray = nlist.getString().getBytes(StandardCharsets.US_ASCII);
|
||||
System.arraycopy(toBytes(stringIndex - stringIndexOrig, 4), 0, nlistArray,
|
||||
0, 4);
|
||||
System.arraycopy(nlistArray, 0, packedSymbolStringTable, nlistIndex,
|
||||
nlistArray.length);
|
||||
System.arraycopy(stringArray, 0, packedSymbolStringTable, stringIndex,
|
||||
|
@ -394,11 +420,13 @@ public class DyldCacheDylibExtractor {
|
|||
if (cmd.getSymbolOffset() > 0) {
|
||||
long symbolOffset = fixup(cmd.getStartIndex() + 0x8, getLinkEditAdjustment(cmd), 4,
|
||||
linkEditSegment);
|
||||
set(cmd.getStartIndex() + 0xc, cmd.getNumberOfSymbols(), 4);
|
||||
if (cmd.getStringTableOffset() > 0) {
|
||||
if (cmd.getNumberOfSymbols() > 0) {
|
||||
set(cmd.getStartIndex() + 0x10,
|
||||
symbolOffset + cmd.getNumberOfSymbols() * cmd.getSymbolAt(0).getSize(),
|
||||
4);
|
||||
set(cmd.getStartIndex() + 0x14, cmd.getStringTableSize(), 4);
|
||||
}
|
||||
else {
|
||||
set(cmd.getStartIndex() + 0x10, symbolOffset, 4);
|
||||
|
|
|
@ -120,7 +120,7 @@ public class DyldCacheFileSystem extends GFileSystemBase {
|
|||
MessageLog log = new MessageLog();
|
||||
monitor.setMessage("Opening DYLD cache...");
|
||||
|
||||
splitDyldCache = new SplitDyldCache(provider, false, log, monitor);
|
||||
splitDyldCache = new SplitDyldCache(provider, true, log, monitor);
|
||||
for (int i = 0; i < splitDyldCache.size(); i++) {
|
||||
DyldCacheHeader header = splitDyldCache.getDyldCacheHeader(i);
|
||||
monitor.setMessage("Find files...");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue