Merge remote-tracking branch 'origin/GP-1073_ghidravore_checking_uses_of_getSymbols_address--SQUASHED'

This commit is contained in:
Ryan Kurtz 2021-10-07 08:27:14 -04:00
commit f7c31cc8fc
33 changed files with 530 additions and 550 deletions

View file

@ -326,6 +326,13 @@ public class DBTraceProgramViewSymbolTable implements SymbolTable {
} }
} }
@Override
public SymbolIterator getSymbolsAsIterator(Address addr) {
Symbol[] symbols = getSymbols(addr);
List<Symbol> list = Arrays.asList(symbols);
return new SymbolIteratorAdapter(list.iterator());
}
@Override @Override
public Symbol[] getUserSymbols(Address addr) { public Symbol[] getUserSymbols(Address addr) {
try (LockHold hold = program.trace.lockRead()) { try (LockHold hold = program.trace.lockRead()) {

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,7 +41,8 @@ public class AutoRenameLabelsScript extends GhidraScript {
int num = 1; int num = 1;
AddressSetView view = currentSelection; AddressSetView view = currentSelection;
if ((view == null) || (view.isEmpty())) return; if ((view == null) || (view.isEmpty()))
return;
// Obtain the symbol table and listing from program // Obtain the symbol table and listing from program
SymbolTable symbolTable = currentProgram.getSymbolTable(); SymbolTable symbolTable = currentProgram.getSymbolTable();
@ -51,12 +51,11 @@ public class AutoRenameLabelsScript extends GhidraScript {
AddressIterator it = view.getAddresses(true); AddressIterator it = view.getAddresses(true);
CompoundCmd cmd = new CompoundCmd("Auto Rename Labels"); CompoundCmd cmd = new CompoundCmd("Auto Rename Labels");
while(it.hasNext()) { while (it.hasNext()) {
Address address = it.next(); Address address = it.next();
Symbol[] symbols = symbolTable.getSymbols(address); Symbol primary = symbolTable.getPrimarySymbol(address);
Symbol defaultSymbol = getDynamicSymbol( symbols ); if (primary != null && primary.getSource() == SourceType.DEFAULT) {
if ( defaultSymbol != null ) { cmd.add(new RenameLabelCmd(address, null, base + num++, SourceType.USER_DEFINED));
cmd.add(new RenameLabelCmd(address, null, base+num++, SourceType.USER_DEFINED));
} }
} }
if (cmd.size() > 0) { if (cmd.size() > 0) {
@ -71,13 +70,4 @@ public class AutoRenameLabelsScript extends GhidraScript {
println("No default labels found in selection."); println("No default labels found in selection.");
} }
} }
private Symbol getDynamicSymbol( Symbol[] symbols ) {
for (int i=0;i<symbols.length;i++) {
if ( symbols[i].getSource() == SourceType.DEFAULT ) {
return symbols[i];
}
}
return null;
}
} }

View file

@ -201,7 +201,7 @@ public class GccRttiAnalysisScript extends GhidraScript {
// find the three special vtables and replace the incorrectly made array with // find the three special vtables and replace the incorrectly made array with
// data types found in vtable // data types found in vtable
boolean continueProcessing = createSpecialVtables(); boolean continueProcessing = createSpecialVtables();
if(!continueProcessing) { if (!continueProcessing) {
return; return;
} }
// find all typeinfo symbols and get their class namespace and create RecoveredClass object // find all typeinfo symbols and get their class namespace and create RecoveredClass object
@ -265,8 +265,10 @@ public class GccRttiAnalysisScript extends GhidraScript {
} }
} }
if(class_type_info_vtable == null && si_class_type_info_vtable == null && vmi_class_type_info_vtable == null) { if (class_type_info_vtable == null && si_class_type_info_vtable == null &&
println("Since there are no class typeinfo tables this program does not appear to have RTTI."); 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 false;
} }
return true; 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 // 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 // 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; return numLongs;
} }
@ -499,7 +501,10 @@ public class GccRttiAnalysisScript extends GhidraScript {
private void setIsGcc() { private void setIsGcc() {
isGcc = isGcc =
currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase( currentProgram.getCompilerSpec()
.getCompilerSpecID()
.getIdAsString()
.equalsIgnoreCase(
"gcc"); "gcc");
} }
@ -684,7 +689,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
*/ */
private void processVtables() throws Exception { private void processVtables() throws Exception {
// find all vtable symbols // find all vtable symbols
List<Symbol> listOfVtableSymbols = getListOfSymbolsInAddressSet( List<Symbol> listOfVtableSymbols = getListOfSymbolsInAddressSet(
currentProgram.getAddressFactory().getAddressSet(), VTABLE_LABEL, false); currentProgram.getAddressFactory().getAddressSet(), VTABLE_LABEL, false);
@ -700,7 +704,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
processVtable(vtableAddress, vtableNamespace, true); processVtable(vtableAddress, vtableNamespace, true);
} }
return; return;
} }
@ -756,7 +759,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
return; return;
} }
int numFunctionPointers = getNumFunctionPointers(vftableAddress, true, true); int numFunctionPointers = getNumFunctionPointers(vftableAddress, true, true);
// if at least one function pointer make vftable label - the createVftable method will // 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 // check for an internal vtable and make a symbol there if there is one
// will process them later // will process them later
Address possibleInternalVtableAddress = Address possibleInternalVtableAddress =
@ -1160,7 +1161,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
} }
} }
private Address findNextTypeinfoRef(Address startAddress) { private Address findNextTypeinfoRef(Address startAddress) {
int offset = 0; int offset = 0;
@ -1275,4 +1275,3 @@ public class GccRttiAnalysisScript extends GhidraScript {
} }
} }

View file

@ -970,10 +970,11 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer {
return false; 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)) { if (!memory.contains(testAddr)) {
Symbol syms[] = program.getSymbolTable().getSymbols(testAddr); Symbol symbol = program.getSymbolTable().getPrimarySymbol(testAddr);
if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) { if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
return false; return false;
} }
} }

View file

