From eca1a025c8ed7bffa3db7040d2f61d8216e8b36b Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 25 Mar 2024 13:41:56 -0400 Subject: [PATCH] GP-4461: Fixing some Mach-O string/symbol table load errors --- .../commands/DynamicSymbolTableCommand.java | 2 +- .../util/bin/format/macho/commands/NList.java | 13 ++++++---- .../macho/commands/SymbolTableCommand.java | 2 +- .../app/util/opinion/MachoProgramBuilder.java | 26 ++++++++++++------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java index d60e8bcbf0..6e6c54e43d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java @@ -386,7 +386,7 @@ public class DynamicSymbolTableCommand extends LoadCommand { symbolTableAddr.add(nlistIndex * nlist.getSize()), RefType.DATA, SourceType.IMPORTED, 0); referenceManager.setPrimary(ref, true); - if (stringTableAddr != null) { + if (stringTableAddr != null && nlist.getStringTableIndex() != 0) { Address strAddr = stringTableAddr.add(nlist.getStringTableIndex()); referenceManager.addMemoryReference(dataAddr, strAddr, RefType.DATA, SourceType.IMPORTED, 0); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/NList.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/NList.java index ef4dc3c0fd..12b1eb4ae6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/NList.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/NList.java @@ -69,11 +69,14 @@ public class NList implements StructConverter { * @param stringTableOffset offset of the string table */ public void initString(BinaryReader reader, long stringTableOffset) { - try { - string = reader.readAsciiString(stringTableOffset + n_strx); - } - catch (Exception e) { - string = ""; + string = ""; + if (n_strx != 0) { + try { + string = reader.readAsciiString(stringTableOffset + n_strx); + } + catch (Exception e) { + // use empty string + } } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java index 77a1503032..9cd919ad83 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java @@ -200,7 +200,7 @@ public class SymbolTableCommand extends LoadCommand { Data d = DataUtilities.createData(program, nlistAddr, dt, -1, DataUtilities.ClearDataMode.CHECK_FOR_SPACE); - if (stringTableAddr != null) { + if (stringTableAddr != null && nlist.getStringTableIndex() != 0) { Address strAddr = stringTableAddr.add(nlist.getStringTableIndex()); DataUtilities.createData(program, strAddr, STRING, -1, DataUtilities.ClearDataMode.CHECK_FOR_SPACE); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java index 772c7c49dc..e7e2c09b4e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java @@ -1450,23 +1450,31 @@ public class MachoProgramBuilder { if (address.compareTo(block.getEnd()) > 0) { break; } - int length; try { listing.createData(address, datatype); - length = listing.getDataAt(address).getLength(); + if (datatype instanceof Pointer) { + fixupThumbPointers(address); + } + address = address.add(listing.getDataAt(address).getLength()); } - catch (Exception e) { - // don't worry about exceptions - // may have already been created, by relocation, or chain pointers - if (!(datatype instanceof Pointer)) { + catch (CodeUnitInsertionException e) { + if (datatype instanceof TerminatedStringDataType) { + // Sometimes there are huge strings, like JSON blobs + log.appendMsg("Skipping markup for large string at: " + address); + } + else if (!(datatype instanceof Pointer)) { + // May have already been created, by relocation, or chain pointers + log.appendMsg("Skipping markup for existing pointer at: " + address); + } + else { log.appendException(e); } return; } - if (datatype instanceof Pointer) { - fixupThumbPointers(address); + catch (Exception e) { + log.appendException(e); + return; } - address = address.add(length); } }