mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-19 16:40:38 -09:00
GP-2511: Don't create Mach-O duplicate symbols with namespaces named
after sections
This commit is contained in:
@@ -21,6 +21,7 @@ import ghidra.app.util.bin.format.macho.MachHeader;
|
|||||||
import ghidra.app.util.bin.format.macho.commands.*;
|
import ghidra.app.util.bin.format.macho.commands.*;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.model.reloc.Relocation.Status;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
import ghidra.program.model.symbol.SymbolIterator;
|
import ghidra.program.model.symbol.SymbolIterator;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
@@ -70,6 +71,9 @@ abstract public class AbstractDyldInfoState {
|
|||||||
|
|
||||||
program.getMemory().setBytes(address, bytes);
|
program.getMemory().setBytes(address, bytes);
|
||||||
|
|
||||||
|
program.getRelocationTable()
|
||||||
|
.add(address, Status.APPLIED_OTHER, type, null, bytes.length, symbolName);
|
||||||
|
|
||||||
//ReferenceManager referenceManager = program.getReferenceManager();
|
//ReferenceManager referenceManager = program.getReferenceManager();
|
||||||
//Reference reference = referenceManager.addMemoryReference( address, symbol.getAddress(), RefType.READ, SourceType.IMPORTED, 0 );
|
//Reference reference = referenceManager.addMemoryReference( address, symbol.getAddress(), RefType.READ, SourceType.IMPORTED, 0 );
|
||||||
//referenceManager.setPrimary( reference, true );
|
//referenceManager.setPrimary( reference, true );
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ public class MachoProgramBuilder {
|
|||||||
processUnsupportedLoadCommands();
|
processUnsupportedLoadCommands();
|
||||||
boolean exportsFound = processExports(machoHeader);
|
boolean exportsFound = processExports(machoHeader);
|
||||||
processSymbolTables(machoHeader, !exportsFound);
|
processSymbolTables(machoHeader, !exportsFound);
|
||||||
processIndirectSymbols();
|
|
||||||
setRelocatableProperty();
|
setRelocatableProperty();
|
||||||
processLibraries();
|
processLibraries();
|
||||||
processProgramDescription();
|
processProgramDescription();
|
||||||
@@ -590,80 +589,6 @@ public class MachoProgramBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The indirect symbols need to be applied across the IMPORT segment. The
|
|
||||||
* individual section do not really matter except the number of bytes
|
|
||||||
* between each symbol varies based on section.
|
|
||||||
*
|
|
||||||
* @throws Exception if there is a problem
|
|
||||||
*/
|
|
||||||
protected void processIndirectSymbols() throws Exception {
|
|
||||||
|
|
||||||
monitor.setMessage("Processing indirect symbols...");
|
|
||||||
|
|
||||||
SymbolTableCommand symbolTableCommand =
|
|
||||||
machoHeader.getFirstLoadCommand(SymbolTableCommand.class);
|
|
||||||
|
|
||||||
DynamicSymbolTableCommand dynamicCommand =
|
|
||||||
machoHeader.getFirstLoadCommand(DynamicSymbolTableCommand.class);
|
|
||||||
|
|
||||||
if (dynamicCommand == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int[] indirectSymbols = dynamicCommand.getIndirectSymbols();
|
|
||||||
if (indirectSymbols.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] sectionTypes = new int[] { SectionTypes.S_NON_LAZY_SYMBOL_POINTERS,
|
|
||||||
SectionTypes.S_LAZY_SYMBOL_POINTERS, SectionTypes.S_SYMBOL_STUBS };
|
|
||||||
|
|
||||||
List<Section> sections = getSectionsWithTypes(sectionTypes);
|
|
||||||
|
|
||||||
for (Section section : sections) {
|
|
||||||
if (monitor.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (section.getSize() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace namespace = createNamespaceForSection(section);
|
|
||||||
|
|
||||||
int indirectSymbolTableIndex = section.getReserved1();
|
|
||||||
|
|
||||||
int symbolSize = machoHeader.getAddressSize();
|
|
||||||
if (section.getType() == SectionTypes.S_SYMBOL_STUBS) {
|
|
||||||
symbolSize = section.getReserved2();
|
|
||||||
}
|
|
||||||
|
|
||||||
int nSymbols = (int) section.getSize() / symbolSize;
|
|
||||||
|
|
||||||
Address startAddr = space.getAddress(section.getAddress());
|
|
||||||
for (int i = indirectSymbolTableIndex; i < indirectSymbolTableIndex + nSymbols; ++i) {
|
|
||||||
if (monitor.isCancelled()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int symbolIndex = indirectSymbols[i];
|
|
||||||
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
|
|
||||||
if (symbol != null) {
|
|
||||||
String name = generateValidName(symbol.getString());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startAddr = startAddr.add(symbolSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setRelocatableProperty() {
|
protected void setRelocatableProperty() {
|
||||||
Options props = program.getOptions(Program.PROGRAM_INFO);
|
Options props = program.getOptions(Program.PROGRAM_INFO);
|
||||||
switch (machoHeader.getFileType()) {
|
switch (machoHeader.getFileType()) {
|
||||||
@@ -864,15 +789,16 @@ public class MachoProgramBuilder {
|
|||||||
log.appendMsg(e.getMessage());
|
log.appendMsg(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (command.getLazyBindSize() > 0) {
|
if (command.getLazyBindSize() > 0) {
|
||||||
// LazyBindProcessor processor = new LazyBindProcessor(program, header, provider, command);
|
LazyBindProcessor processor =
|
||||||
// try {
|
new LazyBindProcessor(program, machoHeader, provider, command);
|
||||||
// processor.process(monitor);
|
try {
|
||||||
// }
|
processor.process(monitor);
|
||||||
// catch (Exception e) {
|
}
|
||||||
// log.appendException(e);
|
catch (Exception e) {
|
||||||
// }
|
log.appendException(e);
|
||||||
//}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doClassic) {
|
if (!doClassic) {
|
||||||
@@ -1506,10 +1432,6 @@ public class MachoProgramBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Namespace createNamespaceForSection(Section section) {
|
|
||||||
return createNamespace(section.getSectionName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Namespace createNamespace(String namespaceName) {
|
private Namespace createNamespace(String namespaceName) {
|
||||||
try {
|
try {
|
||||||
return program.getSymbolTable()
|
return program.getSymbolTable()
|
||||||
@@ -1532,25 +1454,6 @@ public class MachoProgramBuilder {
|
|||||||
return SymbolUtilities.replaceInvalidChars(name, true);
|
return SymbolUtilities.replaceInvalidChars(name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Section> getSectionsWithTypes(int[] sectionTypes) {
|
|
||||||
List<Section> list = new ArrayList<>();
|
|
||||||
List<Section> sections = machoHeader.getAllSections();
|
|
||||||
for (Section section : sections) {
|
|
||||||
if (monitor.isCancelled()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (int sectionType : sectionTypes) {
|
|
||||||
if (monitor.isCancelled()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (section.getType() == sectionType) {
|
|
||||||
list.add(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a one-byte function, so that when the code is analyzed,
|
* create a one-byte function, so that when the code is analyzed,
|
||||||
* it will be disassembled, and the function created with the correct body.
|
* it will be disassembled, and the function created with the correct body.
|
||||||
@@ -1812,10 +1715,13 @@ public class MachoProgramBuilder {
|
|||||||
byteLength = result.byteLength();
|
byteLength = result.byteLength();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
addRelocationTableEntry(chainLoc, status,
|
if (shouldAddChainedFixupsRelocations) {
|
||||||
(start ? 0x8000 : 0x4000) | (isAuthenticated ? 4 : 0) | (isBound ? 2 : 0) |
|
program.getRelocationTable()
|
||||||
1,
|
.add(chainLoc, status,
|
||||||
newChainValue, byteLength, symName);
|
(start ? 0x8000 : 0x4000) | (isAuthenticated ? 4 : 0) |
|
||||||
|
(isBound ? 2 : 0) | 1,
|
||||||
|
new long[] { newChainValue }, byteLength, symName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// delay creating data until after memory has been changed
|
// delay creating data until after memory has been changed
|
||||||
@@ -1827,15 +1733,6 @@ public class MachoProgramBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRelocationTableEntry(Address chainLoc, Status status, int type, long chainValue,
|
|
||||||
int byteLength, String name) {
|
|
||||||
if (shouldAddChainedFixupsRelocations) {
|
|
||||||
// Add entry to relocation table for the pointer fixup
|
|
||||||
program.getRelocationTable()
|
|
||||||
.add(chainLoc, status, type, new long[] { chainValue }, byteLength, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixes up any chained pointers, starting at the given address.
|
* Fixes up any chained pointers, starting at the given address.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user