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 9192cac750..cdb6eb2a06 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 @@ -124,7 +124,7 @@ public class MachoProgramBuilder { processEntryPoint(); boolean exportsFound = processExports(machoHeader); processSymbolTables(machoHeader, !exportsFound); - processIndirectSymbols(); + processStubs(); processUndefinedSymbols(); processAbsoluteSymbols(); List
chainedFixups = processChainedFixups(machoHeader); @@ -570,19 +570,8 @@ public class MachoProgramBuilder { } } - protected void processIndirectSymbols() throws Exception { - // We only want to directly handle indirect symbols on incomplete dylibs that were extracted - // from a dyld_shared_cache. If the Mach-O is fully-formed and contains binding information - // (found in the DyldChainedFixupsCommand or DyldInfoCommand), thunk analysis properly - // associates indirect symbols with their "real" symbol and we shouldn't do anything here. - // We hope to one day include binding information in our extracted dylibs, at which point - // this method can fully go away. - if (machoHeader.getFirstLoadCommand(DyldChainedFixupsCommand.class) != null || - machoHeader.getFirstLoadCommand(DyldInfoCommand.class) != null) { - return; - } - - monitor.setMessage("Processing indirect symbols..."); + protected void processStubs() throws Exception { + monitor.setMessage("Processing stubs..."); SymbolTableCommand symbolTableCommand = machoHeader.getFirstLoadCommand(SymbolTableCommand.class); @@ -598,24 +587,14 @@ public class MachoProgramBuilder { return; } - List sectionTypes = List.of(SectionTypes.S_NON_LAZY_SYMBOL_POINTERS, - SectionTypes.S_LAZY_SYMBOL_POINTERS, SectionTypes.S_SYMBOL_STUBS); - - List
sections = machoHeader.getAllSections() - .stream() - .filter(s -> sectionTypes.contains(s.getType())) - .toList(); - - for (Section section : sections) { + for (Section section : machoHeader.getAllSections()) { if (monitor.isCancelled()) { return; } - if (section.getSize() == 0) { + if (section.getSize() == 0 || section.getType() != SectionTypes.S_SYMBOL_STUBS) { continue; } - Namespace namespace = createNamespace(section.getSectionName()); - int indirectSymbolTableIndex = section.getReserved1(); int symbolSize = machoHeader.getAddressSize(); @@ -632,19 +611,19 @@ public class MachoProgramBuilder { } int symbolIndex = indirectSymbols[i]; NList symbol = symbolTableCommand.getSymbolAt(symbolIndex); - if (symbol != null) { - String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true); - if (name != null && name.length() > 0) { - try { - program.getSymbolTable() - .createLabel(startAddr, name, namespace, SourceType.IMPORTED); - } - catch (Exception e) { - log.appendMsg("Unable to create indirect symbol " + name); - log.appendException(e); - } + if (symbol == null) { + continue; + } + String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true); + if (name != null && name.length() > 0) { + Function stubFunc = createOneByteFunction(name, startAddr); + if (stubFunc != null) { + ExternalLocation loc = program.getExternalManager() + .addExtLocation(Library.UNKNOWN, name, null, SourceType.IMPORTED); + stubFunc.setThunkedFunction(loc.createFunction()); } } + startAddr = startAddr.add(symbolSize); } } @@ -1511,14 +1490,19 @@ public class MachoProgramBuilder { * * @param name the name of the function * @param address location to create the function + * @return If a function already existed at the given address, that function will be returned. + * Otherwise, the newly created function will be returned. If there was a problem creating + * the function, null will be returned. */ - void createOneByteFunction(String name, Address address) { + Function createOneByteFunction(String name, Address address) { FunctionManager functionMgr = program.getFunctionManager(); - if (functionMgr.getFunctionAt(address) != null) { - return; + Function function = functionMgr.getFunctionAt(address); + if (function != null) { + return function; } try { - functionMgr.createFunction(name, address, new AddressSet(address), SourceType.IMPORTED); + return functionMgr.createFunction(name, address, new AddressSet(address), + SourceType.IMPORTED); } catch (InvalidInputException e) { // ignore @@ -1526,6 +1510,7 @@ public class MachoProgramBuilder { catch (OverlappingFunctionException e) { // ignore } + return null; } /**