@ -78,7 +78,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
} }
@Override @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; int count = 0;
monitor = taskMonitor; monitor = taskMonitor;
@ -95,7 +96,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
monitor.setProgress(++count); monitor.setProgress(++count);
checkOperands(program, instr); checkOperands(program, instr);
} }
} finally { }
finally {
monitor = null; // get rid of the reference to it monitor = null; // get rid of the reference to it
} }
@ -123,22 +125,26 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
try { try {
switch (scalar.bitLength()) { switch (scalar.bitLength()) {
case 8: case 8:
if (program.getMemory().getByte(addr) == scalar.getSignedValue()) { if (program.getMemory().getByte(addr) == scalar
.getSignedValue()) {
found = true; found = true;
} }
break; break;
case 16: case 16:
if (program.getMemory().getShort(addr) == scalar.getSignedValue()) { if (program.getMemory().getShort(addr) == scalar
.getSignedValue()) {
found = true; found = true;
} }
break; break;
case 32: case 32:
if (program.getMemory().getInt(addr) == scalar.getSignedValue()) { if (program.getMemory().getInt(addr) == scalar
.getSignedValue()) {
found = true; found = true;
} }
break; break;
case 64: case 64:
if (program.getMemory().getLong(addr) == scalar.getSignedValue()) { if (program.getMemory().getLong(addr) == scalar
.getSignedValue()) {
found = true; found = true;
} }
break; break;
@ -162,7 +168,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
} }
// check the address in this space first // 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; continue;
} }
@ -209,10 +216,11 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
return false; 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)) { if (!program.getMemory().contains(addr)) {
Symbol syms[] = program.getSymbolTable().getSymbols(addr); Symbol symbol = program.getSymbolTable().getPrimarySymbol(addr);
if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) { if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
return false; return false;
} }
} }
@ -284,7 +292,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled); AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled);
if (table != null) { if (table != null) {
// add in an offcut reference // add in an offcut reference
program.getReferenceManager().addOffsetMemReference(refInstr.getMinAddress(), offAddr, program.getReferenceManager()
.addOffsetMemReference(refInstr.getMinAddress(), offAddr,
-entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); -entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
return; return;
} }
@ -321,7 +330,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
offAddr = lastGoodTable.getTopAddress(); offAddr = lastGoodTable.getTopAddress();
// add in an offcut reference // add in an offcut reference
program.getReferenceManager().addOffsetMemReference(instr.getMinAddress(), offAddr, program.getReferenceManager()
.addOffsetMemReference(instr.getMinAddress(), offAddr,
(i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex); (i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
return; return;
} }

View file

@ -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 // the presentation at the call or jump instruction, it doesn't matter which symbol of the
// same name you pick. // same name you pick.
private Symbol findSymbol(SymbolTable symTable, String currentLabel, Address symAddr) { private Symbol findSymbol(SymbolTable symTable, String currentLabel, Address symAddr) {
Symbol[] symbols = symTable.getSymbols(symAddr); SymbolIterator symbols = symTable.getSymbolsAsIterator(symAddr);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
if (symbol.getName(true).equals(currentLabel)) { if (symbol.getName(true).equals(currentLabel)) {
return symbol; return symbol;

View file

@ -153,7 +153,8 @@ public class MakeStringsTask extends ProgramTask {
if (paddingLength != 0) { if (paddingLength != 0) {
try { try {
program.getListing().createData(address.add(length), new AlignmentDataType(), program.getListing()
.createData(address.add(length), new AlignmentDataType(),
paddingLength); paddingLength);
} }
catch (Exception e) { catch (Exception e) {
@ -241,7 +242,7 @@ public class MakeStringsTask extends ProgramTask {
private boolean labelAlreadyExists(Address addr, String name) { private boolean labelAlreadyExists(Address addr, String name) {
SymbolTable symbolTable = program.getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(addr); SymbolIterator symbols = symbolTable.getSymbolsAsIterator(addr);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
if (symbol.getName().equals(name)) { if (symbol.getName().equals(name)) {
return true; return true;

View file

@ -287,12 +287,8 @@ class SymbolTableModel extends AddressBasedTableModel<Symbol> {
CompoundCmd cmd = new CompoundCmd("Delete symbol(s)"); CompoundCmd cmd = new CompoundCmd("Delete symbol(s)");
for (Symbol symbol : rowObjects) { for (Symbol symbol : rowObjects) {
if (symbol.isDynamic()) { 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); deleteList.add(symbol);
String label = symbol.getName(); String label = symbol.getName();

View file

@ -370,11 +370,9 @@ public class AddEditDialog extends DialogComponentProvider {
private FunctionSymbol getFunctionSymbol(Address address) { private FunctionSymbol getFunctionSymbol(Address address) {
SymbolTable symbolTable = program.getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(address); Symbol primary = symbolTable.getPrimarySymbol(address);
for (Symbol localSymbol : symbols) { if (primary instanceof FunctionSymbol) {
if (localSymbol instanceof FunctionSymbol) { return (FunctionSymbol) primary;
return (FunctionSymbol) localSymbol;
}
} }
return null; return null;
} }
@ -395,10 +393,8 @@ public class AddEditDialog extends DialogComponentProvider {
pinnedCheckBox.setEnabled(true); pinnedCheckBox.setEnabled(true);
pinnedCheckBox.setSelected(false); pinnedCheckBox.setSelected(false);
Symbol[] symbols = symbolTable.getSymbols(address); Symbol primarySymbol = symbolTable.getPrimarySymbol(address);
if (primarySymbol == null) {
FunctionSymbol functionSymbol = getFunctionSymbol(address);
if (functionSymbol == null && symbols.length == 0) {
primaryCheckBox.setSelected(true); primaryCheckBox.setSelected(true);
primaryCheckBox.setEnabled(false); primaryCheckBox.setEnabled(false);
} }
@ -463,9 +459,8 @@ public class AddEditDialog extends DialogComponentProvider {
nameBorder.setTitle("Enter Label:"); nameBorder.setTitle("Enter Label:");
entryPointCheckBox.setEnabled(true); entryPointCheckBox.setEnabled(true);
entryPointCheckBox.setSelected(symbolTable.isExternalEntryPoint(addr)); entryPointCheckBox.setSelected(symbolTable.isExternalEntryPoint(addr));
Symbol[] symbols = symbolTable.getSymbols(addr);
primaryCheckBox.setSelected(s.isPrimary()); primaryCheckBox.setSelected(s.isPrimary());
primaryCheckBox.setEnabled(!s.isPrimary() && symbols.length > 1); primaryCheckBox.setEnabled(!s.isPrimary());
pinnedCheckBox.setEnabled(true); pinnedCheckBox.setEnabled(true);
pinnedCheckBox.setSelected(s.isPinned()); pinnedCheckBox.setSelected(s.isPinned());
namespaceChoices.setEnabled(true); namespaceChoices.setEnabled(true);

View file

@ -537,7 +537,8 @@ public class ElfDefaultGotPltMarkup {
// Stop on first error but discard error bookmark since // Stop on first error but discard error bookmark since
// some plt sections are partly empty and must rely // some plt sections are partly empty and must rely
// on normal flow disassembly during analysis // on normal flow disassembly during analysis
prog.getBookmarkManager().removeBookmarks(set, BookmarkType.ERROR, prog.getBookmarkManager()
.removeBookmarks(set, BookmarkType.ERROR,
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor); Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
break;//we did not disassemble anything... break;//we did not disassemble anything...
} }
@ -604,11 +605,8 @@ public class ElfDefaultGotPltMarkup {
if (memory.contains(refAddr)) { if (memory.contains(refAddr)) {
return true; return true;
} }
Symbol syms[] = program.getSymbolTable().getSymbols(refAddr); Symbol primary = program.getSymbolTable().getPrimarySymbol(refAddr);
if (syms != null && syms.length > 0 && syms[0].getSource() != SourceType.DEFAULT) { return primary != null && primary.getSource() != SourceType.DEFAULT;
return true;
}
return false;
} }
private void removeMemRefs(Data data) { private void removeMemRefs(Data data) {

View file

@ -2360,9 +2360,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
.addMemoryReference(valueData.getAddress(), refAddr, RefType.DATA, .addMemoryReference(valueData.getAddress(), refAddr, RefType.DATA,
SourceType.ANALYSIS, 0); SourceType.ANALYSIS, 0);
if (label != null) { if (label != null) {
// add label if a non-default label does not exist // add label if no label exists of there is just a default label
Symbol[] symbols = program.getSymbolTable().getSymbols(refAddr); Symbol symbol = program.getSymbolTable().getPrimarySymbol(refAddr);
if (symbols.length == 0 || symbols[0].getSource() == SourceType.DEFAULT) { if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
createSymbol(refAddr, "_" + label, false, false, null); createSymbol(refAddr, "_" + label, false, false, null);
} }
} }

View file

@ -1377,7 +1377,7 @@ public class FlatProgramAPI {
*/ */
@Deprecated @Deprecated
public final Symbol getSymbolAt(Address address, String name) { public final Symbol getSymbolAt(Address address, String name) {
Symbol[] symbols = currentProgram.getSymbolTable().getSymbols(address); SymbolIterator symbols = currentProgram.getSymbolTable().getSymbolsAsIterator(address);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
if (symbol.getName().equals(name)) { if (symbol.getName().equals(name)) {
return symbol; return symbol;

View file

@ -199,7 +199,28 @@ public class SymbolManagerTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(!s.isGlobal()); assertTrue(!s.isGlobal());
assertTrue(s.getSource() == SourceType.USER_DEFINED); assertTrue(s.getSource() == SourceType.USER_DEFINED);
assertTrue(s.isPrimary()); 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 @Test

View file

@ -166,7 +166,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
byte[] gccBytes = { (byte) 0x47, (byte) 0x43, (byte) 0x43, (byte) 0x3a }; byte[] gccBytes = { (byte) 0x47, (byte) 0x43, (byte) 0x43, (byte) 0x3a };
byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
Address found = program.getMemory().findBytes(commentBlock.getStart(), Address found = program.getMemory()
.findBytes(commentBlock.getStart(),
commentBlock.getEnd(), gccBytes, maskBytes, true, monitor); commentBlock.getEnd(), gccBytes, maskBytes, true, monitor);
if (found == null) { if (found == null) {
return false; return false;
@ -256,7 +257,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
updateClassesWithParentsAndFlags(typeinfoSymbols); updateClassesWithParentsAndFlags(typeinfoSymbols);
// update the vftable offset map // update the vftable offset map
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
while (recoveredClassIterator.hasNext()) { while (recoveredClassIterator.hasNext()) {
@ -417,7 +417,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (specialTypeinfoRef.equals(vmi_class_type_info) || if (specialTypeinfoRef.equals(vmi_class_type_info) ||
specialTypeinfoRef.equals(vmi_class_type_info_vtable)) { specialTypeinfoRef.equals(vmi_class_type_info_vtable)) {
List<RecoveredClass> parents = List<RecoveredClass> parents =
addGccClassParentsFromVmiStruct(recoveredClass, typeinfoAddress); addGccClassParentsFromVmiStruct(recoveredClass, typeinfoAddress);
@ -493,7 +492,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
for (Address typeinfoRef : typeinfoReferencesNotInTypeinfoStructs) { for (Address typeinfoRef : typeinfoReferencesNotInTypeinfoStructs) {
monitor.checkCanceled(); monitor.checkCanceled();
Address typeinfoAddress = extraUtils.getPointer(typeinfoRef); Address typeinfoAddress = extraUtils.getPointer(typeinfoRef);
if (typeinfoAddress == null) { if (typeinfoAddress == null) {
@ -532,7 +530,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
throw new Exception("typeinfo has global namespace " + typeinfoAddress); throw new Exception("typeinfo has global namespace " + typeinfoAddress);
} }
try { try {
Symbol vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL, Symbol vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
classNamespace, SourceType.ANALYSIS); classNamespace, SourceType.ANALYSIS);
@ -617,8 +614,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return false; return false;
} }
private Namespace createConstructionNamespace(Symbol vtableSymbol, Symbol vttSymbol) private Namespace createConstructionNamespace(Symbol vtableSymbol, Symbol vttSymbol)
throws Exception { throws Exception {
@ -722,7 +717,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Data dataContainingTypeinfoRef = prog.getListing().getDefinedDataContaining(addr); Data dataContainingTypeinfoRef = prog.getListing().getDefinedDataContaining(addr);
Instruction instructionContainingAddr = Instruction instructionContainingAddr =
prog.getListing().getInstructionContaining(addr); prog.getListing().getInstructionContaining(addr);
@ -863,7 +857,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
api.setPlateComment(vtableAddress, "construction vtable " + n + api.setPlateComment(vtableAddress, "construction vtable " + n +
" for class " + " for class " +
vttSymbolBeforeConstructionVtable.getParentNamespace().getName( vttSymbolBeforeConstructionVtable.getParentNamespace()
.getName(
true)); true));
} }
@ -1190,7 +1185,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return false; return false;
} }
return true; 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 // 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 // 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; return numLongs;
} }
@ -1507,7 +1501,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Structure vmiClassTypeinfoStructure = Structure vmiClassTypeinfoStructure =
getOrCreateVmiTypeinfoStructure(typeinfoAddress, baseClassTypeInfoStructure); getOrCreateVmiTypeinfoStructure(typeinfoAddress, baseClassTypeInfoStructure);
if (vmiClassTypeinfoStructure != null) { if (vmiClassTypeinfoStructure != null) {
newStructure = applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress); newStructure =
applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress);
} }
} }
@ -1840,7 +1835,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return specialTypeinfoRefs; return specialTypeinfoRefs;
} }
/** /**
* Method to call the various methods to determine whether the functions that make references to * 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 * 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 pointer = dataTypeManager.getPointer(null);
DataType charPointer = dataTypeManager.getPointer(characterDT); DataType charPointer = dataTypeManager.getPointer(characterDT);
vmiClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null); vmiClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null);
vmiClassTypeInfoStructure.add(charPointer, "typeinfoName", null); vmiClassTypeInfoStructure.add(charPointer, "typeinfoName", null);
vmiClassTypeInfoStructure.add(unsignedIntDT, "flags", null); vmiClassTypeInfoStructure.add(unsignedIntDT, "flags", null);
@ -2011,7 +2004,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private List<RecoveredClass> addGccClassParentsFromVmiStruct(RecoveredClass recoveredClass, private List<RecoveredClass> addGccClassParentsFromVmiStruct(RecoveredClass recoveredClass,
Address typeinfoAddress) throws Exception { Address typeinfoAddress) throws Exception {
Structure vmiTypeinfoStructure = getTypeinfoStructure(typeinfoAddress); Structure vmiTypeinfoStructure = getTypeinfoStructure(typeinfoAddress);
if (vmiTypeinfoStructure == null || if (vmiTypeinfoStructure == null ||
!vmiTypeinfoStructure.getName().contains(VMI_CLASS_TYPE_INFO_STRUCTURE)) { !vmiTypeinfoStructure.getName().contains(VMI_CLASS_TYPE_INFO_STRUCTURE)) {
@ -2150,8 +2142,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
parentClass.setIsPublicClass(isPublic); parentClass.setIsPublicClass(isPublic);
// from doc: // from doc:
//All but the lower 8 bits of __offset_flags are a signed offset. For a //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. //non-virtual base, this is the offset in the object of the base subobject.
@ -2168,7 +2158,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
continue; continue;
} }
if (DEBUG) { if (DEBUG) {
@ -2893,7 +2882,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return; return;
} }
if (!recoveredClass.hasVftable()) { if (!recoveredClass.hasVftable()) {
createSimpleClassStructure(recoveredClass, null); createSimpleClassStructure(recoveredClass, null);
// return in this case because if there is no vftable for a class the script cannot // 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."); " : structure should exist but doesn't.");
} }
if (structUtils.canAdd(classStructureDataType, parentOffset, if (structUtils.canAdd(classStructureDataType, parentOffset,
baseClassStructure.getLength(), monitor)) { baseClassStructure.getLength(), monitor)) {
classStructureDataType = classStructureDataType =
@ -3049,7 +3036,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
} }
if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) { if (classStructureDataType.getNumComponents() == classStructureDataType
.getNumDefinedComponents()) {
classStructureDataType.setPackingEnabled(true); classStructureDataType.setPackingEnabled(true);
} }

View file

@ -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_META_PTR_LABEL = "vftable_meta_ptr";
private static final String VFTABLE_LABEL = "vftable"; private static final String VFTABLE_LABEL = "vftable";
private static final String CLASS_VTABLE_STRUCT_NAME = "_vbtable"; private static final String CLASS_VTABLE_STRUCT_NAME = "_vbtable";
private static final String CLASS_VTABLE_PTR_FIELD_EXT = "vftablePtr"; private static final String CLASS_VTABLE_PTR_FIELD_EXT = "vftablePtr";
private static final int CHD_MULTINH = 0x00000001; //Multiple inheritance private static final int CHD_MULTINH = 0x00000001; //Multiple inheritance
private static final int CHD_VIRTINH = 0x00000002; //Virtual inheritance private static final int CHD_VIRTINH = 0x00000002; //Virtual inheritance
private static final int CHD_AMBIGUOUS = 0x00000004; //Multiple inheritance with repeated base classes private static final int CHD_AMBIGUOUS = 0x00000004; //Multiple inheritance with repeated base classes
@ -91,7 +89,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return true; return true;
} }
@Override @Override
public boolean isValidProgramType() { public boolean isValidProgramType() {
if (!isVisualStudioOrClangPe()) { if (!isVisualStudioOrClangPe()) {
@ -100,7 +97,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return true; return true;
} }
@Override @Override
public void fixUpProgram() { public void fixUpProgram() {
@ -184,10 +180,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
determineParentClassInfoFromBaseClassArray(recoveredClasses); determineParentClassInfoFromBaseClassArray(recoveredClasses);
assignParentClassToVftables(recoveredClasses); assignParentClassToVftables(recoveredClasses);
// using all the information found above, create the class structures, add the constructor, // 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 // destructor, vfunctions to class which finds the appropriate class structure and assigns
// to "this" param // to "this" param
@ -219,14 +213,12 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
} }
private boolean isVisualStudioOrClangPe() { private boolean isVisualStudioOrClangPe() {
return program.getExecutableFormat().equals(PeLoader.PE_NAME) && return program.getExecutableFormat().equals(PeLoader.PE_NAME) &&
(program.getCompiler().equals(CompilerEnum.VisualStudio.toString()) || (program.getCompiler().equals(CompilerEnum.VisualStudio.toString()) ||
program.getCompiler().equals(CompilerEnum.Clang.toString())); program.getCompiler().equals(CompilerEnum.Clang.toString()));
} }
private boolean hasTypeInfoVftable() throws CancelledException { private boolean hasTypeInfoVftable() throws CancelledException {
List<Symbol> vftableSymbols = getListOfVftableSymbols(); List<Symbol> vftableSymbols = getListOfVftableSymbols();
@ -474,7 +466,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4)); Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4));
Data baseClassDescriptor = extraUtils.getDataAt(baseClassDescriptorAddress); Data baseClassDescriptor = extraUtils.getDataAt(baseClassDescriptorAddress);
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals( if (baseClassDescriptor == null || !baseClassDescriptor.getDataType()
.getName()
.equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
int num1 = extraUtils.getInt(baseClassDescriptorAddress.add(8)); int num1 = extraUtils.getInt(baseClassDescriptorAddress.add(8));
@ -563,7 +557,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
Data classHierarchyStructure = extraUtils.getDataAt(classHierarchyDescriptorAddress); Data classHierarchyStructure = extraUtils.getDataAt(classHierarchyDescriptorAddress);
if (classHierarchyStructure != null && if (classHierarchyStructure != null &&
classHierarchyStructure.getDataType().getName().equals( classHierarchyStructure.getDataType()
.getName()
.equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
return classHierarchyDescriptorAddress; return classHierarchyDescriptorAddress;
@ -803,7 +799,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
private Symbol getGivenSymbol(Address address, String name, Namespace namespace) private Symbol getGivenSymbol(Address address, String name, Namespace namespace)
throws CancelledException { throws CancelledException {
Symbol[] symbols = symbolTable.getSymbols(address); SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol sym : symbols) { for (Symbol sym : symbols) {
monitor.checkCanceled(); monitor.checkCanceled();
if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) { if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) {
@ -884,10 +880,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
findFunctionsUsingAtexit(); findFunctionsUsingAtexit();
} }
/** /**
* Method to recover the class information for each vftable symbol on the list * Method to recover the class information for each vftable symbol on the list
* * For each virtual function table: * * For each virtual function table:
@ -923,7 +915,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) { if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) {
classNamespace = promoteToClassNamespace(classNamespace); classNamespace = promoteToClassNamespace(classNamespace);
if(classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) { if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) {
Msg.debug(this, Msg.debug(this,
classHierarchyDescriptorAddress.toString() + " Could not promote " + classHierarchyDescriptorAddress.toString() + " Could not promote " +
classNamespace.getName(true) + " to a class namespace."); classNamespace.getName(true) + " to a class namespace.");
@ -963,11 +955,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
List<RecoveredClass> classesWithVftablesInNamespace = List<RecoveredClass> classesWithVftablesInNamespace =
recoverClassesFromVftables(vftableSymbolsInNamespace, false, false); recoverClassesFromVftables(vftableSymbolsInNamespace, false, false);
if (classesWithVftablesInNamespace.size() == 0) { 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; continue;
} }
if (classesWithVftablesInNamespace.size() > 1) { if (classesWithVftablesInNamespace.size() > 1) {
Msg.debug(this,"Unexpected multiple classes recovered for namespace " + Msg.debug(this, "Unexpected multiple classes recovered for namespace " +
classNamespace.getName()); classNamespace.getName());
continue; 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 * 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 * 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 * 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. * and non-virtual classes then the children and their children until all classes are processed.
@ -2502,7 +2485,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
} }
if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) { if (classStructureDataType.getNumComponents() == classStructureDataType
.getNumDefinedComponents()) {
classStructureDataType.setPackingEnabled(true); classStructureDataType.setPackingEnabled(true);
} }
@ -2590,7 +2574,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return classStructureDataType; return classStructureDataType;
} }
/** /**
* Method to apply the given class's vbtable structure * 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 * @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"); recoveredClass.getClassNamespace().getName(true) + "::vbtable");
} }
} }

View file

@ -169,7 +169,6 @@ public class RecoveredClassUtils {
decompilerUtils = new DecompilerScriptUtils(program, tool, monitor); decompilerUtils = new DecompilerScriptUtils(program, tool, monitor);
structUtils = new EditStructureUtils(); structUtils = new EditStructureUtils();
dataTypeManager = program.getDataTypeManager(); dataTypeManager = program.getDataTypeManager();
symbolTable = program.getSymbolTable(); symbolTable = program.getSymbolTable();
@ -522,8 +521,6 @@ public class RecoveredClassUtils {
return allInlinedDestructors; return allInlinedDestructors;
} }
/** /**
* Method to determine if referenced vftables are from the same class * Method to determine if referenced vftables are from the same class
* @param vftableReferences list of vftable references * @param vftableReferences list of vftable references
@ -1288,8 +1285,6 @@ public class RecoveredClassUtils {
} }
/** /**
* Method to determine if the given possible ancestor is an ancestor of any of the listed classes * Method to determine if the given possible ancestor is an ancestor of any of the listed classes
* @param recoveredClasses List of classes * @param recoveredClasses List of classes
@ -2658,7 +2653,6 @@ public class RecoveredClassUtils {
return false; return false;
} }
/** /**
* Method to create a new recovered class object and add it to the namespaceToClassMap * Method to create a new recovered class object and add it to the namespaceToClassMap
* @param namespace the namespace to put the new class in * @param namespace the namespace to put the new class in
@ -2766,7 +2760,6 @@ public class RecoveredClassUtils {
Map<Address, Function> vftableReferenceToFunctionMapping = Map<Address, Function> vftableReferenceToFunctionMapping =
createVftableReferenceToFunctionMapping(referencesToVftable); createVftableReferenceToFunctionMapping(referencesToVftable);
//vftableReferenceToFunctionMapping //vftableReferenceToFunctionMapping
List<Function> possibleConstructorDestructorsForThisClass = List<Function> possibleConstructorDestructorsForThisClass =
findPossibleConstructorDestructors(vftableReferenceToFunctionMapping); findPossibleConstructorDestructors(vftableReferenceToFunctionMapping);
@ -2910,8 +2903,6 @@ public class RecoveredClassUtils {
return cdFunctions; return cdFunctions;
} }
/** /**
* Method to get functions from vftable * Method to get functions from vftable
* @param vftableAddress the address of the vftable * @param vftableAddress the address of the vftable
@ -3890,8 +3881,8 @@ public class RecoveredClassUtils {
String simpleName = extraUtils.removeTemplate(name); String simpleName = extraUtils.removeTemplate(name);
Symbol[] symbols = symbolTable.getSymbols(address); SymbolIterator it = symbolTable.getSymbolsAsIterator(address);
for (Symbol symbol : symbols) { for (Symbol symbol : it) {
monitor.checkCanceled(); monitor.checkCanceled();
String simpleSymbolName = extraUtils.removeTemplate(symbol.getName()); String simpleSymbolName = extraUtils.removeTemplate(symbol.getName());
@ -4935,7 +4926,8 @@ public class RecoveredClassUtils {
Msg.debug(this, Msg.debug(this,
recoveredClass.getName() + " function " + recoveredClass.getName() + " function " +
functionContainingInline.getEntryPoint().toString() + " first ref: " + functionContainingInline.getEntryPoint().toString() + " first ref: " +
classVftableRef.toString() + " other way ref: " + otherWayRef.toString()); classVftableRef.toString() + " other way ref: " +
otherWayRef.toString());
} }
} }
@ -5056,7 +5048,8 @@ public class RecoveredClassUtils {
Function firstCalledFunction = Function firstCalledFunction =
extraUtils.getCalledFunctionByCallOrder(deletingDestructor, 1); extraUtils.getCalledFunctionByCallOrder(deletingDestructor, 1);
if (firstCalledFunction == null || if (firstCalledFunction == null ||
!recoveredClass.getConstructorOrDestructorFunctions().contains( !recoveredClass.getConstructorOrDestructorFunctions()
.contains(
firstCalledFunction)) { firstCalledFunction)) {
return null; return null;
} }
@ -5201,10 +5194,13 @@ public class RecoveredClassUtils {
return; return;
} }
if (parentDestructorClasses.size() == 1) { if (parentDestructorClasses.size() == 1) {
if (!parentDestructorClasses.get(0).getDestructorList().contains( if (!parentDestructorClasses.get(0)
.getDestructorList()
.contains(
parentDestructor)) { parentDestructor)) {
addDestructorToClass(parentDestructorClasses.get(0), parentDestructor); addDestructorToClass(parentDestructorClasses.get(0), parentDestructor);
parentDestructorClasses.get(0).removeIndeterminateConstructorOrDestructor( parentDestructorClasses.get(0)
.removeIndeterminateConstructorOrDestructor(
parentDestructor); parentDestructor);
} }
} }
@ -5390,7 +5386,9 @@ public class RecoveredClassUtils {
*/ */
public boolean isClassOffsetToVftableMapComplete(RecoveredClass recoveredClass) { public boolean isClassOffsetToVftableMapComplete(RecoveredClass recoveredClass) {
if (recoveredClass.getClassOffsetToVftableMap().values().containsAll( if (recoveredClass.getClassOffsetToVftableMap()
.values()
.containsAll(
recoveredClass.getVftableAddresses())) { recoveredClass.getVftableAddresses())) {
return true; return true;
} }
@ -5434,7 +5432,8 @@ public class RecoveredClassUtils {
Function secondCalledFunction = Function secondCalledFunction =
extraUtils.getCalledFunctionByCallOrder(vFunction, 2); extraUtils.getCalledFunctionByCallOrder(vFunction, 2);
if (firstCalledFunction != null && secondCalledFunction != null && if (firstCalledFunction != null && secondCalledFunction != null &&
!recoveredClass.getConstructorOrDestructorFunctions().contains( !recoveredClass.getConstructorOrDestructorFunctions()
.contains(
firstCalledFunction) && firstCalledFunction) &&
secondCalledFunction.equals(operator_delete) && secondCalledFunction.equals(operator_delete) &&
!getAllConstructorsAndDestructors().contains(vFunction)) { !getAllConstructorsAndDestructors().contains(vFunction)) {
@ -6903,7 +6902,6 @@ public class RecoveredClassUtils {
} }
} }
return changedItems; return changedItems;
} }
@ -7424,7 +7422,7 @@ public class RecoveredClassUtils {
for (DataTypeComponent component : components) { for (DataTypeComponent component : components) {
monitor.checkCanceled(); monitor.checkCanceled();
DataType componentDataType = component.getDataType(); DataType componentDataType = component.getDataType();
if(componentDataType.getName().equals(nameOfParent)) { if (componentDataType.getName().equals(nameOfParent)) {
return (Structure) componentDataType; return (Structure) componentDataType;
} }
} }
@ -7520,12 +7518,14 @@ public class RecoveredClassUtils {
DataTypeComponent[] vfunctionComponents = vfunctionStructure.getComponents(); DataTypeComponent[] vfunctionComponents = vfunctionStructure.getComponents();
for (DataTypeComponent vfunctionComponent : vfunctionComponents) { for (DataTypeComponent vfunctionComponent : vfunctionComponents) {
monitor.checkCanceled(); monitor.checkCanceled();
Object changedItem = updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress); Object changedItem =
if(changedItem != null && !changedItems.contains(changedItem)) { updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress);
if (changedItem != null && !changedItems.contains(changedItem)) {
changedItems.add(changedItem); changedItems.add(changedItem);
FunctionDefinition newFunctionDefinition = getComponentFunctionDefinition(vfunctionComponent); FunctionDefinition newFunctionDefinition =
if(newFunctionDefinition == null) { getComponentFunctionDefinition(vfunctionComponent);
if (newFunctionDefinition == null) {
continue; continue;
} }
@ -7604,7 +7604,6 @@ public class RecoveredClassUtils {
return null; return null;
} }
boolean changed = updateFunctionSignature(vfunction, newFunctionDefinition); boolean changed = updateFunctionSignature(vfunction, newFunctionDefinition);
if (changed) { if (changed) {
return vfunction; return vfunction;

View file

@ -671,13 +671,11 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer {
} }
private String getLabelFromUndefinedData(Program program, Address address) { private String getLabelFromUndefinedData(Program program, Address address) {
Symbol[] symbols = program.getSymbolTable().getSymbols(address); Symbol primary = program.getSymbolTable().getPrimarySymbol(address);
if (symbols.length == 0) { if (primary == null) {
return null; return null;
} }
for (Symbol symbol : symbols) { String symbolName = primary.getName();
if (symbol.isPrimary()) {
String symbolName = symbol.getName();
if (symbolName.contains("_OBJC_CLASS_$_")) { if (symbolName.contains("_OBJC_CLASS_$_")) {
symbolName = symbolName.substring("_OBJC_CLASS_$_".length()); symbolName = symbolName.substring("_OBJC_CLASS_$_".length());
} }
@ -686,9 +684,6 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer {
} }
return symbolName; return symbolName;
} }
}
return null;
}
private String getClassName(Program program, Address toAddress) { private String getClassName(Program program, Address toAddress) {
try { try {

View file

@ -764,14 +764,10 @@ public class FGProvider extends VisualGraphComponentProvider<FGVertex, FGEdge, F
SymbolTable symbolTable = currentProgram.getSymbolTable(); SymbolTable symbolTable = currentProgram.getSymbolTable();
AddressSetView vertexAddresses = destinationVertex.getAddresses(); AddressSetView vertexAddresses = destinationVertex.getAddresses();
Address minAddress = vertexAddresses.getMinAddress(); Address minAddress = vertexAddresses.getMinAddress();
Symbol[] symbols = symbolTable.getSymbols(minAddress);
if (symbols.length > 1) { Symbol primary = symbolTable.getPrimarySymbol(minAddress);
return; // real user symbols if (!primary.isDynamic()) {
} return;
else if (symbols.length == 1) {
if (!symbols[0].isDynamic()) {
return; // real user symbol
}
} }
ReferenceManager referenceManager = currentProgram.getReferenceManager(); ReferenceManager referenceManager = currentProgram.getReferenceManager();

View file

@ -28,6 +28,7 @@ import ghidra.program.model.lang.Language;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException; import ghidra.util.exception.VersionException;
@ -57,7 +58,7 @@ public class FidStatistics extends GhidraScript {
private String sym1; private String sym1;
private String sym2; private String sym2;
public SymbolPair(String a,String b) { public SymbolPair(String a, String b) {
sym1 = a; sym1 = a;
sym2 = b; sym2 = b;
} }
@ -83,7 +84,7 @@ public class FidStatistics extends GhidraScript {
private float childScore; private float childScore;
private float parentScore; 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.progName = result.function.getProgram().getDomainFile().getPathname();
this.fullHash = result.hashQuad.getFullHash(); this.fullHash = result.hashQuad.getFullHash();
this.funcName = result.function.getName(); this.funcName = result.function.getName();
@ -136,8 +137,8 @@ public class FidStatistics extends GhidraScript {
falsePositive = 0; falsePositive = 0;
} }
public static void indent(StringBuilder buf,String last) { public static void indent(StringBuilder buf, String last) {
for(int i=last.length();i<10;++i) { for (int i = last.length(); i < 10; ++i) {
buf.append(' '); buf.append(' ');
} }
} }
@ -145,22 +146,23 @@ public class FidStatistics extends GhidraScript {
public void print(StringBuilder buf) { public void print(StringBuilder buf) {
String str = Integer.toString(totalFunction); String str = Integer.toString(totalFunction);
buf.append(str); buf.append(str);
indent(buf,str); indent(buf, str);
str = Integer.toString(noMatch); str = Integer.toString(noMatch);
buf.append(str); buf.append(str);
indent(buf,str); indent(buf, str);
str = Integer.toString(matchUniquely + matchMultiply); str = Integer.toString(matchUniquely + matchMultiply);
buf.append(str); buf.append(str);
indent(buf, str); indent(buf, str);
str = Integer.toString(hitCount); str = Integer.toString(hitCount);
buf.append(str); buf.append(str);
indent(buf, str); indent(buf, str);
str = '(' + Integer.toString(matchUniquely) + ',' + Integer.toString(matchMultiply) + ')'; str =
'(' + Integer.toString(matchUniquely) + ',' + Integer.toString(matchMultiply) + ')';
buf.append(str); buf.append(str);
indent(buf,str); indent(buf, str);
str = Integer.toString(nameMatched); str = Integer.toString(nameMatched);
buf.append(str); buf.append(str);
indent(buf,str); indent(buf, str);
str = Integer.toString(falsePositive); str = Integer.toString(falsePositive);
buf.append(str); buf.append(str);
} }
@ -170,10 +172,10 @@ public class FidStatistics extends GhidraScript {
} }
} }
private void addEquivSymbols(String a,String b) { private void addEquivSymbols(String a, String b) {
SymbolPair pair = new SymbolPair(a,b); SymbolPair pair = new SymbolPair(a, b);
equivSymbols.add(pair); equivSymbols.add(pair);
pair = new SymbolPair(b,a); pair = new SymbolPair(b, a);
equivSymbols.add(pair); equivSymbols.add(pair);
} }
@ -182,108 +184,120 @@ public class FidStatistics extends GhidraScript {
service = new FidService(); service = new FidService();
matchAnalysis = new MatchNameAnalysis(); matchAnalysis = new MatchNameAnalysis();
equivSymbols = new TreeSet<SymbolPair>(); equivSymbols = new TreeSet<SymbolPair>();
addEquivSymbols("entry","_WinMainCRTStartup"); addEquivSymbols("entry", "_WinMainCRTStartup");
addEquivSymbols("__alloca_probe","__chkstk"); addEquivSymbols("__alloca_probe", "__chkstk");
addEquivSymbols("_strncpy_s_downlevel","_strncpy_s"); addEquivSymbols("_strncpy_s_downlevel", "_strncpy_s");
addEquivSymbols("_strcpy_s_downlevel","_strcpy_s"); addEquivSymbols("_strcpy_s_downlevel", "_strcpy_s");
addEquivSymbols("strcat_s_downlevel", "strcat_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("_memmove_s_downlevel", "_memmove_s");
addEquivSymbols("__ftol2_downlevel","__ftol2"); addEquivSymbols("__ftol2_downlevel", "__ftol2");
addEquivSymbols("_wmakepath_s_downlevel", "_wmakepath_s"); addEquivSymbols("_wmakepath_s_downlevel", "_wmakepath_s");
addEquivSymbols("entry", "_wWinMainCRTStartup"); addEquivSymbols("entry", "_wWinMainCRTStartup");
addEquivSymbols("entry", "_wmainCRTStartup"); addEquivSymbols("entry", "_wmainCRTStartup");
addEquivSymbols("entry", "_mainCRTStartup"); addEquivSymbols("entry", "_mainCRTStartup");
addEquivSymbols("entry","__DllMainCRTStartup@12"); addEquivSymbols("entry", "__DllMainCRTStartup@12");
addEquivSymbols("_errno", "__doserrno"); addEquivSymbols("_errno", "__doserrno");
addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyW@12"); addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyW@12");
addEquivSymbols("_StringCchCopyNW@16", "?StringCchCopyNW@@YGJPAGIPBGI@Z"); 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("_StringCchLengthA@12", "?StringCchLengthA@@YGJPBDIPAI@Z");
addEquivSymbols("_RtlStringCchCopyW@12","=_StringCchCopyW@12"); addEquivSymbols("_RtlStringCchCopyW@12", "=_StringCchCopyW@12");
addEquivSymbols("?RtlStringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyA@12"); addEquivSymbols("?RtlStringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyA@12");
addEquivSymbols("_RtlStringCchCopyW@12","_StringCchCopyW@12"); addEquivSymbols("_RtlStringCchCopyW@12", "_StringCchCopyW@12");
addEquivSymbols("_RtlStringCchCopyNW@16", "?StringCchCopyNW@@YGJPAGIPBGI@Z"); addEquivSymbols("_RtlStringCchCopyNW@16", "?StringCchCopyNW@@YGJPAGIPBGI@Z");
addEquivSymbols("?RtlStringCchLengthW@@YGJPBGIPAI@Z", "?StringCchLengthW@@YGJPB_WIPAI@Z"); addEquivSymbols("?RtlStringCchLengthW@@YGJPBGIPAI@Z", "?StringCchLengthW@@YGJPB_WIPAI@Z");
addEquivSymbols("_RtlStringCchLengthW@12", "?StringCchLengthW@@YGJPB_WIPAI@Z"); addEquivSymbols("_RtlStringCchLengthW@12", "?StringCchLengthW@@YGJPB_WIPAI@Z");
addEquivSymbols("?RtlStringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12"); addEquivSymbols("?RtlStringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12");
addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12"); addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatA@12");
addEquivSymbols("_StringCchCatW@12", "_StringCchCatA@12"); addEquivSymbols("_StringCchCatW@12", "_StringCchCatA@12");
addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z","_StringCchCopyA@12"); addEquivSymbols("?StringCchCopyW@@YGJPAGIPBG@Z", "_StringCchCopyA@12");
addEquivSymbols("?ULongLongToUInt@@YGJ_KPAI@Z","_ULongLongToULong@12"); addEquivSymbols("?ULongLongToUInt@@YGJ_KPAI@Z", "_ULongLongToULong@12");
addEquivSymbols("_ULongLongToUInt@12","_ULongLongToULong@12"); addEquivSymbols("_ULongLongToUInt@12", "_ULongLongToULong@12");
addEquivSymbols("_ULongLongToUInt@12","_ULongLongToULong@12"); addEquivSymbols("_ULongLongToUInt@12", "_ULongLongToULong@12");
addEquivSymbols("?ULongLongToULong@@YGJ_KPAK@Z","_ULongLongToULong@12"); addEquivSymbols("?ULongLongToULong@@YGJ_KPAK@Z", "_ULongLongToULong@12");
addEquivSymbols("_RtlULongLongToULong@12", "_ULongLongToULong@12"); addEquivSymbols("_RtlULongLongToULong@12", "_ULongLongToULong@12");
addEquivSymbols("_RtlULongLongToUInt@12", "_ULongLongToULong@12"); addEquivSymbols("_RtlULongLongToUInt@12", "_ULongLongToULong@12");
addEquivSymbols("?RtlULongLongToULong@@YGJ_KPAK@Z", "_ULongLongToULong@12"); addEquivSymbols("?RtlULongLongToULong@@YGJ_KPAK@Z", "_ULongLongToULong@12");
addEquivSymbols("?ULongPtrAdd@@YGJKKPAK@Z", "_ULongAdd@12"); addEquivSymbols("?ULongPtrAdd@@YGJKKPAK@Z", "_ULongAdd@12");
addEquivSymbols("_ULongAdd@12","?ULongAdd@@YGJKKPAK@Z"); addEquivSymbols("_ULongAdd@12", "?ULongAdd@@YGJKKPAK@Z");
addEquivSymbols("_ULongAdd@12","?SizeTAdd@@YGJIIPAI@Z"); addEquivSymbols("_ULongAdd@12", "?SizeTAdd@@YGJIIPAI@Z");
addEquivSymbols("_ULongAdd@12","?UIntAdd@@YGJIIPAI@Z"); addEquivSymbols("_ULongAdd@12", "?UIntAdd@@YGJIIPAI@Z");
addEquivSymbols("_ULongAdd@12","?SIZETAdd@@YGJKKPAK@Z"); addEquivSymbols("_ULongAdd@12", "?SIZETAdd@@YGJKKPAK@Z");
addEquivSymbols("_RtlULongAdd@12","?RtlULongAdd@@YGJKKPAK@Z"); addEquivSymbols("_RtlULongAdd@12", "?RtlULongAdd@@YGJKKPAK@Z");
addEquivSymbols("_RtlSIZETAdd@12","?RtlULongAdd@@YGJKKPAK@Z"); addEquivSymbols("_RtlSIZETAdd@12", "?RtlULongAdd@@YGJKKPAK@Z");
addEquivSymbols("_UIntAdd@12","_ULongAdd@12"); addEquivSymbols("_UIntAdd@12", "_ULongAdd@12");
addEquivSymbols("LoadStringA","LoadStringW"); addEquivSymbols("LoadStringA", "LoadStringW");
addEquivSymbols("_StringCchCopyW@12", "_StringCchCopyA@12"); addEquivSymbols("_StringCchCopyW@12", "_StringCchCopyA@12");
addEquivSymbols("?StringCchCopyA@@YGJPADIPBD@Z","_StringCchCopyA@12"); addEquivSymbols("?StringCchCopyA@@YGJPADIPBD@Z", "_StringCchCopyA@12");
addEquivSymbols("StringCchVPrintfA","StringCchVPrintfW"); addEquivSymbols("StringCchVPrintfA", "StringCchVPrintfW");
addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatW@12"); addEquivSymbols("?StringCchCatW@@YGJPAGIPBG@Z", "_StringCchCatW@12");
addEquivSymbols("__safecrt_fassign", "__fassign_l"); addEquivSymbols("__safecrt_fassign", "__fassign_l");
addEquivSymbols("?StringLengthWorkerW@@YGJPBGIPAI@Z","_StringLengthWorkerW@12"); addEquivSymbols("?StringLengthWorkerW@@YGJPBGIPAI@Z", "_StringLengthWorkerW@12");
addEquivSymbols("?StringCatWorkerW@@YGJPAGIPBG@Z", "_StringCatWorkerW@12"); addEquivSymbols("?StringCatWorkerW@@YGJPAGIPBG@Z", "_StringCatWorkerW@12");
addEquivSymbols("_decode_aligned_offset_block@12","_decode_verbatim_block@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", 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"); "??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", addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@PBGHPAUIAtlStringMgr@1@@Z",
"??0?$CSimpleStringT@_W$0A@@ATL@@QAE@PB_WHPAUIAtlStringMgr@1@@Z"); "??0?$CSimpleStringT@_W$0A@@ATL@@QAE@PB_WHPAUIAtlStringMgr@1@@Z");
addEquivSymbols("_NFMdeco_destroy@8","_NFMcomp_destroy@8"); addEquivSymbols("_NFMdeco_destroy@8", "_NFMcomp_destroy@8");
addEquivSymbols("_StringCchVPrintfW@16","?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); addEquivSymbols("_StringCchVPrintfW@16", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z");
addEquivSymbols("_StringCbVPrintfA@16","?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); addEquivSymbols("_StringCbVPrintfA@16", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z");
addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ");
addEquivSymbols("_StringCchPrintfW","?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("_StringCchPrintfW", "?StringCchPrintfW@@YAJPAGIPBGZZ");
addEquivSymbols("_StringCbPrintfA","?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("_StringCbPrintfA", "?StringCchPrintfW@@YAJPAGIPBGZZ");
addEquivSymbols("?AtlA2WHelper@@YGPAGPAGPBDH@Z","?AfxA2WHelper@@YGPA_WPA_WPBDH@Z"); addEquivSymbols("?AtlA2WHelper@@YGPAGPAGPBDH@Z", "?AfxA2WHelper@@YGPA_WPA_WPBDH@Z");
addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z", addEquivSymbols("??0?$CSimpleStringT@G$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z",
"??0?$CSimpleStringT@D$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z"); "??0?$CSimpleStringT@D$0A@@ATL@@QAE@PAUIAtlStringMgr@1@@Z");
addEquivSymbols("_RtlStringCchCopyA@12","?StringCchCopyA@@YGJPADIPBD@Z"); addEquivSymbols("_RtlStringCchCopyA@12", "?StringCchCopyA@@YGJPADIPBD@Z");
addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGHPAUIAtlStringMgr@1@@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"); "??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?$CSimpleStringT@G$0A@@ATL@@QAE@ABV01@@Z",
addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBGPAUIAtlStringMgr@1@@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"); "??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", 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"); "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@ABV01@@Z");
addEquivSymbols("__ltoa_s_downlevel","__ltow_s"); addEquivSymbols("__ltoa_s_downlevel", "__ltow_s");
addEquivSymbols("??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@V_STL70@@@std@@QAE@XZ", 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"); "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
addEquivSymbols("_StringCchPrintfA","?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("_StringCchPrintfA", "?StringCchPrintfW@@YAJPAGIPBGZZ");
addEquivSymbols("?StringCbPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ"); addEquivSymbols("?StringCbPrintfA@@YAJPADIPBDZZ", "?StringCchPrintfW@@YAJPAGIPBGZZ");
addEquivSymbols("?ULongMult@@YGJKKPAK@Z", "_ULongMult@12"); addEquivSymbols("?ULongMult@@YGJKKPAK@Z", "_ULongMult@12");
addEquivSymbols("?_Getwctypes@@YAPB_WPB_W0PAFPBU_Ctypevec@@@Z", "__Getwctypes"); addEquivSymbols("?_Getwctypes@@YAPB_WPB_W0PAFPBU_Ctypevec@@@Z", "__Getwctypes");
addEquivSymbols("?_Getwctype@@YAF_WPBU_Ctypevec@@@Z", "__Getwctype"); addEquivSymbols("?_Getwctype@@YAF_WPBU_Ctypevec@@@Z", "__Getwctype");
addEquivSymbols("?_Getwctype@@YAF_WPEBU_Ctypevec@@@Z", "_Getwctype"); addEquivSymbols("?_Getwctype@@YAF_WPEBU_Ctypevec@@@Z", "_Getwctype");
addEquivSymbols("?AtlW2AHelper@@YGPADPADPBGH@Z", "?AfxW2AHelper@@YGPADPADPB_WH@Z"); 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", 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"); "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ID@Z");
addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ","?StringCbPrintfA@@YAJPADIPBDZZ"); addEquivSymbols("?StringCchPrintfA@@YAJPADIPBDZZ", "?StringCbPrintfA@@YAJPADIPBDZZ");
addEquivSymbols("??0?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@@QAE@PBDHPAUIAtlStringMgr@1@@Z", 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"); "??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("_wmemcpy_s",
addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z","_StringCbCopyA@12"); "?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z");
addEquivSymbols("??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@V_STL70@@@std@@QAE@IG@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"); "??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", 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"); "??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", addEquivSymbols("?CopyChars@?$CSimpleStringT@G$0A@@ATL@@SAXPAGIPBGH@Z",
"?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@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", 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"); "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_WPAUIAtlStringMgr@1@@Z");
addEquivSymbols("wcscpy_s_downlevel", "wcscpy_s"); addEquivSymbols("wcscpy_s_downlevel", "wcscpy_s");
addEquivSymbols("_StringCbCopyA@12", "_StringCchCopyA@12"); addEquivSymbols("_StringCbCopyA@12", "_StringCchCopyA@12");
addEquivSymbols("_wcscat_s_downlevel", "_wcscat_s"); 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", 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"); "??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("?_Towupper@@YA_W_WPBU_Ctypevec@@@Z", "__Towupper");
addEquivSymbols("?_Towlower@@YA_W_WPBU_Ctypevec@@@Z", "__Towlower"); addEquivSymbols("?_Towlower@@YA_W_WPBU_Ctypevec@@@Z", "__Towlower");
@ -291,55 +305,64 @@ public class FidStatistics extends GhidraScript {
addEquivSymbols("?_Towlower@@YA_W_WPEBU_Ctypevec@@@Z", "_Towlower"); addEquivSymbols("?_Towlower@@YA_W_WPEBU_Ctypevec@@@Z", "_Towlower");
addEquivSymbols("_wcsncpy_s_downlevel", "_wcsncpy_s"); addEquivSymbols("_wcsncpy_s_downlevel", "_wcsncpy_s");
addEquivSymbols("_strnlen_downlevel", "_strnlen"); addEquivSymbols("_strnlen_downlevel", "_strnlen");
addEquivSymbols("GetProxyDllInfo","_GetProxyDllInfo@8"); addEquivSymbols("GetProxyDllInfo", "_GetProxyDllInfo@8");
addEquivSymbols("DllGetClassObject","_DllGetClassObject@12"); addEquivSymbols("DllGetClassObject", "_DllGetClassObject@12");
addEquivSymbols("_PrxDllGetClassObject@12", "_DllGetClassObject@12"); addEquivSymbols("_PrxDllGetClassObject@12", "_DllGetClassObject@12");
addEquivSymbols("__itoa_s_downlevel", "__itow_s"); addEquivSymbols("__itoa_s_downlevel", "__itow_s");
addEquivSymbols("?StringCbVPrintfA@@YGJPADIPBD0@Z", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z"); addEquivSymbols("?StringCbVPrintfA@@YGJPADIPBD0@Z", "?StringCchVPrintfW@@YGJPAGIPBGPAD@Z");
addEquivSymbols("?UShortMult@@YGJGGPAG@Z", "?RtlUShortMult@@YGJGGPAG@Z"); addEquivSymbols("?UShortMult@@YGJGGPAG@Z", "?RtlUShortMult@@YGJGGPAG@Z");
addEquivSymbols("??1?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@XZ", addEquivSymbols("??1?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@XZ",
"??1?$CStringT@_WV?$StrTraitMFC@_WV?$ChTraitsOS@_W@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("?memcpy_s@Checked@ATL@@YAXPAXIPBXI@Z",
addEquivSymbols("?tcsncpy_s@Checked@ATL@@YAHPAGIPBGI@Z", "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z");
addEquivSymbols("?wmemcpy_s@Checked@ATL@@YAXPAGIPBGI@Z", "?memmove_s@Checked@ATL@@YAXPAXIPBXI@Z"); addEquivSymbols("?tcsncpy_s@Checked@ATL@@YAHPAGIPBGI@Z",
addEquivSymbols("??$AtlMultiply@I@ATL@@YAJPAIII@Z","??$AtlMultiply@K@ATL@@YAJPAKKK@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("__it_wcsncpy", "_wcsncpy");
addEquivSymbols("??1?$CFixedStringT@V?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@$0BA@@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"); "??1?$CFixedStringT@V?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@$0EA@@ATL@@UAE@XZ");
addEquivSymbols("?StringCbCatA@@YGJPADIPBD@Z", "_StringCchCatA@12"); addEquivSymbols("?StringCbCatA@@YGJPADIPBD@Z", "_StringCchCatA@12");
addEquivSymbols("??0?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@QAE@PBG@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"); "??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PB_W@Z");
addEquivSymbols("UShortAdd", "RtlUShortAdd"); addEquivSymbols("UShortAdd", "RtlUShortAdd");
addEquivSymbols("_StringCchPrintfA", "?StringCbPrintfA@@YAJPADIPBDZZ"); addEquivSymbols("_StringCchPrintfA", "?StringCbPrintfA@@YAJPADIPBDZZ");
addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z", "_StringCchCopyA@12"); addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z", "_StringCchCopyA@12");
// 64-bit // 64-bit
addEquivSymbols("??1?$CTempBuffer@G$0BAA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ","??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); addEquivSymbols("??1?$CTempBuffer@G$0BAA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ",
addEquivSymbols("?IsEqualGUID@@YAHAEBU_GUID@@0@Z","IsEqualGUID"); "??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ");
addEquivSymbols("??1?$CAtlSafeAllocBufferManager@V_CCRTAllocator@_ATL_SAFE_ALLOCA_IMPL@ATL@@@_ATL_SAFE_ALLOCA_IMPL@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"); "??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("??_E_Locimp@locale@std@@MEAAPEAXI@Z",
addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z","StringCchCopyW"); "??_G_Locimp@locale@std@@MEAAPEAXI@Z");
addEquivSymbols("StringCchPrintfA","?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z", "StringCchCopyW");
addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z","StringCchCatA"); addEquivSymbols("StringCchPrintfA", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ");
addEquivSymbols("?StringCbCatA@@YAJPEAD_KPEBD@Z","StringCchCatA"); addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA");
addEquivSymbols("entry","mainCRTStartup"); addEquivSymbols("?StringCbCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA");
addEquivSymbols("entry","wmainCRTStartup"); addEquivSymbols("entry", "mainCRTStartup");
addEquivSymbols("entry","WinMainCRTStartup"); addEquivSymbols("entry", "wmainCRTStartup");
addEquivSymbols("WPP_SF_ii","WPP_SF_qq"); addEquivSymbols("entry", "WinMainCRTStartup");
addEquivSymbols("WPP_SF_DDDDD","WPP_SF_ddddd"); addEquivSymbols("WPP_SF_ii", "WPP_SF_qq");
addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z","FDIDestroy"); addEquivSymbols("WPP_SF_DDDDD", "WPP_SF_ddddd");
addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ","??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ"); addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z", "FDIDestroy");
addEquivSymbols("WPP_SF_xx","WPP_SF_qq"); addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ",
addEquivSymbols("WPP_SF_iii","WPP_SF_qqq"); "??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ");
addEquivSymbols("RtlStringCchCopyW","StringCchCopyW"); addEquivSymbols("WPP_SF_xx", "WPP_SF_qq");
addEquivSymbols("_strcmpi","_stricmp"); addEquivSymbols("WPP_SF_iii", "WPP_SF_qqq");
addEquivSymbols("WPP_SF_DDDDDDDD","WPP_SF_dddddddd"); addEquivSymbols("RtlStringCchCopyW", "StringCchCopyW");
addEquivSymbols("?StringCchPrintfA@@YAJPEAD_KPEBDZZ","?StringCbPrintfA@@YAJPEAD_KPEBDZZ"); addEquivSymbols("_strcmpi", "_stricmp");
addEquivSymbols("WPP_SF_h","WPP_SF_H"); addEquivSymbols("WPP_SF_DDDDDDDD", "WPP_SF_dddddddd");
addEquivSymbols("WPP_SF_qqDD","WPP_SF_qqdd"); addEquivSymbols("?StringCchPrintfA@@YAJPEAD_KPEBDZZ", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ");
addEquivSymbols("WPP_SF_DqD","WPP_SF_dqd"); addEquivSymbols("WPP_SF_h", "WPP_SF_H");
addEquivSymbols("WPP_SF_Dq","WPP_SF_dq"); 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_assign_from");
addEquivSymbols("std::vector<>::_Assign_rv", "std::vector<>::_Move_from"); addEquivSymbols("std::vector<>::_Assign_rv", "std::vector<>::_Move_from");
} }
@ -360,23 +383,22 @@ public class FidStatistics extends GhidraScript {
} }
} }
private boolean checkNames(String a,String b) { private boolean checkNames(String a, String b) {
if (a.equals(b)) { if (a.equals(b)) {
return true; return true;
} }
return equivSymbols.contains(new SymbolPair(a,b)); return equivSymbols.contains(new SymbolPair(a, b));
} }
private String chooseFunctionName(FidSearchResult result) { private String chooseFunctionName(FidSearchResult result) {
Program program = result.function.getProgram(); Program program = result.function.getProgram();
Symbol[] symbols = program.getSymbolTable().getSymbols(result.function.getEntryPoint()); SymbolIterator it =
if (symbols.length > 1) { program.getSymbolTable().getSymbolsAsIterator(result.function.getEntryPoint());
for (Symbol symbol : symbols) { for (Symbol symbol : it) {
if (matchAnalysis.containsRawName(symbol.getName())) { if (matchAnalysis.containsRawName(symbol.getName())) {
return symbol.getName(); return symbol.getName();
} }
} }
}
return result.function.getName(); return result.function.getName();
} }
@ -384,7 +406,7 @@ public class FidStatistics extends GhidraScript {
throws CancelledException, IOException { throws CancelledException, IOException {
StatRecord record = statRecord; StatRecord record = statRecord;
record.totalFunction += 1; record.totalFunction += 1;
if (result.matches==null || result.matches.size() == 0) { if (result.matches == null || result.matches.size() == 0) {
record.noMatch += 1; record.noMatch += 1;
} }
else { else {
@ -407,17 +429,17 @@ public class FidStatistics extends GhidraScript {
NameVersions nameVersions = NameVersions.generate(funcName, program); NameVersions nameVersions = NameVersions.generate(funcName, program);
boolean exactNameMatch = false; boolean exactNameMatch = false;
Iterator<String> iter = matchAnalysis.getRawNameIterator(); Iterator<String> iter = matchAnalysis.getRawNameIterator();
while(iter.hasNext()) { while (iter.hasNext()) {
String raw = iter.next(); String raw = iter.next();
NameVersions matchNames = NameVersions.generate(raw, program); NameVersions matchNames = NameVersions.generate(raw, program);
if (matchNames.rawName == null) { if (matchNames.rawName == null) {
continue; continue;
} }
if (checkNames(nameVersions.rawName,matchNames.rawName)) { if (checkNames(nameVersions.rawName, matchNames.rawName)) {
exactNameMatch = true; exactNameMatch = true;
break; break;
} }
if (checkNames(nameVersions.similarName,matchNames.similarName)) { if (checkNames(nameVersions.similarName, matchNames.similarName)) {
exactNameMatch = true; exactNameMatch = true;
break; break;
} }
@ -441,7 +463,7 @@ public class FidStatistics extends GhidraScript {
if (matchNames.demangledBaseName == null) { if (matchNames.demangledBaseName == null) {
continue; continue;
} }
if (checkNames(nameVersions.demangledBaseName,matchNames.demangledBaseName)) { if (checkNames(nameVersions.demangledBaseName, matchNames.demangledBaseName)) {
exactNameMatch = true; exactNameMatch = true;
break; break;
} }
@ -463,7 +485,7 @@ public class FidStatistics extends GhidraScript {
record.hitCount += 1; record.hitCount += 1;
} }
if (exactNameMatch && ((score < scoreThreshold) || !matchHappened)) { if (exactNameMatch && ((score < scoreThreshold) || !matchHappened)) {
MatchRecord matchRecord = new MatchRecord(result,null,false); MatchRecord matchRecord = new MatchRecord(result, null, false);
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
matchRecord.print(buffer); matchRecord.print(buffer);
lowTruePositive.append(buffer.toString()); lowTruePositive.append(buffer.toString());
@ -471,7 +493,7 @@ public class FidStatistics extends GhidraScript {
} }
else if ((!exactNameMatch) && (score >= scoreThreshold) && matchHappened) { else if ((!exactNameMatch) && (score >= scoreThreshold) && matchHappened) {
record.falsePositive += 1; record.falsePositive += 1;
MatchRecord matchRecord = new MatchRecord(result,finalMatchName,true); MatchRecord matchRecord = new MatchRecord(result, finalMatchName, true);
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
matchRecord.print(buffer); matchRecord.print(buffer);
highFalsePositive.append(buffer.toString()); highFalsePositive.append(buffer.toString());
@ -481,12 +503,13 @@ public class FidStatistics extends GhidraScript {
} }
private void processProgram(Program program,FidQueryService queryService) throws MemoryAccessException, CancelledException, VersionException, IOException { private void processProgram(Program program, FidQueryService queryService)
FidProgramSeeker programSeeker = service.getProgramSeeker(program,queryService, 10.0f); throws MemoryAccessException, CancelledException, VersionException, IOException {
FidProgramSeeker programSeeker = service.getProgramSeeker(program, queryService, 10.0f);
monitor.setMessage("Processing " + program.getName()); monitor.setMessage("Processing " + program.getName());
monitor.initialize(program.getFunctionManager().getFunctionCount()); monitor.initialize(program.getFunctionManager().getFunctionCount());
FunctionIterator iter = program.getFunctionManager().getFunctionsNoStubs(true); FunctionIterator iter = program.getFunctionManager().getFunctionsNoStubs(true);
while(iter.hasNext()) { while (iter.hasNext()) {
Function func = iter.next(); Function func = iter.next();
monitor.incrementProgress(1); monitor.incrementProgress(1);
if (func.getName().startsWith("FUN_") || func.getName().startsWith("Ordinal_")) { if (func.getName().startsWith("FUN_") || func.getName().startsWith("Ordinal_")) {
@ -500,7 +523,8 @@ public class FidStatistics extends GhidraScript {
} }
} }
private LinkedList<DomainFile> buildDomainFileList() throws CancelledException, VersionException, IOException { private LinkedList<DomainFile> buildDomainFileList()
throws CancelledException, VersionException, IOException {
ArrayList<DomainFolder> folders = new ArrayList<DomainFolder>(); ArrayList<DomainFolder> folders = new ArrayList<DomainFolder>();
while (true) { while (true) {
monitor.checkCanceled(); monitor.checkCanceled();
@ -530,7 +554,7 @@ public class FidStatistics extends GhidraScript {
LinkedList<DomainFile> programList = buildDomainFileList(); LinkedList<DomainFile> programList = buildDomainFileList();
File lowFile = askFile("Select file to report true matches", "OK"); File lowFile = askFile("Select file to report true matches", "OK");
File highFile = askFile("Select file to report false positives", "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); lowTruePositive = new FileWriter(lowFile);
highFalsePositive = new FileWriter(highFile); highFalsePositive = new FileWriter(highFile);
@ -540,7 +564,7 @@ public class FidStatistics extends GhidraScript {
int maxPrograms = programList.size(); int maxPrograms = programList.size();
int counter = 0; int counter = 0;
try { try {
for(DomainFile domainFile : programList) { for (DomainFile domainFile : programList) {
Program program = null; Program program = null;
try { try {
program = (Program) domainFile.getDomainObject(this, false, false, monitor); program = (Program) domainFile.getDomainObject(this, false, false, monitor);
@ -551,7 +575,7 @@ public class FidStatistics extends GhidraScript {
lastLanguage = program.getLanguage(); lastLanguage = program.getLanguage();
queryService = service.openFidQueryService(lastLanguage, false); queryService = service.openFidQueryService(lastLanguage, false);
} }
processProgram(program,queryService); processProgram(program, queryService);
counter += 1; counter += 1;
monitor.setMessage("Processing programs ..."); monitor.setMessage("Processing programs ...");
monitor.initialize(maxPrograms); monitor.initialize(maxPrograms);
@ -563,7 +587,8 @@ public class FidStatistics extends GhidraScript {
} }
} }
} }
} catch(CancelledException ex) { }
catch (CancelledException ex) {
// A cancel in middle of processing still allows results to get printed // A cancel in middle of processing still allows results to get printed
} }

View file

@ -278,7 +278,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand {
private boolean hasUserOrImportedSymbols(Function function) { private boolean hasUserOrImportedSymbols(Function function) {
Program program = function.getProgram(); Program program = function.getProgram();
SymbolTable symbolTable = program.getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(function.getEntryPoint()); SymbolIterator symbols = symbolTable.getSymbolsAsIterator(function.getEntryPoint());
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
SourceType sourceType = symbol.getSource(); SourceType sourceType = symbol.getSource();
if (sourceType == SourceType.USER_DEFINED || sourceType == SourceType.IMPORTED) { if (sourceType == SourceType.USER_DEFINED || sourceType == SourceType.IMPORTED) {
@ -297,40 +297,27 @@ public class ApplyFidEntriesCommand extends BackgroundCommand {
} }
/** /**
* Delete a symbol of the given name and address, knowing there are multiple Symbols at the address. * Delete a symbol of the given name at the given address.
* If the symbol is primary, make another Symbol at the address primary before deleting *
* @param matchName is the given Symbol name * @param matchName is the given Symbol name
* @param addr is the given Address * @param addr is the given Address
* @param program is the Program * @param program is the Program
* @return the number of Symbols remaining at the address * @return the number of Symbols remaining at the address
*/ */
private int deleteSymbol(String matchName, Address addr, Program program) { 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); Symbol[] symbols = program.getSymbolTable().getSymbols(addr);
numSymbols = symbols.length; int numSymbols = symbols.length;
if (numSymbols <= 1) { if (numSymbols <= 1) {
break; return numSymbols;
} }
for (Symbol sym : symbols) { // Among Symbols at the Address // find the matching symbol and delete it
if (sym.getName().equals(matchName)) { // Find one with matching name for (Symbol sym : symbols) {
if (!sym.isPrimary()) { // If it is not primary if (sym.getName().equals(matchName)) {
sym.delete(); // delete it immediately sym.delete();
numSymbols -= 1; 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; break;
} }
} }
}
return numSymbols; return numSymbols;
} }

View file

@ -460,14 +460,9 @@ class FidServiceLibraryIngest {
} }
private static String grabSymbol(SymbolTable symbolTable, Address address) { private static String grabSymbol(SymbolTable symbolTable, Address address) {
Symbol[] symbols = symbolTable.getSymbols(address); Symbol primary = symbolTable.getPrimarySymbol(address);
if (symbols == null || symbols.length == 0) { if (primary != null) {
return null; return primary.getName();
}
for (Symbol symbol : symbols) {
if (symbol.isPrimary()) {
return symbol.getName();
}
} }
return null; return null;
} }

View file

@ -264,7 +264,9 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4)); Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4));
Data baseClassDescriptor = getDataAt(baseClassDescriptorAddress); Data baseClassDescriptor = getDataAt(baseClassDescriptorAddress);
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals( if (baseClassDescriptor == null || !baseClassDescriptor.getDataType()
.getName()
.equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) { RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
int num1 = getInt(baseClassDescriptorAddress.add(8)); int num1 = getInt(baseClassDescriptorAddress.add(8));
@ -352,7 +354,9 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
Data classHierarchyStructure = getDataAt(classHierarchyDescriptorAddress); Data classHierarchyStructure = getDataAt(classHierarchyDescriptorAddress);
if (classHierarchyStructure != null && if (classHierarchyStructure != null &&
classHierarchyStructure.getDataType().getName().equals( classHierarchyStructure.getDataType()
.getName()
.equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) { RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
return classHierarchyDescriptorAddress; return classHierarchyDescriptorAddress;
@ -588,7 +592,7 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
private Symbol getGivenSymbol(Address address, String name, Namespace namespace) private Symbol getGivenSymbol(Address address, String name, Namespace namespace)
throws CancelledException { throws CancelledException {
Symbol[] symbols = symbolTable.getSymbols(address); SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol sym : symbols) { for (Symbol sym : symbols) {
monitor.checkCanceled(); monitor.checkCanceled();
if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) { if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) {

View file

@ -278,7 +278,7 @@ public class EHDataTypeUtilities {
dataTypeName = SymbolUtilities.replaceInvalidChars(dataTypeName, true); dataTypeName = SymbolUtilities.replaceInvalidChars(dataTypeName, true);
SymbolTable symbolTable = program.getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(address); SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
if (symbol.getName().contains(dataTypeName)) { if (symbol.getName().contains(dataTypeName)) {
return null; // Already have one with dataTypeName. return null; // Already have one with dataTypeName.

View file

@ -97,7 +97,7 @@ public class RttiUtil {
return false; return false;
} }
// Don't create it if a similar symbol already exists at the address of the data. // 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) { for (Symbol symbol : symbols) {
String name = symbol.getName(); String name = symbol.getName();
if (name.contains(rttiSuffix)) { if (name.contains(rttiSuffix)) {
@ -159,7 +159,7 @@ public class RttiUtil {
} }
// check in .text and .nep if either exists // check in .text and .nep if either exists
if ( textBlock != null || nepBlock != null) { if (textBlock != null || nepBlock != null) {
MemoryBlock refedBlock = memory.getBlock(referencedAddress); MemoryBlock refedBlock = memory.getBlock(referencedAddress);
boolean inTextBlock = ((textBlock != null) && textBlock.equals(refedBlock)); boolean inTextBlock = ((textBlock != null) && textBlock.equals(refedBlock));
boolean inNepBlock = ((nepBlock != null) && nepBlock.equals(refedBlock)); boolean inNepBlock = ((nepBlock != null) && nepBlock.equals(refedBlock));
@ -358,7 +358,8 @@ public class RttiUtil {
} }
// check to see if symbol already exists both non-pdb and pdb versions // 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) { if (vftableSymbol != null) {
return; return;
} }

View file

@ -57,6 +57,7 @@ public class BlockGraphTask extends Task {
private ColorizingService colorizingService; private ColorizingService colorizingService;
private final static String ENTRY_NEXUS_NAME = "Entry Points"; private final static String ENTRY_NEXUS_NAME = "Entry Points";
private static final int MAX_SYMBOLS = 10;
private CodeBlockModel blockModel; private CodeBlockModel blockModel;
private AddressSetView selection; private AddressSetView selection;
private ProgramLocation location; private ProgramLocation location;
@ -417,14 +418,20 @@ public class BlockGraphTask extends Task {
} }
private void addSymbolAttribute(AttributedVertex vertex, CodeBlock bb) { private void addSymbolAttribute(AttributedVertex vertex, CodeBlock bb) {
Symbol[] symbols = program.getSymbolTable().getSymbols(bb.getMinAddress()); SymbolIterator it = program.getSymbolTable().getSymbolsAsIterator(bb.getMinAddress());
if (symbols.length != 0) { int count = 0;
if (it.hasNext()) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i = 0; i < symbols.length; i++) { for (Symbol symbol : it) {
if (i != 0) { if (count != 0) {
buf.append('\n'); 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()); vertex.setAttribute(SYMBOLS_ATTRIBUTE, buf.toString());
} }

View file

@ -15,8 +15,7 @@
*/ */
package ghidra.feature.vt.api.markuptype; 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.*;
import static ghidra.feature.vt.gui.util.VTOptionDefines.LABELS;
import java.util.*; import java.util.*;
@ -232,10 +231,6 @@ public class LabelMarkupType extends VTMarkupType {
LabelMarkupUtils.removeAllLabels(getDestinationProgram(association), LabelMarkupUtils.removeAllLabels(getDestinationProgram(association),
destinationAddress); destinationAddress);
} }
else if (replaceDefault) {
LabelMarkupUtils.removeDefaultLabels(getDestinationProgram(association),
destinationAddress);
}
Program destinationProgram = getDestinationProgram(association); Program destinationProgram = getDestinationProgram(association);
try { try {

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,30 +23,14 @@ import ghidra.program.model.symbol.SymbolTable;
public class LabelMarkupUtils { public class LabelMarkupUtils {
public static void removeDefaultLabels( Program destinationProgram, Address address ) { public static void removeAllLabels(Program destinationProgram, Address address) {
SymbolTable symbolTable = destinationProgram.getSymbolTable(); SymbolTable symbolTable = destinationProgram.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols( address ); Symbol[] symbols = symbolTable.getSymbols(address);
for ( Symbol symbol : symbols ) { for (Symbol symbol : symbols) {
if ( symbol instanceof FunctionSymbol ) { if (symbol instanceof FunctionSymbol) {
continue; continue;
} }
symbolTable.removeSymbolSpecial(symbol);
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 );
} }
} }

View file

@ -401,7 +401,7 @@ public class NamespaceUtils {
return null; return null;
} }
Symbol[] symbols = program.getSymbolTable().getSymbols(address); SymbolIterator symbols = program.getSymbolTable().getSymbolsAsIterator(address);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
if (symbol.getSymbolType() == SymbolType.FUNCTION && if (symbol.getSymbolType() == SymbolType.FUNCTION &&
symbolPath.matchesPathOf(symbol)) { symbolPath.matchesPathOf(symbol)) {

View file

@ -757,16 +757,14 @@ public class PseudoDisassembler {
for (Address flow : flows) { for (Address flow : flows) {
// does this reference a valid function? // does this reference a valid function?
if (program != null) { if (program != null) {
Symbol[] syms = program.getSymbolTable().getSymbols(flow); Symbol primary = program.getSymbolTable().getPrimarySymbol(flow);
for (Symbol sym : syms) { if (primary.getSymbolType() == SymbolType.FUNCTION) {
if (sym.getSymbolType() == SymbolType.FUNCTION) {
didCallValidSubroutine = true; didCallValidSubroutine = true;
break;
}
} }
} }
// if respecting execute flag on memory, test to make sure we did flow into non-execute memory // 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()) { if (!flow.isExternalAddress()) {
MemoryBlock block = memory.getBlock(flow); MemoryBlock block = memory.getBlock(flow);
// flowing into non-executable, but readable memory is bad // flowing into non-executable, but readable memory is bad
@ -782,7 +780,9 @@ public class PseudoDisassembler {
target = newTarget; target = newTarget;
} }
} }
catch (InsufficientBytesException e) { catch (
InsufficientBytesException e) {
return false; return false;
} }
catch (UnknownInstructionException e) { catch (UnknownInstructionException e) {

View file

@ -270,16 +270,21 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
try { try {
checkIsValid(); checkIsValid();
ReferenceManager rm = symbolMgr.getReferenceManager(); ReferenceManager rm = symbolMgr.getReferenceManager();
ReferenceIterator iter = rm.getReferencesTo(address);
boolean isPrimary = this.isPrimary(); // if there is only one symbol, then all the references to this address count
Symbol[] symbols = symbolMgr.getSymbols(address); if (hasExactlyOneSymbolAtAddress(address)) {
if (symbols.length == 1) {
return rm.getReferenceCountTo(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; int count = 0;
boolean isPrimary = this.isPrimary();
while (iter.hasNext()) { while (iter.hasNext()) {
Reference ref = iter.next(); Reference ref = iter.next();
long symbolID = ref.getSymbolID(); 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)) { if (symbolID == key || (isPrimary && symbolID < 0)) {
count++; 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 @Override
public Reference[] getReferences(TaskMonitor monitor) { public Reference[] getReferences(TaskMonitor monitor) {
lock.acquire(); lock.acquire();

View file

@ -600,7 +600,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
if (sym.getSymbolType() == SymbolType.FUNCTION) { if (sym.getSymbolType() == SymbolType.FUNCTION) {
Address addr = sym.getAddress(); Address addr = sym.getAddress();
Function f = (Function) sym.getObject(); Function f = (Function) sym.getObject();
Symbol nextPrimary = getNextPrimarySymbol(this, addr); Symbol nextPrimary = findFirstNonPrimarySymbol(addr);
String name; String name;
Namespace parentNamespace; Namespace parentNamespace;
SourceType source; SourceType source;
@ -636,20 +636,14 @@ public class SymbolManager implements SymbolTable, ManagerDB {
} }
} }
// @Override private Symbol findFirstNonPrimarySymbol(Address address) {
// public boolean removeSymbol(Symbol sym) { SymbolIterator it = getSymbolsAsIterator(address);
// return removeSymbolSpecial(sym); for (Symbol symbol : it) {
// } if (!symbol.isPrimary()) {
return symbol; // return the first non-primary symbol we find
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.
} }
} }
return next; return null;
} }
void removeChildren(SymbolDB sym) { void removeChildren(SymbolDB sym) {
@ -804,6 +798,21 @@ public class SymbolManager implements SymbolTable, ManagerDB {
return false; 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 @Override
public Symbol[] getSymbols(Address addr) { public Symbol[] getSymbols(Address addr) {
lock.acquire(); lock.acquire();
@ -932,14 +941,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override @Override
public Symbol getGlobalSymbol(String name, Address addr) { public Symbol getGlobalSymbol(String name, Address addr) {
Symbol[] symbols = getSymbols(addr); return getSymbol(name, addr, program.getGlobalNamespace());
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;
} }
@Override @Override
@ -1714,9 +1716,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
private void findNextDynamicSymbol() { private void findNextDynamicSymbol() {
while (addrIt.hasNext()) { while (addrIt.hasNext()) {
Symbol[] symbols = getSymbols(addrIt.next()); Symbol symbol = getPrimarySymbol(addrIt.next());
if (symbols.length == 1 && symbols[0].isDynamic()) { if (symbol != null && symbol.isDynamic()) {
nextDynamicSymbol = symbols[0]; nextDynamicSymbol = symbol;
return; return;
} }
} }
@ -3062,28 +3064,3 @@ public class SymbolManager implements SymbolTable, ManagerDB {
return getFirstSymbol(name, namespace, s -> s.getSymbolType() == type); return getFirstSymbol(name, namespace, s -> s.getSymbolType() == type);
} }
} }
class SymbolMatcher implements Predicate<Symbol> {
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;
}
}

View file

@ -353,11 +353,26 @@ public interface SymbolTable {
* the primary symbol will be returned in array slot 0. * the primary symbol will be returned in array slot 0.
* WARNING! Use of this method with a Variable address is highly discouraged since * 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. * 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. * @param addr the address at which to retrieve all symbols.
* @return a zero-length array when no symbols are defined at address. * @return a zero-length array when no symbols are defined at address.
* @see #getSymbolsAsIterator(Address)
*/ */
public Symbol[] getSymbols(Address addr); 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 * Returns an array of all user defined symbols at the given address
* @param addr the address at which to retrieve all user defined symbols. * @param addr the address at which to retrieve all user defined symbols.

View file

@ -1032,7 +1032,7 @@ public class SymbolUtilities {
if (namespace.isGlobal()) { if (namespace.isGlobal()) {
// do not add global symbol if same name already exists at address // 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())) { if (name.equals(s.getName())) {
return null; return null;
} }