diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/program/DBTraceProgramViewSymbolTable.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/program/DBTraceProgramViewSymbolTable.java index d40598c164..0720a58ba0 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/program/DBTraceProgramViewSymbolTable.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/program/DBTraceProgramViewSymbolTable.java @@ -326,6 +326,13 @@ public class DBTraceProgramViewSymbolTable implements SymbolTable { } } + @Override + public SymbolIterator getSymbolsAsIterator(Address addr) { + Symbol[] symbols = getSymbols(addr); + List list = Arrays.asList(symbols); + return new SymbolIteratorAdapter(list.iterator()); + } + @Override public Symbol[] getUserSymbols(Address addr) { try (LockHold hold = program.trace.lockRead()) { diff --git a/Ghidra/Features/Base/ghidra_scripts/AutoRenameLabelsScript.java b/Ghidra/Features/Base/ghidra_scripts/AutoRenameLabelsScript.java index bee994160b..ab9863e61b 100644 --- a/Ghidra/Features/Base/ghidra_scripts/AutoRenameLabelsScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/AutoRenameLabelsScript.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,58 +25,49 @@ import ghidra.program.model.symbol.*; public class AutoRenameLabelsScript extends GhidraScript { - @Override - public void run() throws Exception { - if (currentSelection == null || currentSelection.isEmpty()) { - println("No selection exists."); - return; - } + @Override + public void run() throws Exception { + if (currentSelection == null || currentSelection.isEmpty()) { + println("No selection exists."); + return; + } - String base = askString("Auto Rename Labels", "Enter label base name:"); - if (base == null) { - println("No base value entered."); - return; - } + String base = askString("Auto Rename Labels", "Enter label base name:"); + if (base == null) { + println("No base value entered."); + return; + } - int num = 1; + int num = 1; - AddressSetView view = currentSelection; - if ((view == null) || (view.isEmpty())) return; + AddressSetView view = currentSelection; + if ((view == null) || (view.isEmpty())) + return; - // Obtain the symbol table and listing from program - SymbolTable symbolTable = currentProgram.getSymbolTable(); + // Obtain the symbol table and listing from program + SymbolTable symbolTable = currentProgram.getSymbolTable(); - // Get the addresses in the set. - AddressIterator it = view.getAddresses(true); - - CompoundCmd cmd = new CompoundCmd("Auto Rename Labels"); - while(it.hasNext()) { - Address address = it.next(); - Symbol[] symbols = symbolTable.getSymbols(address); - Symbol defaultSymbol = getDynamicSymbol( symbols ); - if ( defaultSymbol != null ) { - cmd.add(new RenameLabelCmd(address, null, base+num++, SourceType.USER_DEFINED)); - } - } - if (cmd.size() > 0) { - if (!cmd.applyTo(currentProgram)) { - String msg = cmd.getStatusMsg(); - if (msg != null && msg.length() > 0) { - setToolStatusMessage(msg, true); - } - } - } - else { - println("No default labels found in selection."); - } - } + // Get the addresses in the set. + AddressIterator it = view.getAddresses(true); - private Symbol getDynamicSymbol( Symbol[] symbols ) { - for (int i=0;i 0) { + if (!cmd.applyTo(currentProgram)) { + String msg = cmd.getStatusMsg(); + if (msg != null && msg.length() > 0) { + setToolStatusMessage(msg, true); + } + } + } + else { + println("No default labels found in selection."); + } + } } diff --git a/Ghidra/Features/Base/ghidra_scripts/GccRttiAnalysisScript.java b/Ghidra/Features/Base/ghidra_scripts/GccRttiAnalysisScript.java index a88f161c0d..2f58b1e2f1 100644 --- a/Ghidra/Features/Base/ghidra_scripts/GccRttiAnalysisScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/GccRttiAnalysisScript.java @@ -77,7 +77,7 @@ public class GccRttiAnalysisScript extends GhidraScript { symbolTable = currentProgram.getSymbolTable(); globalNamespace = (GlobalNamespace) currentProgram.getGlobalNamespace(); - + // create the path for the data type manager root/ClassDataTypes folder classDataTypesCategoryPath = createDataTypeCategoryPath(CategoryPath.ROOT, DTM_CLASS_DATA_FOLDER_NAME); @@ -201,7 +201,7 @@ public class GccRttiAnalysisScript extends GhidraScript { // find the three special vtables and replace the incorrectly made array with // data types found in vtable boolean continueProcessing = createSpecialVtables(); - if(!continueProcessing) { + if (!continueProcessing) { return; } // find all typeinfo symbols and get their class namespace and create RecoveredClass object @@ -264,9 +264,11 @@ public class GccRttiAnalysisScript extends GhidraScript { return false; } } - - if(class_type_info_vtable == null && si_class_type_info_vtable == null && vmi_class_type_info_vtable == null) { - println("Since there are no class typeinfo tables this program does not appear to have RTTI."); + + if (class_type_info_vtable == null && si_class_type_info_vtable == null && + vmi_class_type_info_vtable == null) { + println( + "Since there are no class typeinfo tables this program does not appear to have RTTI."); return false; } return true; @@ -378,7 +380,7 @@ public class GccRttiAnalysisScript extends GhidraScript { // Except for the first one which should have a symbol, if there is a symbol at the // address, stop making longs because it there are no references into the vtable longs - if (offset > 0 && symbolTable.getSymbols(address).length > 0) { + if (offset > 0 && symbolTable.getPrimarySymbol(address) != null) { return numLongs; } @@ -499,8 +501,11 @@ public class GccRttiAnalysisScript extends GhidraScript { private void setIsGcc() { isGcc = - currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase( - "gcc"); + currentProgram.getCompilerSpec() + .getCompilerSpecID() + .getIdAsString() + .equalsIgnoreCase( + "gcc"); } private void createTypeinfoStructs(List typeinfoSymbols) throws CancelledException { @@ -684,7 +689,6 @@ public class GccRttiAnalysisScript extends GhidraScript { */ private void processVtables() throws Exception { - // find all vtable symbols List listOfVtableSymbols = getListOfSymbolsInAddressSet( currentProgram.getAddressFactory().getAddressSet(), VTABLE_LABEL, false); @@ -700,7 +704,6 @@ public class GccRttiAnalysisScript extends GhidraScript { processVtable(vtableAddress, vtableNamespace, true); - } return; } @@ -756,7 +759,6 @@ public class GccRttiAnalysisScript extends GhidraScript { return; } - int numFunctionPointers = getNumFunctionPointers(vftableAddress, true, true); // if at least one function pointer make vftable label - the createVftable method will @@ -791,7 +793,6 @@ public class GccRttiAnalysisScript extends GhidraScript { } } - // check for an internal vtable and make a symbol there if there is one // will process them later Address possibleInternalVtableAddress = @@ -1160,7 +1161,6 @@ public class GccRttiAnalysisScript extends GhidraScript { } } - private Address findNextTypeinfoRef(Address startAddress) { int offset = 0; @@ -1275,4 +1275,3 @@ public class GccRttiAnalysisScript extends GhidraScript { } } - diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java index fec6f20506..f1c9c03003 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java @@ -970,10 +970,11 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { return false; } - // See if the tested address is contained in memory + // if the reference is not in memory or to a well known location, then don't create it + // because we are not sure it is correct if (!memory.contains(testAddr)) { - Symbol syms[] = program.getSymbolTable().getSymbols(testAddr); - if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) { + Symbol symbol = program.getSymbolTable().getPrimarySymbol(testAddr); + if (symbol == null || symbol.getSource() == SourceType.DEFAULT) { return false; } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/ScalarOperandAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/ScalarOperandAnalyzer.java index 600b4a510d..f69e3de890 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/ScalarOperandAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/ScalarOperandAnalyzer.java @@ -56,7 +56,7 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { private static final int MAX_NEG_ENTRIES = 32; private int alignment = 4; - + private TaskMonitor monitor; public ScalarOperandAnalyzer() { @@ -78,7 +78,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { } @Override - public boolean added(Program program, AddressSetView set, TaskMonitor taskMonitor, MessageLog log) { + public boolean added(Program program, AddressSetView set, TaskMonitor taskMonitor, + MessageLog log) { int count = 0; monitor = taskMonitor; @@ -88,14 +89,15 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { // Evaluate each operand // Listing listing = program.getListing(); - + InstructionIterator iter = listing.getInstructions(set, true); while (iter.hasNext() && !monitor.isCancelled()) { Instruction instr = iter.next(); monitor.setProgress(++count); checkOperands(program, instr); } - } finally { + } + finally { monitor = null; // get rid of the reference to it } @@ -123,22 +125,26 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { try { switch (scalar.bitLength()) { case 8: - if (program.getMemory().getByte(addr) == scalar.getSignedValue()) { + if (program.getMemory().getByte(addr) == scalar + .getSignedValue()) { found = true; } break; case 16: - if (program.getMemory().getShort(addr) == scalar.getSignedValue()) { + if (program.getMemory().getShort(addr) == scalar + .getSignedValue()) { found = true; } break; case 32: - if (program.getMemory().getInt(addr) == scalar.getSignedValue()) { + if (program.getMemory().getInt(addr) == scalar + .getSignedValue()) { found = true; } break; case 64: - if (program.getMemory().getLong(addr) == scalar.getSignedValue()) { + if (program.getMemory().getLong(addr) == scalar + .getSignedValue()) { found = true; } break; @@ -162,7 +168,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { } // check the address in this space first - if (addReference(program, instr, i, instr.getMinAddress().getAddressSpace(), scalar)) { + if (addReference(program, instr, i, instr.getMinAddress().getAddressSpace(), + scalar)) { continue; } @@ -209,10 +216,11 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { return false; } - //check that memory contains the target address + // if the reference is not in memory or to a well known location, then don't create it + // because we are not sure it is correct if (!program.getMemory().contains(addr)) { - Symbol syms[] = program.getSymbolTable().getSymbols(addr); - if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) { + Symbol symbol = program.getSymbolTable().getPrimarySymbol(addr); + if (symbol == null || symbol.getSource() == SourceType.DEFAULT) { return false; } } @@ -284,8 +292,9 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled); if (table != null) { // add in an offcut reference - program.getReferenceManager().addOffsetMemReference(refInstr.getMinAddress(), offAddr, - -entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); + program.getReferenceManager() + .addOffsetMemReference(refInstr.getMinAddress(), offAddr, + -entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); return; } @@ -321,8 +330,9 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer { offAddr = lastGoodTable.getTopAddress(); // add in an offcut reference - program.getReferenceManager().addOffsetMemReference(instr.getMinAddress(), offAddr, - (i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); + program.getReferenceManager() + .addOffsetMemReference(instr.getMinAddress(), offAddr, + (i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); return; } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/OperandLabelDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/OperandLabelDialog.java index ff60514cde..e720d381f7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/OperandLabelDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/OperandLabelDialog.java @@ -121,7 +121,7 @@ public class OperandLabelDialog extends DialogComponentProvider { // the presentation at the call or jump instruction, it doesn't matter which symbol of the // same name you pick. private Symbol findSymbol(SymbolTable symTable, String currentLabel, Address symAddr) { - Symbol[] symbols = symTable.getSymbols(symAddr); + SymbolIterator symbols = symTable.getSymbolsAsIterator(symAddr); for (Symbol symbol : symbols) { if (symbol.getName(true).equals(currentLabel)) { return symbol; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/MakeStringsTask.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/MakeStringsTask.java index 32724b1522..2cc1dad837 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/MakeStringsTask.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/MakeStringsTask.java @@ -153,8 +153,9 @@ public class MakeStringsTask extends ProgramTask { if (paddingLength != 0) { try { - program.getListing().createData(address.add(length), new AlignmentDataType(), - paddingLength); + program.getListing() + .createData(address.add(length), new AlignmentDataType(), + paddingLength); } catch (Exception e) { // don't care that padding failed @@ -241,7 +242,7 @@ public class MakeStringsTask extends ProgramTask { private boolean labelAlreadyExists(Address addr, String name) { SymbolTable symbolTable = program.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols(addr); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(addr); for (Symbol symbol : symbols) { if (symbol.getName().equals(name)) { return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTableModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTableModel.java index d8e483b2b6..3774b141f3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTableModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTableModel.java @@ -287,11 +287,7 @@ class SymbolTableModel extends AddressBasedTableModel { CompoundCmd cmd = new CompoundCmd("Delete symbol(s)"); for (Symbol symbol : rowObjects) { if (symbol.isDynamic()) { - Symbol[] symbols = symbolTable.getSymbols(symbol.getAddress()); - if (symbols.length == 1) { - tool.setStatusInfo("Unable to delete symbol: " + symbol.getName()); - continue;//can't delete dynamic symbols... - } + continue;//can't delete dynamic symbols... } deleteList.add(symbol); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/AddEditDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/AddEditDialog.java index 1f033db398..9263b3f9f2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/AddEditDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/AddEditDialog.java @@ -370,11 +370,9 @@ public class AddEditDialog extends DialogComponentProvider { private FunctionSymbol getFunctionSymbol(Address address) { SymbolTable symbolTable = program.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols(address); - for (Symbol localSymbol : symbols) { - if (localSymbol instanceof FunctionSymbol) { - return (FunctionSymbol) localSymbol; - } + Symbol primary = symbolTable.getPrimarySymbol(address); + if (primary instanceof FunctionSymbol) { + return (FunctionSymbol) primary; } return null; } @@ -395,10 +393,8 @@ public class AddEditDialog extends DialogComponentProvider { pinnedCheckBox.setEnabled(true); pinnedCheckBox.setSelected(false); - Symbol[] symbols = symbolTable.getSymbols(address); - - FunctionSymbol functionSymbol = getFunctionSymbol(address); - if (functionSymbol == null && symbols.length == 0) { + Symbol primarySymbol = symbolTable.getPrimarySymbol(address); + if (primarySymbol == null) { primaryCheckBox.setSelected(true); primaryCheckBox.setEnabled(false); } @@ -463,9 +459,8 @@ public class AddEditDialog extends DialogComponentProvider { nameBorder.setTitle("Enter Label:"); entryPointCheckBox.setEnabled(true); entryPointCheckBox.setSelected(symbolTable.isExternalEntryPoint(addr)); - Symbol[] symbols = symbolTable.getSymbols(addr); primaryCheckBox.setSelected(s.isPrimary()); - primaryCheckBox.setEnabled(!s.isPrimary() && symbols.length > 1); + primaryCheckBox.setEnabled(!s.isPrimary()); pinnedCheckBox.setEnabled(true); pinnedCheckBox.setSelected(s.isPinned()); namespaceChoices.setEnabled(true); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfDefaultGotPltMarkup.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfDefaultGotPltMarkup.java index 3c69648868..be7b097223 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfDefaultGotPltMarkup.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfDefaultGotPltMarkup.java @@ -234,7 +234,7 @@ public class ElfDefaultGotPltMarkup { long symbolSearchSpacing; // nominal PLT entry size for computing maxSymbolSearchAddress Address firstPltEntryAddr = null; // may be offcut within first PLT entry - + if (pltSpacing == 0) { // Entries have same original bytes which refer to PLT head Function pltHeadFunc = elfLoadHelper.createOneByteFunction(null, pltAddr1, false); if (pltHeadFunc.getSymbol().getSource() == SourceType.DEFAULT) { @@ -537,8 +537,9 @@ public class ElfDefaultGotPltMarkup { // Stop on first error but discard error bookmark since // some plt sections are partly empty and must rely // on normal flow disassembly during analysis - prog.getBookmarkManager().removeBookmarks(set, BookmarkType.ERROR, - Disassembler.ERROR_BOOKMARK_CATEGORY, monitor); + prog.getBookmarkManager() + .removeBookmarks(set, BookmarkType.ERROR, + Disassembler.ERROR_BOOKMARK_CATEGORY, monitor); break;//we did not disassemble anything... } set.delete(disset); @@ -604,11 +605,8 @@ public class ElfDefaultGotPltMarkup { if (memory.contains(refAddr)) { return true; } - Symbol syms[] = program.getSymbolTable().getSymbols(refAddr); - if (syms != null && syms.length > 0 && syms[0].getSource() != SourceType.DEFAULT) { - return true; - } - return false; + Symbol primary = program.getSymbolTable().getPrimarySymbol(refAddr); + return primary != null && primary.getSource() != SourceType.DEFAULT; } private void removeMemRefs(Data data) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java index 78753edbbc..1159e134ea 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java @@ -1570,7 +1570,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { return address; } - + /** * Find memory register with matching name (ignoring leading and trailing underscore chars). * @param elfSymbol ELF symbol @@ -1586,7 +1586,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { } return regAddr; } - + private Address getMemoryRegister(String name, long value) { Register reg = program.getRegister(name); if (reg != null && reg.getAddress().isMemoryAddress()) { @@ -2360,9 +2360,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { .addMemoryReference(valueData.getAddress(), refAddr, RefType.DATA, SourceType.ANALYSIS, 0); if (label != null) { - // add label if a non-default label does not exist - Symbol[] symbols = program.getSymbolTable().getSymbols(refAddr); - if (symbols.length == 0 || symbols[0].getSource() == SourceType.DEFAULT) { + // add label if no label exists of there is just a default label + Symbol symbol = program.getSymbolTable().getPrimarySymbol(refAddr); + if (symbol == null || symbol.getSource() == SourceType.DEFAULT) { createSymbol(refAddr, "_" + label, false, false, null); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java b/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java index c2840f7f2e..c178e39a09 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java @@ -1377,7 +1377,7 @@ public class FlatProgramAPI { */ @Deprecated public final Symbol getSymbolAt(Address address, String name) { - Symbol[] symbols = currentProgram.getSymbolTable().getSymbols(address); + SymbolIterator symbols = currentProgram.getSymbolTable().getSymbolsAsIterator(address); for (Symbol symbol : symbols) { if (symbol.getName().equals(name)) { return symbol; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/symbol/SymbolManagerTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/symbol/SymbolManagerTest.java index f43a560bb9..00cf2fd9f5 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/symbol/SymbolManagerTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/symbol/SymbolManagerTest.java @@ -199,7 +199,28 @@ public class SymbolManagerTest extends AbstractGhidraHeadedIntegrationTest { assertTrue(!s.isGlobal()); assertTrue(s.getSource() == SourceType.USER_DEFINED); assertTrue(s.isPrimary()); + } + @Test + public void testGetSymbolIteratorByAddress() throws Exception { + createSymbol(addr(100), "A"); + createSymbol(addr(100), "fred"); + createSymbol(addr(100), "joe"); + Namespace scope = st.createNameSpace(null, "MyNamespace", SourceType.USER_DEFINED); + createSymbol(addr(200), "fred", scope); + + SymbolIterator it = st.getSymbolsAsIterator(addr(100)); + + assertTrue(it.hasNext()); + assertEquals("A", it.next().getName()); + + assertTrue(it.hasNext()); + assertEquals("fred", it.next().getName()); + + assertTrue(it.hasNext()); + assertEquals("joe", it.next().getName()); + + assertFalse(it.hasNext()); } @Test diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java index 43a70f8a19..74f872de7b 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java @@ -166,8 +166,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { byte[] gccBytes = { (byte) 0x47, (byte) 0x43, (byte) 0x43, (byte) 0x3a }; byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; - Address found = program.getMemory().findBytes(commentBlock.getStart(), - commentBlock.getEnd(), gccBytes, maskBytes, true, monitor); + Address found = program.getMemory() + .findBytes(commentBlock.getStart(), + commentBlock.getEnd(), gccBytes, maskBytes, true, monitor); if (found == null) { return false; } @@ -256,7 +257,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { updateClassesWithParentsAndFlags(typeinfoSymbols); - // update the vftable offset map Iterator recoveredClassIterator = recoveredClasses.iterator(); while (recoveredClassIterator.hasNext()) { @@ -417,7 +417,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { if (specialTypeinfoRef.equals(vmi_class_type_info) || specialTypeinfoRef.equals(vmi_class_type_info_vtable)) { - List parents = addGccClassParentsFromVmiStruct(recoveredClass, typeinfoAddress); @@ -493,7 +492,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { for (Address typeinfoRef : typeinfoReferencesNotInTypeinfoStructs) { monitor.checkCanceled(); - Address typeinfoAddress = extraUtils.getPointer(typeinfoRef); if (typeinfoAddress == null) { @@ -524,14 +522,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { if (!typeinfoSymbol.getName().equals("typeinfo")) { continue; } - + // check for construction table and make new namespace if so Namespace classNamespace = typeinfoSymbol.getParentNamespace(); - + if (classNamespace.equals(globalNamespace)) { throw new Exception("typeinfo has global namespace " + typeinfoAddress); } - try { Symbol vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL, @@ -617,8 +614,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { return false; } - - private Namespace createConstructionNamespace(Symbol vtableSymbol, Symbol vttSymbol) throws Exception { @@ -635,7 +630,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { try { Namespace newNamespace = NamespaceUtils.createNamespaceHierarchy(name, vtableNamespace, - program, SourceType.ANALYSIS); + program, SourceType.ANALYSIS); return newNamespace; } catch (InvalidInputException e) { @@ -722,7 +717,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { Data dataContainingTypeinfoRef = prog.getListing().getDefinedDataContaining(addr); - Instruction instructionContainingAddr = prog.getListing().getInstructionContaining(addr); @@ -863,8 +857,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { api.setPlateComment(vtableAddress, "construction vtable " + n + " for class " + - vttSymbolBeforeConstructionVtable.getParentNamespace().getName( - true)); + vttSymbolBeforeConstructionVtable.getParentNamespace() + .getName( + true)); } catch (InvalidInputException e) { @@ -897,7 +892,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { } int numFunctionPointers = getNumFunctionPointers(possibleVftableAddress, true, true); - + if (numFunctionPointers == 0) { // if not a vftable check for an internal vtable boolean isInternalVtable = @@ -1190,7 +1185,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { return false; } - return true; } @@ -1402,7 +1396,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { // Except for the first one which should have a symbol, if there is a symbol at the // address, stop making longs because it there are no references into the vtable longs - if (offset > 0 && symbolTable.getSymbols(address).length > 0) { + if (offset > 0 && symbolTable.getPrimarySymbol(address) != null) { return numLongs; } @@ -1489,33 +1483,34 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { // create a "no inheritance" struct here if (specialTypeinfoRef.equals(class_type_info) || specialTypeinfoRef.equals(class_type_info_vtable)) { - + newStructure = applyTypeinfoStructure(classTypeInfoStructure, typeinfoAddress); } // create a "single inheritance" struct here else if (specialTypeinfoRef.equals(si_class_type_info) || specialTypeinfoRef.equals(si_class_type_info_vtable)) { - + newStructure = applyTypeinfoStructure(siClassTypeInfoStructure, typeinfoAddress); } // create a "virtual multip inheritance" struct here else if (specialTypeinfoRef.equals(vmi_class_type_info) || specialTypeinfoRef.equals(vmi_class_type_info_vtable)) { - + Structure vmiClassTypeinfoStructure = getOrCreateVmiTypeinfoStructure(typeinfoAddress, baseClassTypeInfoStructure); if (vmiClassTypeinfoStructure != null) { - newStructure = applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress); + newStructure = + applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress); } } - + if (newStructure == null) { throw new Exception( "ERROR: Could not apply typeinfo structure to " + typeinfoAddress); } - + // check for existing symbol and if none, demangle the name and apply Symbol typeinfoSymbol = api.getSymbolAt(typeinfoAddress); if (typeinfoSymbol == null || typeinfoSymbol.getSource() == SourceType.DEFAULT) { @@ -1840,7 +1835,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { return specialTypeinfoRefs; } - /** * Method to call the various methods to determine whether the functions that make references to * the vftables are constructors, destructors, deleting destructors, clones, or vbase functions @@ -1985,7 +1979,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { DataType pointer = dataTypeManager.getPointer(null); DataType charPointer = dataTypeManager.getPointer(characterDT); - vmiClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null); vmiClassTypeInfoStructure.add(charPointer, "typeinfoName", null); vmiClassTypeInfoStructure.add(unsignedIntDT, "flags", null); @@ -2011,7 +2004,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { private List addGccClassParentsFromVmiStruct(RecoveredClass recoveredClass, Address typeinfoAddress) throws Exception { - Structure vmiTypeinfoStructure = getTypeinfoStructure(typeinfoAddress); if (vmiTypeinfoStructure == null || !vmiTypeinfoStructure.getName().contains(VMI_CLASS_TYPE_INFO_STRUCTURE)) { @@ -2150,8 +2142,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { parentClass.setIsPublicClass(isPublic); - - // from doc: //All but the lower 8 bits of __offset_flags are a signed offset. For a //non-virtual base, this is the offset in the object of the base subobject. @@ -2168,7 +2158,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { continue; - } if (DEBUG) { @@ -2893,7 +2882,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { return; } - if (!recoveredClass.hasVftable()) { createSimpleClassStructure(recoveredClass, null); // return in this case because if there is no vftable for a class the script cannot @@ -3018,7 +3006,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { " : structure should exist but doesn't."); } - if (structUtils.canAdd(classStructureDataType, parentOffset, baseClassStructure.getLength(), monitor)) { classStructureDataType = @@ -3049,7 +3036,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { } - if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) { + if (classStructureDataType.getNumComponents() == classStructureDataType + .getNumDefinedComponents()) { classStructureDataType.setPackingEnabled(true); } diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java index 20d7f9afa1..c9471bfcf6 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java @@ -56,11 +56,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { private static final String VFTABLE_META_PTR_LABEL = "vftable_meta_ptr"; private static final String VFTABLE_LABEL = "vftable"; - private static final String CLASS_VTABLE_STRUCT_NAME = "_vbtable"; private static final String CLASS_VTABLE_PTR_FIELD_EXT = "vftablePtr"; - private static final int CHD_MULTINH = 0x00000001; //Multiple inheritance private static final int CHD_VIRTINH = 0x00000002; //Virtual inheritance private static final int CHD_AMBIGUOUS = 0x00000004; //Multiple inheritance with repeated base classes @@ -91,7 +89,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { return true; } - @Override public boolean isValidProgramType() { if (!isVisualStudioOrClangPe()) { @@ -100,7 +97,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { return true; } - @Override public void fixUpProgram() { @@ -184,10 +180,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { determineParentClassInfoFromBaseClassArray(recoveredClasses); - assignParentClassToVftables(recoveredClasses); - // using all the information found above, create the class structures, add the constructor, // destructor, vfunctions to class which finds the appropriate class structure and assigns // to "this" param @@ -205,7 +199,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { //println("Removing erroneous FID namespaces and corresponding class data types"); removeEmptyClassesAndStructures(); } - + return recoveredClasses; } catch (CancelledException e) { @@ -219,14 +213,12 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { } - private boolean isVisualStudioOrClangPe() { return program.getExecutableFormat().equals(PeLoader.PE_NAME) && (program.getCompiler().equals(CompilerEnum.VisualStudio.toString()) || program.getCompiler().equals(CompilerEnum.Clang.toString())); } - private boolean hasTypeInfoVftable() throws CancelledException { List vftableSymbols = getListOfVftableSymbols(); @@ -474,8 +466,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4)); Data baseClassDescriptor = extraUtils.getDataAt(baseClassDescriptorAddress); - if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals( - RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { + if (baseClassDescriptor == null || !baseClassDescriptor.getDataType() + .getName() + .equals( + RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { int num1 = extraUtils.getInt(baseClassDescriptorAddress.add(8)); int num2 = extraUtils.getInt(baseClassDescriptorAddress.add(12)); @@ -563,8 +557,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { Data classHierarchyStructure = extraUtils.getDataAt(classHierarchyDescriptorAddress); if (classHierarchyStructure != null && - classHierarchyStructure.getDataType().getName().equals( - RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { + classHierarchyStructure.getDataType() + .getName() + .equals( + RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { return classHierarchyDescriptorAddress; } @@ -803,7 +799,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { private Symbol getGivenSymbol(Address address, String name, Namespace namespace) throws CancelledException { - Symbol[] symbols = symbolTable.getSymbols(address); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address); for (Symbol sym : symbols) { monitor.checkCanceled(); if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) { @@ -884,10 +880,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { findFunctionsUsingAtexit(); } - - - - /** * Method to recover the class information for each vftable symbol on the list * * For each virtual function table: @@ -923,7 +915,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) { classNamespace = promoteToClassNamespace(classNamespace); - if(classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) { + if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) { Msg.debug(this, classHierarchyDescriptorAddress.toString() + " Could not promote " + classNamespace.getName(true) + " to a class namespace."); @@ -963,11 +955,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { List classesWithVftablesInNamespace = recoverClassesFromVftables(vftableSymbolsInNamespace, false, false); if (classesWithVftablesInNamespace.size() == 0) { - Msg.debug(this,"No class recovered for namespace " + classNamespace.getName()); + Msg.debug(this, "No class recovered for namespace " + classNamespace.getName()); continue; } if (classesWithVftablesInNamespace.size() > 1) { - Msg.debug(this,"Unexpected multiple classes recovered for namespace " + + Msg.debug(this, "Unexpected multiple classes recovered for namespace " + classNamespace.getName()); continue; } @@ -1372,7 +1364,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { } - /** * Method to recover parent information, including class offsets, vbase structure and its offset and address if applicable, and whether * the parent is regularly or virtually inherited @@ -2142,14 +2133,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { } - - - - - - - - /** * Method to call create and apply class structures method starting with top parent classes * and non-virtual classes then the children and their children until all classes are processed. @@ -2493,7 +2476,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { Structure recoveredClassDataStruct = createClassMemberDataStructure(recoveredClass, - classStructureDataType, dataLen, dataOffset); + classStructureDataType, dataLen, dataOffset); if (recoveredClassDataStruct != null) { classStructureDataType = structUtils.addDataTypeToStructure( @@ -2502,7 +2485,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { } - if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) { + if (classStructureDataType.getNumComponents() == classStructureDataType + .getNumDefinedComponents()) { classStructureDataType.setPackingEnabled(true); } @@ -2590,7 +2574,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { return classStructureDataType; } - /** * Method to apply the given class's vbtable structure * @param recoveredClass the given RecoveredClass object which, if applicable, contains the address and structure to apply @@ -2615,6 +2598,4 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer { recoveredClass.getClassNamespace().getName(true) + "::vbtable"); } - - } diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassUtils.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassUtils.java index cd070c0389..9a16054249 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassUtils.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassUtils.java @@ -169,7 +169,6 @@ public class RecoveredClassUtils { decompilerUtils = new DecompilerScriptUtils(program, tool, monitor); structUtils = new EditStructureUtils(); - dataTypeManager = program.getDataTypeManager(); symbolTable = program.getSymbolTable(); @@ -236,7 +235,7 @@ public class RecoveredClassUtils { } } } - + public List
getVftableReferences(Function function) { return functionToVftableRefsMap.get(function); } @@ -522,8 +521,6 @@ public class RecoveredClassUtils { return allInlinedDestructors; } - - /** * Method to determine if referenced vftables are from the same class * @param vftableReferences list of vftable references @@ -907,7 +904,7 @@ public class RecoveredClassUtils { */ public Address getStoredVftableAddress(List storedPcodeOps) throws CancelledException { - + if (storedPcodeOps.size() > 0) { Iterator iterator = storedPcodeOps.iterator(); // figure out if vftable is referenced @@ -1288,8 +1285,6 @@ public class RecoveredClassUtils { } - - /** * Method to determine if the given possible ancestor is an ancestor of any of the listed classes * @param recoveredClasses List of classes @@ -2658,7 +2653,6 @@ public class RecoveredClassUtils { return false; } - /** * Method to create a new recovered class object and add it to the namespaceToClassMap * @param namespace the namespace to put the new class in @@ -2724,7 +2718,7 @@ public class RecoveredClassUtils { } continue; } - + // get only the functions from the ones that are not already processed structures // return null if not an unprocessed table List virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol, @@ -2766,7 +2760,6 @@ public class RecoveredClassUtils { Map vftableReferenceToFunctionMapping = createVftableReferenceToFunctionMapping(referencesToVftable); - //vftableReferenceToFunctionMapping List possibleConstructorDestructorsForThisClass = findPossibleConstructorDestructors(vftableReferenceToFunctionMapping); @@ -2910,8 +2903,6 @@ public class RecoveredClassUtils { return cdFunctions; } - - /** * Method to get functions from vftable * @param vftableAddress the address of the vftable @@ -3890,8 +3881,8 @@ public class RecoveredClassUtils { String simpleName = extraUtils.removeTemplate(name); - Symbol[] symbols = symbolTable.getSymbols(address); - for (Symbol symbol : symbols) { + SymbolIterator it = symbolTable.getSymbolsAsIterator(address); + for (Symbol symbol : it) { monitor.checkCanceled(); String simpleSymbolName = extraUtils.removeTemplate(symbol.getName()); @@ -4541,7 +4532,7 @@ public class RecoveredClassUtils { if (nameField.contains("purecall")) { nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber; comment = recoveredClass.getName() + " pure " + comment; - + } PointerDataType functionPointerDataType = @@ -4932,10 +4923,11 @@ public class RecoveredClassUtils { //TODO: remove after testing if (!classVftableRef.equals(otherWayRef)) { if (DEBUG) { - Msg.debug(this, - recoveredClass.getName() + " function " + - functionContainingInline.getEntryPoint().toString() + " first ref: " + - classVftableRef.toString() + " other way ref: " + otherWayRef.toString()); + Msg.debug(this, + recoveredClass.getName() + " function " + + functionContainingInline.getEntryPoint().toString() + " first ref: " + + classVftableRef.toString() + " other way ref: " + + otherWayRef.toString()); } } @@ -5056,8 +5048,9 @@ public class RecoveredClassUtils { Function firstCalledFunction = extraUtils.getCalledFunctionByCallOrder(deletingDestructor, 1); if (firstCalledFunction == null || - !recoveredClass.getConstructorOrDestructorFunctions().contains( - firstCalledFunction)) { + !recoveredClass.getConstructorOrDestructorFunctions() + .contains( + firstCalledFunction)) { return null; } @@ -5201,11 +5194,14 @@ public class RecoveredClassUtils { return; } if (parentDestructorClasses.size() == 1) { - if (!parentDestructorClasses.get(0).getDestructorList().contains( - parentDestructor)) { + if (!parentDestructorClasses.get(0) + .getDestructorList() + .contains( + parentDestructor)) { addDestructorToClass(parentDestructorClasses.get(0), parentDestructor); - parentDestructorClasses.get(0).removeIndeterminateConstructorOrDestructor( - parentDestructor); + parentDestructorClasses.get(0) + .removeIndeterminateConstructorOrDestructor( + parentDestructor); } } // if more than one parent class for this function then let either inline or multi-class @@ -5390,8 +5386,10 @@ public class RecoveredClassUtils { */ public boolean isClassOffsetToVftableMapComplete(RecoveredClass recoveredClass) { - if (recoveredClass.getClassOffsetToVftableMap().values().containsAll( - recoveredClass.getVftableAddresses())) { + if (recoveredClass.getClassOffsetToVftableMap() + .values() + .containsAll( + recoveredClass.getVftableAddresses())) { return true; } return false; @@ -5434,8 +5432,9 @@ public class RecoveredClassUtils { Function secondCalledFunction = extraUtils.getCalledFunctionByCallOrder(vFunction, 2); if (firstCalledFunction != null && secondCalledFunction != null && - !recoveredClass.getConstructorOrDestructorFunctions().contains( - firstCalledFunction) && + !recoveredClass.getConstructorOrDestructorFunctions() + .contains( + firstCalledFunction) && secondCalledFunction.equals(operator_delete) && !getAllConstructorsAndDestructors().contains(vFunction)) { recoveredClass.addDeletingDestructor(vFunction); @@ -6903,7 +6902,6 @@ public class RecoveredClassUtils { } } - return changedItems; } @@ -7419,12 +7417,12 @@ public class RecoveredClassUtils { private Structure getParentClassStructure(Structure childClassStructure, String nameOfParent) throws CancelledException { - + DataTypeComponent[] components = childClassStructure.getComponents(); for (DataTypeComponent component : components) { monitor.checkCanceled(); DataType componentDataType = component.getDataType(); - if(componentDataType.getName().equals(nameOfParent)) { + if (componentDataType.getName().equals(nameOfParent)) { return (Structure) componentDataType; } } @@ -7520,22 +7518,24 @@ public class RecoveredClassUtils { DataTypeComponent[] vfunctionComponents = vfunctionStructure.getComponents(); for (DataTypeComponent vfunctionComponent : vfunctionComponents) { monitor.checkCanceled(); - Object changedItem = updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress); - if(changedItem != null && !changedItems.contains(changedItem)) { + Object changedItem = + updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress); + if (changedItem != null && !changedItems.contains(changedItem)) { changedItems.add(changedItem); - FunctionDefinition newFunctionDefinition = getComponentFunctionDefinition(vfunctionComponent); - if(newFunctionDefinition == null) { + FunctionDefinition newFunctionDefinition = + getComponentFunctionDefinition(vfunctionComponent); + if (newFunctionDefinition == null) { continue; } - + List changedStructs = - applyNewFunctionDefinitionToComponents(vfunctionComponent, - newFunctionDefinition); + applyNewFunctionDefinitionToComponents(vfunctionComponent, + newFunctionDefinition); if (changedStructs.isEmpty()) { continue; } - + changedItems = updateList(changedItems, changedStructs); } } @@ -7604,7 +7604,6 @@ public class RecoveredClassUtils { return null; } - boolean changed = updateFunctionSignature(vfunction, newFunctionDefinition); if (changed) { return vfunction; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/ObjectiveC2_DecompilerMessageAnalyzer.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/ObjectiveC2_DecompilerMessageAnalyzer.java index f36947fc93..14ac26aedf 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/ObjectiveC2_DecompilerMessageAnalyzer.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/analysis/ObjectiveC2_DecompilerMessageAnalyzer.java @@ -502,7 +502,7 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer { offset = ((Address) dataValue).getOffset(); if (offset == address.getOffset()) { // Self-referencing pointer - name = null; + name = null; } else { name = getNameFromOffset(program, offset, input, isClass, isMethod); @@ -671,23 +671,18 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer { } private String getLabelFromUndefinedData(Program program, Address address) { - Symbol[] symbols = program.getSymbolTable().getSymbols(address); - if (symbols.length == 0) { + Symbol primary = program.getSymbolTable().getPrimarySymbol(address); + if (primary == null) { return null; } - for (Symbol symbol : symbols) { - if (symbol.isPrimary()) { - String symbolName = symbol.getName(); - if (symbolName.contains("_OBJC_CLASS_$_")) { - symbolName = symbolName.substring("_OBJC_CLASS_$_".length()); - } - else if (symbolName.contains("_objc_msgSend")) { - return null; - } - return symbolName; - } + String symbolName = primary.getName(); + if (symbolName.contains("_OBJC_CLASS_$_")) { + symbolName = symbolName.substring("_OBJC_CLASS_$_".length()); } - return null; + else if (symbolName.contains("_objc_msgSend")) { + return null; + } + return symbolName; } private String getClassName(Program program, Address toAddress) { diff --git a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGProvider.java b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGProvider.java index 354127d588..9df2141829 100644 --- a/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGProvider.java +++ b/Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/FGProvider.java @@ -764,14 +764,10 @@ public class FGProvider extends VisualGraphComponentProvider 1) { - return; // real user symbols - } - else if (symbols.length == 1) { - if (!symbols[0].isDynamic()) { - return; // real user symbol - } + + Symbol primary = symbolTable.getPrimarySymbol(minAddress); + if (!primary.isDynamic()) { + return; } ReferenceManager referenceManager = currentProgram.getReferenceManager(); diff --git a/Ghidra/Features/FunctionID/ghidra_scripts/FidStatistics.java b/Ghidra/Features/FunctionID/ghidra_scripts/FidStatistics.java index 90310869f1..95b13d34d6 100644 --- a/Ghidra/Features/FunctionID/ghidra_scripts/FidStatistics.java +++ b/Ghidra/Features/FunctionID/ghidra_scripts/FidStatistics.java @@ -28,6 +28,7 @@ import ghidra.program.model.lang.Language; import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.symbol.Symbol; +import ghidra.program.model.symbol.SymbolIterator; import ghidra.util.exception.CancelledException; import ghidra.util.exception.VersionException; @@ -56,8 +57,8 @@ public class FidStatistics extends GhidraScript { private String sym1; private String sym2; - - public SymbolPair(String a,String b) { + + public SymbolPair(String a, String b) { sym1 = a; sym2 = b; } @@ -70,7 +71,7 @@ public class FidStatistics extends GhidraScript { } return sym2.compareTo(o.sym2); } - + } public static class MatchRecord { @@ -83,7 +84,7 @@ public class FidStatistics extends GhidraScript { private float childScore; private float parentScore; - public MatchRecord(FidSearchResult result,String finalMatchName,boolean isFalse) { + public MatchRecord(FidSearchResult result, String finalMatchName, boolean isFalse) { this.progName = result.function.getProgram().getDomainFile().getPathname(); this.fullHash = result.hashQuad.getFullHash(); this.funcName = result.function.getName(); @@ -125,7 +126,7 @@ public class FidStatistics extends GhidraScript { public int noMatch; public int nameMatched; public int falsePositive; - + public StatRecord() { totalFunction = 0; matchUniquely = 0; @@ -136,8 +137,8 @@ public class FidStatistics extends GhidraScript { falsePositive = 0; } - public static void indent(StringBuilder buf,String last) { - for(int i=last.length();i<10;++i) { + public static void indent(StringBuilder buf, String last) { + for (int i = last.length(); i < 10; ++i) { buf.append(' '); } } @@ -145,35 +146,36 @@ public class FidStatistics extends GhidraScript { public void print(StringBuilder buf) { String str = Integer.toString(totalFunction); buf.append(str); - indent(buf,str); + indent(buf, str); str = Integer.toString(noMatch); buf.append(str); - indent(buf,str); + indent(buf, str); str = Integer.toString(matchUniquely + matchMultiply); buf.append(str); indent(buf, str); str = Integer.toString(hitCount); buf.append(str); indent(buf, str); - str = '(' + Integer.toString(matchUniquely) + ',' + Integer.toString(matchMultiply) + ')'; + str = + '(' + Integer.toString(matchUniquely) + ',' + Integer.toString(matchMultiply) + ')'; buf.append(str); - indent(buf,str); + indent(buf, str); str = Integer.toString(nameMatched); buf.append(str); - indent(buf,str); + indent(buf, str); str = Integer.toString(falsePositive); buf.append(str); } - + public static String getColumns() { return "Total No Match Possible Hits uniq/mult N-Match False"; } } - private void addEquivSymbols(String a,String b) { - SymbolPair pair = new SymbolPair(a,b); + private void addEquivSymbols(String a, String b) { + SymbolPair pair = new SymbolPair(a, b); equivSymbols.add(pair); - pair = new SymbolPair(b,a); + pair = new SymbolPair(b, a); equivSymbols.add(pair); } @@ -182,164 +184,185 @@ public class FidStatistics extends GhidraScript { service = new FidService(); matchAnalysis = new MatchNameAnalysis(); equivSymbols = new TreeSet(); - addEquivSymbols("entry","_WinMainCRTStartup"); - addEquivSymbols("__alloca_probe","__chkstk"); - addEquivSymbols("_strncpy_s_downlevel","_strncpy_s"); - addEquivSymbols("_strcpy_s_downlevel","_strcpy_s"); + addEquivSymbols("entry", "_WinMainCRTStartup"); + addEquivSymbols("__alloca_probe", "__chkstk"); + addEquivSymbols("_strncpy_s_downlevel", "_strncpy_s"); + addEquivSymbols("_strcpy_s_downlevel", "_strcpy_s"); addEquivSymbols("strcat_s_downlevel", "strcat_s"); - addEquivSymbols("_memcpy_s_downlevel","_memcpy_s"); + addEquivSymbols("_memcpy_s_downlevel", "_memcpy_s"); addEquivSymbols("_memmove_s_downlevel", "_memmove_s"); - addEquivSymbols("__ftol2_downlevel","__ftol2"); + addEquivSymbols("__ftol2_downlevel", "__ftol2"); addEquivSymbols("_wmakepath_s_downlevel", "_wmakepath_s"); addEquivSymbols("entry", "_wWinMainCRTStartup"); addEquivSymbols("entry", "_wmainCRTStartup"); addEquivSymbols("entry", "_mainCRTStartup"); - addEquivSymbols("entry","__DllMainCRTStartup@12"); + addEquivSymbols("entry", "__DllMainCRTStartup@12"); addEquivSymbols("_errno", "__doserrno"); - addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyW@12"); + addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyW@12"); addEquivSymbols("_StringCchCopyNW@16", "?StringCchCopyNW@@YGJPAGIPBGI@Z"); - addEquivSymbols("_StringCchLengthW@12","?StringCchLengthW@@YGJPB_WIPAI@Z"); + addEquivSymbols("_StringCchLengthW@12", "?StringCchLengthW@@YGJPB_WIPAI@Z"); addEquivSymbols("_StringCchLengthA@12", "?StringCchLengthA@@YGJPBDIPAI@Z"); - addEquivSymbols("_RtlStringCchCopyW@12","=_StringCchCopyW@12"); - addEquivSymbols("?RtlStringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyA@12"); - addEquivSymbols("_RtlStringCchCopyW@12","_StringCchCopyW@12"); + addEquivSymbols("_RtlStringCchCopyW@12", "=_StringCchCopyW@12"); + addEquivSymbols("?RtlStringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyA@12"); + addEquivSymbols("_RtlStringCchCopyW@12", "_StringCchCopyW@12"); addEquivSymbols("_RtlStringCchCopyNW@16", "?StringCchCopyNW@@YGJPAGIPBGI@Z"); addEquivSymbols("?RtlStringCchLengthW@@YGJPBGIPAI@Z", "?StringCchLengthW@@YGJPB_WIPAI@Z"); addEquivSymbols("_RtlStringCchLengthW@12", "?StringCchLengthW@@YGJPB_WIPAI@Z"); addEquivSymbols("?RtlStringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12"); addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12"); addEquivSymbols("_StringCchCatW@12", "_StringCchCatA@12"); - addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyA@12"); - addEquivSymbols("?ULongLongToUInt@@YGJ_KPAI@Z","_ULongLongToULong@12"); - addEquivSymbols("_ULongLongToUInt@12","_ULongLongToULong@12"); - addEquivSymbols("_ULongLongToUInt@12","_ULongLongToULong@12"); - addEquivSymbols("?ULongLongToULong@@YGJ_KPAK@Z","_ULongLongToULong@12"); + addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyA@12"); + addEquivSymbols("?ULongLongToUInt@@YGJ_KPAI@Z", "_ULongLongToULong@12"); + addEquivSymbols("_ULongLongToUInt@12", "_ULongLongToULong@12"); + addEquivSymbols("_ULongLongToUInt@12", "_ULongLongToULong@12"); + addEquivSymbols("?ULongLongToULong@@YGJ_KPAK@Z", "_ULongLongToULong@12"); addEquivSymbols("_RtlULongLongToULong@12", "_ULongLongToULong@12"); addEquivSymbols("_RtlULongLongToUInt@12", "_ULongLongToULong@12"); addEquivSymbols("?RtlULongLongToULong@@YGJ_KPAK@Z", "_ULongLongToULong@12"); addEquivSymbols("?ULongPtrAdd@@YGJKKPAK@Z", "_ULongAdd@12"); - addEquivSymbols("_ULongAdd@12","?ULongAdd@@YGJKKPAK@Z"); - addEquivSymbols("_ULongAdd@12","?SizeTAdd@@YGJIIPAI@Z"); - addEquivSymbols("_ULongAdd@12","?UIntAdd@@YGJIIPAI@Z"); - addEquivSymbols("_ULongAdd@12","?SIZETAdd@@YGJKKPAK@Z"); - addEquivSymbols("_RtlULongAdd@12","?RtlULongAdd@@YGJKKPAK@Z"); - addEquivSymbols("_RtlSIZETAdd@12","?RtlULongAdd@@YGJKKPAK@Z"); - addEquivSymbols("_UIntAdd@12","_ULongAdd@12"); - addEquivSymbols("LoadStringA","LoadStringW"); + addEquivSymbols("_ULongAdd@12", "?ULongAdd@@YGJKKPAK@Z"); + addEquivSymbols("_ULongAdd@12", "?SizeTAdd@@YGJIIPAI@Z"); + addEquivSymbols("_ULongAdd@12", "?UIntAdd@@YGJIIPAI@Z"); + addEquivSymbols("_ULongAdd@12", "?SIZETAdd@@YGJKKPAK@Z"); + addEquivSymbols("_RtlULongAdd@12", "?RtlULongAdd@@YGJKKPAK@Z"); + addEquivSymbols("_RtlSIZETAdd@12", "?RtlULongAdd@@YGJKKPAK@Z"); + addEquivSymbols("_UIntAdd@12", "_ULongAdd@12"); + addEquivSymbols("LoadStringA", "LoadStringW"); addEquivSymbols("_StringCchCopyW@12", "_StringCchCopyA@12"); - addEquivSymbols("?StringCchCopyA@@YGJPADIPBD@Z","_StringCchCopyA@12"); - addEquivSymbols("StringCchVPrintfA","StringCchVPrintfW"); + addEquivSymbols("?StringCchCopyA@@YGJPADIPBD@Z", "_StringCchCopyA@12"); + addEquivSymbols("StringCchVPrintfA", "StringCchVPrintfW"); addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatW@12"); addEquivSymbols("__safecrt_fassign", "__fassign_l"); - addEquivSymbols("?StringLengthWorkerW@@YGJPBGIPAI@Z","_StringLengthWorkerW@12"); + addEquivSymbols("?StringLengthWorkerW@@YGJPBGIPAI@Z", "_StringLengthWorkerW@12"); addEquivSymbols("?StringCatWorkerW@@YGJPAGIPBG@Z", "_StringCatWorkerW@12"); - addEquivSymbols("_decode_aligned_offset_block@12","_decode_verbatim_block@12"); - addEquivSymbols("??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@ABV01@@Z", - "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z"); + addEquivSymbols("_decode_aligned_offset_block@12", "_decode_verbatim_block@12"); + addEquivSymbols( + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@ABV01@@Z", + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z"); addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@PBGHPAUIAtlStringMgr@1@@Z", - "??0?$CSimpleStringT@_W$0A@@ATL@@QAE@PB_WHPAUIAtlStringMgr@1@@Z"); - addEquivSymbols("_NFMdeco_destroy@8","_NFMcomp_destroy@8"); - addEquivSymbols("_StringCchVPrintfW@16","?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); - addEquivSymbols("_StringCbVPrintfA@16","?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); + "??0?$CSimpleStringT@_W$0A@@ATL@@QAE@PB_WHPAUIAtlStringMgr@1@@Z"); + addEquivSymbols("_NFMdeco_destroy@8", "_NFMcomp_destroy@8"); + addEquivSymbols("_StringCchVPrintfW@16", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); + addEquivSymbols("_StringCbVPrintfA@16", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ"); - addEquivSymbols("_StringCchPrintfW","?StringCchPrintfW@@YAJPAGIPBGZZ"); - addEquivSymbols("_StringCbPrintfA","?StringCchPrintfW@@YAJPAGIPBGZZ"); - addEquivSymbols("?AtlA2WHelper@@YGPAGPAGPBDH@Z","?AfxA2WHelper@@YGPA_WPA_WPBDH@Z"); + addEquivSymbols("_StringCchPrintfW", "?StringCchPrintfW@@YAJPAGIPBGZZ"); + addEquivSymbols("_StringCbPrintfA", "?StringCchPrintfW@@YAJPAGIPBGZZ"); + addEquivSymbols("?AtlA2WHelper@@YGPAGPAGPBDH@Z", "?AfxA2WHelper@@YGPA_WPA_WPBDH@Z"); addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z", - "??0?$CSimpleStringT@D$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z"); - addEquivSymbols("_RtlStringCchCopyA@12","?StringCchCopyA@@YGJPADIPBD@Z"); - addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGHPAUIAtlStringMgr@1@@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z"); - addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@ABV01@@Z","??0?$CSimpleStringT@D$0A@@ATL@@QAE@ABV01@@Z"); - addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGPAUIAtlStringMgr@1@@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_WPAUIAtlStringMgr@1@@Z"); - addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@ABV01@@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@ABV01@@Z"); - addEquivSymbols("__ltoa_s_downlevel","__ltow_s"); - addEquivSymbols("??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@XZ", - "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ"); - addEquivSymbols("_StringCchPrintfA","?StringCchPrintfW@@YAJPAGIPBGZZ"); + "??0?$CSimpleStringT@D$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z"); + addEquivSymbols("_RtlStringCchCopyA@12", "?StringCchCopyA@@YGJPADIPBD@Z"); + addEquivSymbols( + "??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGHPAUIAtlStringMgr@1@@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z"); + addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@ABV01@@Z", + "??0?$CSimpleStringT@D$0A@@ATL@@QAE@ABV01@@Z"); + addEquivSymbols( + "??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGPAUIAtlStringMgr@1@@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_WPAUIAtlStringMgr@1@@Z"); + addEquivSymbols( + "??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@ABV01@@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@ABV01@@Z"); + addEquivSymbols("__ltoa_s_downlevel", "__ltow_s"); + addEquivSymbols( + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@XZ", + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ"); + addEquivSymbols("_StringCchPrintfA", "?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("?StringCbPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("?ULongMult@@YGJKKPAK@Z", "_ULongMult@12"); addEquivSymbols("?_Getwctypes@@YAPB_WPB_W0PAFPBU_Ctypevec@@@Z", "__Getwctypes"); addEquivSymbols("?_Getwctype@@YAF_WPBU_Ctypevec@@@Z", "__Getwctype"); addEquivSymbols("?_Getwctype@@YAF_WPEBU_Ctypevec@@@Z", "_Getwctype"); addEquivSymbols("?AtlW2AHelper@@YGPADPADPBGH@Z", "?AfxW2AHelper@@YGPADPADPB_WH@Z"); - addEquivSymbols("??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@ID@Z", - "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ID@Z"); - addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ","?StringCbPrintfA@@YAJPADIPBDZZ"); - addEquivSymbols("??0?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z"); - addEquivSymbols("_wmemcpy_s","?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z"); - addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z","_StringCbCopyA@12"); - addEquivSymbols("??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@V_STL70@@@std@@QAE@IG@Z", - "??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@IG@Z"); + addEquivSymbols( + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@ID@Z", + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ID@Z"); + addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ", "?StringCbPrintfA@@YAJPADIPBDZZ"); + addEquivSymbols( + "??0?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z"); + addEquivSymbols("_wmemcpy_s", + "?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z"); + addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z", "_StringCbCopyA@12"); + addEquivSymbols( + "??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@V_STL70@@@std@@QAE@IG@Z", + "??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@IG@Z"); addEquivSymbols("??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@XZ", "??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@V_STL70@@@std@@QEAA@XZ"); addEquivSymbols("?CopyChars@?$CSimpleStringT@G$0A@@ATL@@SAXPAGIPBGH@Z", - "?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z"); - addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGPAUIAtlStringMgr@1@@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_WPAUIAtlStringMgr@1@@Z"); + "?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z"); + addEquivSymbols( + "??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGPAUIAtlStringMgr@1@@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_WPAUIAtlStringMgr@1@@Z"); addEquivSymbols("wcscpy_s_downlevel", "wcscpy_s"); addEquivSymbols("_StringCbCopyA@12", "_StringCchCopyA@12"); addEquivSymbols("_wcscat_s_downlevel", "_wcscat_s"); - addEquivSymbols("??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@PBD@Z", - "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z"); + addEquivSymbols( + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@PBD@Z", + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z"); addEquivSymbols("?_Towupper@@YA_W_WPBU_Ctypevec@@@Z", "__Towupper"); addEquivSymbols("?_Towlower@@YA_W_WPBU_Ctypevec@@@Z", "__Towlower"); addEquivSymbols("?_Towupper@@YA_W_WPEBU_Ctypevec@@@Z", "_Towupper"); addEquivSymbols("?_Towlower@@YA_W_WPEBU_Ctypevec@@@Z", "_Towlower"); addEquivSymbols("_wcsncpy_s_downlevel", "_wcsncpy_s"); addEquivSymbols("_strnlen_downlevel", "_strnlen"); - addEquivSymbols("GetProxyDllInfo","_GetProxyDllInfo@8"); - addEquivSymbols("DllGetClassObject","_DllGetClassObject@12"); + addEquivSymbols("GetProxyDllInfo", "_GetProxyDllInfo@8"); + addEquivSymbols("DllGetClassObject", "_DllGetClassObject@12"); addEquivSymbols("_PrxDllGetClassObject@12", "_DllGetClassObject@12"); addEquivSymbols("__itoa_s_downlevel", "__itow_s"); addEquivSymbols("?StringCbVPrintfA@@YGJPADIPBD0@Z", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); addEquivSymbols("?UShortMult@@YGJGGPAG@Z", "?RtlUShortMult@@YGJGGPAG@Z"); addEquivSymbols("??1?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@XZ", - "??1?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsOS@_W@ATL@@@@@ATL@@QAE@XZ"); - addEquivSymbols("?memcpy_s@Checked@ATL@@YAXPAXIPBXI@Z", "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); - addEquivSymbols("?tcsncpy_s@Checked@ATL@@YAHPAGIPBGI@Z", "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); - addEquivSymbols("?wmemcpy_s@Checked@ATL@@YAXPAGIPBGI@Z", "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); - addEquivSymbols("??$AtlMultiply@I@ATL@@YAJPAIII@Z","??$AtlMultiply@K@ATL@@YAJPAKKK@Z"); + "??1?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsOS@_W@ATL@@@@@ATL@@QAE@XZ"); + addEquivSymbols("?memcpy_s@Checked@ATL@@YAXPAXIPBXI@Z", + "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); + addEquivSymbols("?tcsncpy_s@Checked@ATL@@YAHPAGIPBGI@Z", + "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); + addEquivSymbols("?wmemcpy_s@Checked@ATL@@YAXPAGIPBGI@Z", + "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); + addEquivSymbols("??$AtlMultiply@I@ATL@@YAJPAIII@Z", "??$AtlMultiply@K@ATL@@YAJPAKKK@Z"); addEquivSymbols("__it_wcsncpy", "_wcsncpy"); - addEquivSymbols("??1?$CFixedStringT@V?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@$0BA@@ATL@@UAE@XZ", - "??1?$CFixedStringT@V?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@$0EA@@ATL@@UAE@XZ"); + addEquivSymbols( + "??1?$CFixedStringT@V?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@$0BA@@ATL@@UAE@XZ", + "??1?$CFixedStringT@V?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@$0EA@@ATL@@UAE@XZ"); addEquivSymbols("?StringCbCatA@@YGJPADIPBD@Z", "_StringCchCatA@12"); - addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBG@Z", - "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_W@Z"); + addEquivSymbols( + "??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBG@Z", + "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_W@Z"); addEquivSymbols("UShortAdd", "RtlUShortAdd"); addEquivSymbols("_StringCchPrintfA", "?StringCbPrintfA@@YAJPADIPBDZZ"); addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z", "_StringCchCopyA@12"); // 64-bit - addEquivSymbols("??1?$CTempBuffer@G$0BAA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ","??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); - addEquivSymbols("?IsEqualGUID@@YAHAEBU_GUID@@0@Z","IsEqualGUID"); - addEquivSymbols("??1?$CAtlSafeAllocBufferManager@V_CCRTAllocator@_ATL_SAFE_ALLOCA_IMPL@ATL@@@_ATL_SAFE_ALLOCA_IMPL@ATL@@QEAA@XZ", - "??1?$CAtlSafeAllocBufferManager@VCCRTAllocator@ATL@@@_ATL_SAFE_ALLOCA_IMPL@ATL@@QEAA@XZ"); - addEquivSymbols("??_E_Locimp@locale@std@@MEAAPEAXI@Z","??_G_Locimp@locale@std@@MEAAPEAXI@Z"); - addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z","StringCchCopyW"); - addEquivSymbols("StringCchPrintfA","?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); - addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z","StringCchCatA"); - addEquivSymbols("?StringCbCatA@@YAJPEAD_KPEBD@Z","StringCchCatA"); - addEquivSymbols("entry","mainCRTStartup"); - addEquivSymbols("entry","wmainCRTStartup"); - addEquivSymbols("entry","WinMainCRTStartup"); - addEquivSymbols("WPP_SF_ii","WPP_SF_qq"); - addEquivSymbols("WPP_SF_DDDDD","WPP_SF_ddddd"); - addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z","FDIDestroy"); - addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ","??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); - addEquivSymbols("WPP_SF_xx","WPP_SF_qq"); - addEquivSymbols("WPP_SF_iii","WPP_SF_qqq"); - addEquivSymbols("RtlStringCchCopyW","StringCchCopyW"); - addEquivSymbols("_strcmpi","_stricmp"); - addEquivSymbols("WPP_SF_DDDDDDDD","WPP_SF_dddddddd"); - addEquivSymbols("?StringCchPrintfA@@YAJPEAD_KPEBDZZ","?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); - addEquivSymbols("WPP_SF_h","WPP_SF_H"); - addEquivSymbols("WPP_SF_qqDD","WPP_SF_qqdd"); - addEquivSymbols("WPP_SF_DqD","WPP_SF_dqd"); - addEquivSymbols("WPP_SF_Dq","WPP_SF_dq"); + addEquivSymbols("??1?$CTempBuffer@G$0BAA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ", + "??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); + addEquivSymbols("?IsEqualGUID@@YAHAEBU_GUID@@0@Z", "IsEqualGUID"); + addEquivSymbols( + "??1?$CAtlSafeAllocBufferManager@V_CCRTAllocator@_ATL_SAFE_ALLOCA_IMPL@ATL@@@_ATL_SAFE_ALLOCA_IMPL@ATL@@QEAA@XZ", + "??1?$CAtlSafeAllocBufferManager@VCCRTAllocator@ATL@@@_ATL_SAFE_ALLOCA_IMPL@ATL@@QEAA@XZ"); + addEquivSymbols("??_E_Locimp@locale@std@@MEAAPEAXI@Z", + "??_G_Locimp@locale@std@@MEAAPEAXI@Z"); + addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z", "StringCchCopyW"); + addEquivSymbols("StringCchPrintfA", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); + addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA"); + addEquivSymbols("?StringCbCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA"); + addEquivSymbols("entry", "mainCRTStartup"); + addEquivSymbols("entry", "wmainCRTStartup"); + addEquivSymbols("entry", "WinMainCRTStartup"); + addEquivSymbols("WPP_SF_ii", "WPP_SF_qq"); + addEquivSymbols("WPP_SF_DDDDD", "WPP_SF_ddddd"); + addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z", "FDIDestroy"); + addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ", + "??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); + addEquivSymbols("WPP_SF_xx", "WPP_SF_qq"); + addEquivSymbols("WPP_SF_iii", "WPP_SF_qqq"); + addEquivSymbols("RtlStringCchCopyW", "StringCchCopyW"); + addEquivSymbols("_strcmpi", "_stricmp"); + addEquivSymbols("WPP_SF_DDDDDDDD", "WPP_SF_dddddddd"); + addEquivSymbols("?StringCchPrintfA@@YAJPEAD_KPEBDZZ", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); + addEquivSymbols("WPP_SF_h", "WPP_SF_H"); + addEquivSymbols("WPP_SF_qqDD", "WPP_SF_qqdd"); + addEquivSymbols("WPP_SF_DqD", "WPP_SF_dqd"); + addEquivSymbols("WPP_SF_Dq", "WPP_SF_dq"); addEquivSymbols("std::vector<>::_Assign_rv", "std::vector<>::_Move_assign_from"); addEquivSymbols("std::vector<>::_Assign_rv", "std::vector<>::_Move_from"); } @@ -360,21 +383,20 @@ public class FidStatistics extends GhidraScript { } } - private boolean checkNames(String a,String b) { + private boolean checkNames(String a, String b) { if (a.equals(b)) { return true; } - return equivSymbols.contains(new SymbolPair(a,b)); + return equivSymbols.contains(new SymbolPair(a, b)); } private String chooseFunctionName(FidSearchResult result) { Program program = result.function.getProgram(); - Symbol[] symbols = program.getSymbolTable().getSymbols(result.function.getEntryPoint()); - if (symbols.length > 1) { - for (Symbol symbol : symbols) { - if (matchAnalysis.containsRawName(symbol.getName())) { - return symbol.getName(); - } + SymbolIterator it = + program.getSymbolTable().getSymbolsAsIterator(result.function.getEntryPoint()); + for (Symbol symbol : it) { + if (matchAnalysis.containsRawName(symbol.getName())) { + return symbol.getName(); } } return result.function.getName(); @@ -384,7 +406,7 @@ public class FidStatistics extends GhidraScript { throws CancelledException, IOException { StatRecord record = statRecord; record.totalFunction += 1; - if (result.matches==null || result.matches.size() == 0) { + if (result.matches == null || result.matches.size() == 0) { record.noMatch += 1; } else { @@ -407,17 +429,17 @@ public class FidStatistics extends GhidraScript { NameVersions nameVersions = NameVersions.generate(funcName, program); boolean exactNameMatch = false; Iterator iter = matchAnalysis.getRawNameIterator(); - while(iter.hasNext()) { + while (iter.hasNext()) { String raw = iter.next(); NameVersions matchNames = NameVersions.generate(raw, program); if (matchNames.rawName == null) { continue; } - if (checkNames(nameVersions.rawName,matchNames.rawName)) { + if (checkNames(nameVersions.rawName, matchNames.rawName)) { exactNameMatch = true; break; } - if (checkNames(nameVersions.similarName,matchNames.similarName)) { + if (checkNames(nameVersions.similarName, matchNames.similarName)) { exactNameMatch = true; break; } @@ -441,7 +463,7 @@ public class FidStatistics extends GhidraScript { if (matchNames.demangledBaseName == null) { continue; } - if (checkNames(nameVersions.demangledBaseName,matchNames.demangledBaseName)) { + if (checkNames(nameVersions.demangledBaseName, matchNames.demangledBaseName)) { exactNameMatch = true; break; } @@ -463,7 +485,7 @@ public class FidStatistics extends GhidraScript { record.hitCount += 1; } if (exactNameMatch && ((score < scoreThreshold) || !matchHappened)) { - MatchRecord matchRecord = new MatchRecord(result,null,false); + MatchRecord matchRecord = new MatchRecord(result, null, false); StringBuilder buffer = new StringBuilder(); matchRecord.print(buffer); lowTruePositive.append(buffer.toString()); @@ -471,22 +493,23 @@ public class FidStatistics extends GhidraScript { } else if ((!exactNameMatch) && (score >= scoreThreshold) && matchHappened) { record.falsePositive += 1; - MatchRecord matchRecord = new MatchRecord(result,finalMatchName,true); + MatchRecord matchRecord = new MatchRecord(result, finalMatchName, true); StringBuilder buffer = new StringBuilder(); matchRecord.print(buffer); highFalsePositive.append(buffer.toString()); highFalsePositive.append('\n'); } } - + } - private void processProgram(Program program,FidQueryService queryService) throws MemoryAccessException, CancelledException, VersionException, IOException { - FidProgramSeeker programSeeker = service.getProgramSeeker(program,queryService, 10.0f); + private void processProgram(Program program, FidQueryService queryService) + throws MemoryAccessException, CancelledException, VersionException, IOException { + FidProgramSeeker programSeeker = service.getProgramSeeker(program, queryService, 10.0f); monitor.setMessage("Processing " + program.getName()); monitor.initialize(program.getFunctionManager().getFunctionCount()); FunctionIterator iter = program.getFunctionManager().getFunctionsNoStubs(true); - while(iter.hasNext()) { + while (iter.hasNext()) { Function func = iter.next(); monitor.incrementProgress(1); if (func.getName().startsWith("FUN_") || func.getName().startsWith("Ordinal_")) { @@ -500,7 +523,8 @@ public class FidStatistics extends GhidraScript { } } - private LinkedList buildDomainFileList() throws CancelledException, VersionException, IOException { + private LinkedList buildDomainFileList() + throws CancelledException, VersionException, IOException { ArrayList folders = new ArrayList(); while (true) { monitor.checkCanceled(); @@ -526,12 +550,12 @@ public class FidStatistics extends GhidraScript { @Override protected void run() throws Exception { initialize(); - + LinkedList programList = buildDomainFileList(); File lowFile = askFile("Select file to report true matches", "OK"); File highFile = askFile("Select file to report false positives", "OK"); - scoreThreshold = (float)askDouble("Choose score threshold", "OK"); - + scoreThreshold = (float) askDouble("Choose score threshold", "OK"); + lowTruePositive = new FileWriter(lowFile); highFalsePositive = new FileWriter(highFile); @@ -540,7 +564,7 @@ public class FidStatistics extends GhidraScript { int maxPrograms = programList.size(); int counter = 0; try { - for(DomainFile domainFile : programList) { + for (DomainFile domainFile : programList) { Program program = null; try { program = (Program) domainFile.getDomainObject(this, false, false, monitor); @@ -551,7 +575,7 @@ public class FidStatistics extends GhidraScript { lastLanguage = program.getLanguage(); queryService = service.openFidQueryService(lastLanguage, false); } - processProgram(program,queryService); + processProgram(program, queryService); counter += 1; monitor.setMessage("Processing programs ..."); monitor.initialize(maxPrograms); @@ -563,14 +587,15 @@ public class FidStatistics extends GhidraScript { } } } - } catch(CancelledException ex) { + } + catch (CancelledException ex) { // A cancel in middle of processing still allows results to get printed } queryService.close(); lowTruePositive.close(); highFalsePositive.close(); - + println(StatRecord.getColumns()); StringBuilder buffer = new StringBuilder(); statRecord.print(buffer); diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java index f1fee20eae..b88d432404 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java @@ -278,7 +278,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { private boolean hasUserOrImportedSymbols(Function function) { Program program = function.getProgram(); SymbolTable symbolTable = program.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols(function.getEntryPoint()); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(function.getEntryPoint()); for (Symbol symbol : symbols) { SourceType sourceType = symbol.getSource(); if (sourceType == SourceType.USER_DEFINED || sourceType == SourceType.IMPORTED) { @@ -297,39 +297,26 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { } /** - * Delete a symbol of the given name and address, knowing there are multiple Symbols at the address. - * If the symbol is primary, make another Symbol at the address primary before deleting + * Delete a symbol of the given name at the given address. + * * @param matchName is the given Symbol name * @param addr is the given Address * @param program is the Program * @return the number of Symbols remaining at the address */ private int deleteSymbol(String matchName, Address addr, Program program) { - int numSymbols = 0; - for (int i = 0; i < 2; ++i) { // Try to find non-primary matching Symbol at most twice - Symbol[] symbols = program.getSymbolTable().getSymbols(addr); - numSymbols = symbols.length; - if (numSymbols <= 1) { + Symbol[] symbols = program.getSymbolTable().getSymbols(addr); + int numSymbols = symbols.length; + if (numSymbols <= 1) { + return numSymbols; + } + // find the matching symbol and delete it + for (Symbol sym : symbols) { + if (sym.getName().equals(matchName)) { + sym.delete(); + numSymbols -= 1; break; } - for (Symbol sym : symbols) { // Among Symbols at the Address - if (sym.getName().equals(matchName)) { // Find one with matching name - if (!sym.isPrimary()) { // If it is not primary - sym.delete(); // delete it immediately - numSymbols -= 1; - break; // and we are done - } - Symbol otherSym = symbols[0]; - if (otherSym == sym) { // Otherwise find another Symbol, which must not be primary - otherSym = symbols[1]; - } - // Set the other symbol to primary - SetLabelPrimaryCmd cmd = new SetLabelPrimaryCmd(addr, otherSym.getName(), - otherSym.getParentNamespace()); - cmd.applyTo(program); - break; - } - } } return numSymbols; } @@ -390,7 +377,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { BookmarkManager bookmarkManager = function.getProgram().getBookmarkManager(); bookmarkManager.setBookmark(addr, BookmarkType.ANALYSIS, FIDCONFLICT_BOOKMARK_CATEGORY, - "Multiple likely matching functions"); + "Multiple likely matching functions"); } } } diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java index d4ff4662f0..6a0888a031 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java @@ -460,14 +460,9 @@ class FidServiceLibraryIngest { } private static String grabSymbol(SymbolTable symbolTable, Address address) { - Symbol[] symbols = symbolTable.getSymbols(address); - if (symbols == null || symbols.length == 0) { - return null; - } - for (Symbol symbol : symbols) { - if (symbol.isPrimary()) { - return symbol.getName(); - } + Symbol primary = symbolTable.getPrimarySymbol(address); + if (primary != null) { + return primary.getName(); } return null; } diff --git a/Ghidra/Features/MicrosoftCodeAnalyzer/ghidra_scripts/FixUpRttiAnalysisScript.java b/Ghidra/Features/MicrosoftCodeAnalyzer/ghidra_scripts/FixUpRttiAnalysisScript.java index b6598df050..d6916b4f5c 100644 --- a/Ghidra/Features/MicrosoftCodeAnalyzer/ghidra_scripts/FixUpRttiAnalysisScript.java +++ b/Ghidra/Features/MicrosoftCodeAnalyzer/ghidra_scripts/FixUpRttiAnalysisScript.java @@ -264,8 +264,10 @@ public class FixUpRttiAnalysisScript extends GhidraScript { Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4)); Data baseClassDescriptor = getDataAt(baseClassDescriptorAddress); - if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals( - RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { + if (baseClassDescriptor == null || !baseClassDescriptor.getDataType() + .getName() + .equals( + RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { int num1 = getInt(baseClassDescriptorAddress.add(8)); int num2 = getInt(baseClassDescriptorAddress.add(12)); @@ -352,8 +354,10 @@ public class FixUpRttiAnalysisScript extends GhidraScript { Data classHierarchyStructure = getDataAt(classHierarchyDescriptorAddress); if (classHierarchyStructure != null && - classHierarchyStructure.getDataType().getName().equals( - RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { + classHierarchyStructure.getDataType() + .getName() + .equals( + RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { return classHierarchyDescriptorAddress; } @@ -588,7 +592,7 @@ public class FixUpRttiAnalysisScript extends GhidraScript { private Symbol getGivenSymbol(Address address, String name, Namespace namespace) throws CancelledException { - Symbol[] symbols = symbolTable.getSymbols(address); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address); for (Symbol sym : symbols) { monitor.checkCanceled(); if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) { diff --git a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/EHDataTypeUtilities.java b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/EHDataTypeUtilities.java index 36288d3e6d..83301b446d 100644 --- a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/EHDataTypeUtilities.java +++ b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/EHDataTypeUtilities.java @@ -278,7 +278,7 @@ public class EHDataTypeUtilities { dataTypeName = SymbolUtilities.replaceInvalidChars(dataTypeName, true); SymbolTable symbolTable = program.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols(address); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address); for (Symbol symbol : symbols) { if (symbol.getName().contains(dataTypeName)) { return null; // Already have one with dataTypeName. diff --git a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java index 587772cc65..050ff96bee 100644 --- a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java +++ b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java @@ -65,7 +65,7 @@ public class RttiUtil { */ static boolean createSymbolFromDemangledType(Program program, Address rttiAddress, TypeDescriptorModel typeDescriptorModel, String rttiSuffix) { - + rttiSuffix = SymbolUtilities.replaceInvalidChars(rttiSuffix, true); // Get or create the namespace for this RTTI's type descriptor. @@ -97,7 +97,7 @@ public class RttiUtil { return false; } // Don't create it if a similar symbol already exists at the address of the data. - Symbol[] symbols = symbolTable.getSymbols(rttiAddress); + SymbolIterator symbols = symbolTable.getSymbolsAsIterator(rttiAddress); for (Symbol symbol : symbols) { String name = symbol.getName(); if (name.contains(rttiSuffix)) { @@ -159,7 +159,7 @@ public class RttiUtil { } // check in .text and .nep if either exists - if ( textBlock != null || nepBlock != null) { + if (textBlock != null || nepBlock != null) { MemoryBlock refedBlock = memory.getBlock(referencedAddress); boolean inTextBlock = ((textBlock != null) && textBlock.equals(refedBlock)); boolean inNepBlock = ((nepBlock != null) && nepBlock.equals(refedBlock)); @@ -168,12 +168,12 @@ public class RttiUtil { break; // Not pointing to good section. } } - + // any references after the first one ends the table if (tableSize > 0 && referenceManager.hasReferencesTo(currentVfPointerAddress)) { break; } - + Function function = functionManager.getFunctionAt(referencedAddress); if (function == null && @@ -212,12 +212,12 @@ public class RttiUtil { boolean terminationRequest = false; Address commonVftableAddress = null; Program program; - + public CommonRTTIMatchCounter(Program program) { this.program = program; defaultPointerSize = program.getDefaultPointerSize(); } - + public Address getinfoVfTable() { return commonVftableAddress; } @@ -249,10 +249,10 @@ public class RttiUtil { } matchingAddrCount = 0; } - + commonVftableAddress = possibleVftableAddress; matchingAddrCount++; - + if (matchingAddrCount > MIN_MATCHING_VFTABLE_PTRS) { // done finding good addresses have at Minimum matching number terminationRequest = true; @@ -261,7 +261,7 @@ public class RttiUtil { return; } } - + /** * Method to figure out the type_info vftable address using pointed to value by all RTTI classes * @param program the current program @@ -293,7 +293,7 @@ public class RttiUtil { dataBlocks, set, monitor); infoVftableAddress = vfTableAddrChecker.getinfoVfTable(); } - + // cache result of search vftableMap.put(program, infoVftableAddress); @@ -308,18 +308,18 @@ public class RttiUtil { private static Address findTypeInfoVftableLabel(Program program) { SymbolTable symbolTable = program.getSymbolTable(); Namespace typeinfoNamespace = - symbolTable.getNamespace(TYPE_INFO_NAMESPACE, program.getGlobalNamespace()); + symbolTable.getNamespace(TYPE_INFO_NAMESPACE, program.getGlobalNamespace()); Symbol vftableSymbol = - symbolTable.getLocalVariableSymbol("vftable", typeinfoNamespace); + symbolTable.getLocalVariableSymbol("vftable", typeinfoNamespace); if (vftableSymbol != null) { return vftableSymbol.getAddress(); } - + vftableSymbol = symbolTable.getLocalVariableSymbol("`vftable'", typeinfoNamespace); if (vftableSymbol != null) { return vftableSymbol.getAddress(); } - + vftableSymbol = symbolTable.getLocalVariableSymbol("type_info", typeinfoNamespace); if (vftableSymbol != null) { return vftableSymbol.getAddress(); @@ -358,7 +358,8 @@ public class RttiUtil { } // check to see if symbol already exists both non-pdb and pdb versions - Symbol vftableSymbol = symbolTable.getSymbol(TYPE_INFO_NAMESPACE, address, typeinfoNamespace); + Symbol vftableSymbol = + symbolTable.getSymbol(TYPE_INFO_NAMESPACE, address, typeinfoNamespace); if (vftableSymbol != null) { return; } diff --git a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java index 52c82af406..1e620b0502 100644 --- a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java +++ b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java @@ -57,6 +57,7 @@ public class BlockGraphTask extends Task { private ColorizingService colorizingService; private final static String ENTRY_NEXUS_NAME = "Entry Points"; + private static final int MAX_SYMBOLS = 10; private CodeBlockModel blockModel; private AddressSetView selection; private ProgramLocation location; @@ -417,14 +418,20 @@ public class BlockGraphTask extends Task { } private void addSymbolAttribute(AttributedVertex vertex, CodeBlock bb) { - Symbol[] symbols = program.getSymbolTable().getSymbols(bb.getMinAddress()); - if (symbols.length != 0) { + SymbolIterator it = program.getSymbolTable().getSymbolsAsIterator(bb.getMinAddress()); + int count = 0; + if (it.hasNext()) { StringBuffer buf = new StringBuffer(); - for (int i = 0; i < symbols.length; i++) { - if (i != 0) { + for (Symbol symbol : it) { + if (count != 0) { buf.append('\n'); } - buf.append(symbols[i].getName()); + // limit the number of symbols to include (there can be a ridiculous # of symbols) + if (count++ > MAX_SYMBOLS) { + buf.append("..."); + break; + } + buf.append(symbol.getName()); } vertex.setAttribute(SYMBOLS_ATTRIBUTE, buf.toString()); } diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/markuptype/LabelMarkupType.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/markuptype/LabelMarkupType.java index c51688ee90..fb614c0cf5 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/markuptype/LabelMarkupType.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/markuptype/LabelMarkupType.java @@ -15,8 +15,7 @@ */ package ghidra.feature.vt.api.markuptype; -import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_LABELS; -import static ghidra.feature.vt.gui.util.VTOptionDefines.LABELS; +import static ghidra.feature.vt.gui.util.VTOptionDefines.*; import java.util.*; @@ -232,10 +231,6 @@ public class LabelMarkupType extends VTMarkupType { LabelMarkupUtils.removeAllLabels(getDestinationProgram(association), destinationAddress); } - else if (replaceDefault) { - LabelMarkupUtils.removeDefaultLabels(getDestinationProgram(association), - destinationAddress); - } Program destinationProgram = getDestinationProgram(association); try { diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/util/LabelMarkupUtils.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/util/LabelMarkupUtils.java index c9c70a73d6..a4c158ccb6 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/util/LabelMarkupUtils.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/util/LabelMarkupUtils.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,31 +23,15 @@ import ghidra.program.model.symbol.SymbolTable; public class LabelMarkupUtils { - public static void removeDefaultLabels( Program destinationProgram, Address address ) { - SymbolTable symbolTable = destinationProgram.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols( address ); - for ( Symbol symbol : symbols ) { - if ( symbol instanceof FunctionSymbol ) { - continue; - } - - if ( !symbol.isDynamic() ) { - continue; - } - - symbolTable.removeSymbolSpecial( symbol ); - } - } - - public static void removeAllLabels( Program destinationProgram, Address address ) { - SymbolTable symbolTable = destinationProgram.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols( address ); - for ( Symbol symbol : symbols ) { - if ( symbol instanceof FunctionSymbol ) { - continue; - } - symbolTable.removeSymbolSpecial( symbol ); - } - } + public static void removeAllLabels(Program destinationProgram, Address address) { + SymbolTable symbolTable = destinationProgram.getSymbolTable(); + Symbol[] symbols = symbolTable.getSymbols(address); + for (Symbol symbol : symbols) { + if (symbol instanceof FunctionSymbol) { + continue; + } + symbolTable.removeSymbolSpecial(symbol); + } + } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/NamespaceUtils.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/NamespaceUtils.java index dad12522fa..94e7613e0e 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/NamespaceUtils.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/NamespaceUtils.java @@ -401,7 +401,7 @@ public class NamespaceUtils { return null; } - Symbol[] symbols = program.getSymbolTable().getSymbols(address); + SymbolIterator symbols = program.getSymbolTable().getSymbolsAsIterator(address); for (Symbol symbol : symbols) { if (symbol.getSymbolType() == SymbolType.FUNCTION && symbolPath.matchesPathOf(symbol)) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassembler.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassembler.java index d088ef61ab..f393c7ccd1 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassembler.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassembler.java @@ -757,16 +757,14 @@ public class PseudoDisassembler { for (Address flow : flows) { // does this reference a valid function? if (program != null) { - Symbol[] syms = program.getSymbolTable().getSymbols(flow); - for (Symbol sym : syms) { - if (sym.getSymbolType() == SymbolType.FUNCTION) { - didCallValidSubroutine = true; - break; - } + Symbol primary = program.getSymbolTable().getPrimarySymbol(flow); + if (primary.getSymbolType() == SymbolType.FUNCTION) { + didCallValidSubroutine = true; } } // if respecting execute flag on memory, test to make sure we did flow into non-execute memory - if (respectExecuteFlag && !execSet.isEmpty() && !execSet.contains(flow)) { + if (respectExecuteFlag && !execSet.isEmpty() && + !execSet.contains(flow)) { if (!flow.isExternalAddress()) { MemoryBlock block = memory.getBlock(flow); // flowing into non-executable, but readable memory is bad @@ -782,7 +780,9 @@ public class PseudoDisassembler { target = newTarget; } } - catch (InsufficientBytesException e) { + catch ( + + InsufficientBytesException e) { return false; } catch (UnknownInstructionException e) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDB.java index a53e3cea87..99e5fd5660 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDB.java @@ -270,16 +270,21 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol { try { checkIsValid(); ReferenceManager rm = symbolMgr.getReferenceManager(); - ReferenceIterator iter = rm.getReferencesTo(address); - boolean isPrimary = this.isPrimary(); - Symbol[] symbols = symbolMgr.getSymbols(address); - if (symbols.length == 1) { + + // if there is only one symbol, then all the references to this address count + if (hasExactlyOneSymbolAtAddress(address)) { return rm.getReferenceCountTo(address); } + + // search through references and see which ones apply specifically to this symbol + ReferenceIterator iter = rm.getReferencesTo(address); int count = 0; + boolean isPrimary = this.isPrimary(); while (iter.hasNext()) { Reference ref = iter.next(); long symbolID = ref.getSymbolID(); + // references refer to me if it matches my key or I'm primary and it doesn't + // specify a specific symbol id if (symbolID == key || (isPrimary && symbolID < 0)) { count++; } @@ -291,6 +296,15 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol { } } + private boolean hasExactlyOneSymbolAtAddress(Address addr) { + SymbolIterator it = symbolMgr.getSymbolsAsIterator(addr); + if (!it.hasNext()) { + return false; + } + it.next(); + return !it.hasNext(); + } + @Override public Reference[] getReferences(TaskMonitor monitor) { lock.acquire(); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java index f36c7b2c80..31241e3d59 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java @@ -600,7 +600,7 @@ public class SymbolManager implements SymbolTable, ManagerDB { if (sym.getSymbolType() == SymbolType.FUNCTION) { Address addr = sym.getAddress(); Function f = (Function) sym.getObject(); - Symbol nextPrimary = getNextPrimarySymbol(this, addr); + Symbol nextPrimary = findFirstNonPrimarySymbol(addr); String name; Namespace parentNamespace; SourceType source; @@ -636,20 +636,14 @@ public class SymbolManager implements SymbolTable, ManagerDB { } } -// @Override -// public boolean removeSymbol(Symbol sym) { -// return removeSymbolSpecial(sym); -// } - - private Symbol getNextPrimarySymbol(SymbolManager sm, Address addr2) { - Symbol[] symbols = sm.getSymbols(addr2); - Symbol next = null; - for (int i = symbols.length - 1; i >= 0; i--) { - if (!symbols[i].isPrimary()) { - return symbols[i]; // For now return the last non-primary found. + private Symbol findFirstNonPrimarySymbol(Address address) { + SymbolIterator it = getSymbolsAsIterator(address); + for (Symbol symbol : it) { + if (!symbol.isPrimary()) { + return symbol; // return the first non-primary symbol we find } } - return next; + return null; } void removeChildren(SymbolDB sym) { @@ -804,6 +798,21 @@ public class SymbolManager implements SymbolTable, ManagerDB { return false; } + public SymbolIterator getSymbolsAsIterator(Address addr) { + lock.acquire(); + try { + RecordIterator iterator = adapter.getSymbols(addr, addr, true); + return new SymbolRecordIterator(iterator, true, true); + } + catch (IOException e) { + program.dbError(e); + } + finally { + lock.release(); + } + return new SymbolRecordIterator(new EmptyRecordIterator(), true, true); + } + @Override public Symbol[] getSymbols(Address addr) { lock.acquire(); @@ -932,14 +941,7 @@ public class SymbolManager implements SymbolTable, ManagerDB { @Override public Symbol getGlobalSymbol(String name, Address addr) { - Symbol[] symbols = getSymbols(addr); - for (Symbol symbol : symbols) { - // there can be only one global symbol with a name at an address - if (symbol.getName().equals(name) && symbol.isGlobal()) { - return symbol; - } - } - return null; + return getSymbol(name, addr, program.getGlobalNamespace()); } @Override @@ -1714,9 +1716,9 @@ public class SymbolManager implements SymbolTable, ManagerDB { private void findNextDynamicSymbol() { while (addrIt.hasNext()) { - Symbol[] symbols = getSymbols(addrIt.next()); - if (symbols.length == 1 && symbols[0].isDynamic()) { - nextDynamicSymbol = symbols[0]; + Symbol symbol = getPrimarySymbol(addrIt.next()); + if (symbol != null && symbol.isDynamic()) { + nextDynamicSymbol = symbol; return; } } @@ -3062,28 +3064,3 @@ public class SymbolManager implements SymbolTable, ManagerDB { return getFirstSymbol(name, namespace, s -> s.getSymbolType() == type); } } - -class SymbolMatcher implements Predicate { - - private String name; - private Namespace namespace; - private SymbolType type1; - - public SymbolMatcher(String name, Namespace namespace, SymbolType type1) { - this.name = name; - this.namespace = namespace; - this.type1 = type1; - } - - @Override - public boolean test(Symbol s) { - if (!name.equals(s.getName())) { - return false; - } - if (!namespace.equals(s.getParentNamespace())) { - return false; - } - SymbolType type = s.getSymbolType(); - return type == type1; - } -} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java index af0d71e39e..8e017fb020 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java @@ -353,11 +353,26 @@ public interface SymbolTable { * the primary symbol will be returned in array slot 0. * WARNING! Use of this method with a Variable address is highly discouraged since * a single Variable address could be used multiple times by many functions. + * Note that unless all the symbols are needed at once, you should consider using + * the {@link #getSymbolsAsIterator(Address)} method instead. * @param addr the address at which to retrieve all symbols. * @return a zero-length array when no symbols are defined at address. + * @see #getSymbolsAsIterator(Address) */ public Symbol[] getSymbols(Address addr); + /** + * Returns a symbol iterator over all the symbols at the given address. Use this instead of + * {@link #getSymbols(Address)} when you do not need to get all symbols, but rather are + * searching for a particular symbol. This method prevents all symbols at the given address + * from being loaded up front. + * + * @param addr the address at which to retrieve all symbols + * @return an iterator over all the symbols at the given address + * @see #getSymbols(Address) + */ + public SymbolIterator getSymbolsAsIterator(Address addr); + /** * Returns an array of all user defined symbols at the given address * @param addr the address at which to retrieve all user defined symbols. diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolUtilities.java index 97ae28119e..dbbf836370 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolUtilities.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolUtilities.java @@ -1032,7 +1032,7 @@ public class SymbolUtilities { if (namespace.isGlobal()) { // do not add global symbol if same name already exists at address - for (Symbol s : program.getSymbolTable().getSymbols(address)) { + for (Symbol s : program.getSymbolTable().getSymbolsAsIterator(address)) { if (name.equals(s.getName())) { return null; }