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
33 changed files with 530 additions and 550 deletions
@@ -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
public Symbol[] getUserSymbols(Address addr) {
try (LockHold hold = program.trace.lockRead()) {
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,58 +25,49 @@ import ghidra.program.model.symbol.*;
public class AutoRenameLabelsScript extends GhidraScript {
@Override
public void run() throws Exception {
if (currentSelection == null || currentSelection.isEmpty()) {
println("No selection exists.");
return;
}
@Override
public void run() throws Exception {
if (currentSelection == null || currentSelection.isEmpty()) {
println("No selection exists.");
return;
}
String base = askString("Auto Rename Labels", "Enter label base name:");
if (base == null) {
println("No base value entered.");
return;
}
String base = askString("Auto Rename Labels", "Enter label base name:");
if (base == null) {
println("No base value entered.");
return;
}
int num = 1;
int num = 1;
AddressSetView view = currentSelection;
if ((view == null) || (view.isEmpty())) return;
AddressSetView view = currentSelection;
if ((view == null) || (view.isEmpty()))
return;
// Obtain the symbol table and listing from program
SymbolTable symbolTable = currentProgram.getSymbolTable();
// Obtain the symbol table and listing from program
SymbolTable symbolTable = currentProgram.getSymbolTable();
// Get the addresses in the set.
AddressIterator it = view.getAddresses(true);
CompoundCmd cmd = new CompoundCmd("Auto Rename Labels");
while(it.hasNext()) {
Address address = it.next();
Symbol[] symbols = symbolTable.getSymbols(address);
Symbol defaultSymbol = getDynamicSymbol( symbols );
if ( defaultSymbol != null ) {
cmd.add(new RenameLabelCmd(address, null, base+num++, SourceType.USER_DEFINED));
}
}
if (cmd.size() > 0) {
if (!cmd.applyTo(currentProgram)) {
String msg = cmd.getStatusMsg();
if (msg != null && msg.length() > 0) {
setToolStatusMessage(msg, true);
}
}
}
else {
println("No default labels found in selection.");
}
}
// Get the addresses in the set.
AddressIterator it = view.getAddresses(true);
private Symbol getDynamicSymbol( Symbol[] symbols ) {
for (int i=0;i<symbols.length;i++) {
if ( symbols[i].getSource() == SourceType.DEFAULT ) {
return symbols[i];
}
}
return null;
}
CompoundCmd cmd = new CompoundCmd("Auto Rename Labels");
while (it.hasNext()) {
Address address = it.next();
Symbol primary = symbolTable.getPrimarySymbol(address);
if (primary != null && primary.getSource() == SourceType.DEFAULT) {
cmd.add(new RenameLabelCmd(address, null, base + num++, SourceType.USER_DEFINED));
}
}
if (cmd.size() > 0) {
if (!cmd.applyTo(currentProgram)) {
String msg = cmd.getStatusMsg();
if (msg != null && msg.length() > 0) {
setToolStatusMessage(msg, true);
}
}
}
else {
println("No default labels found in selection.");
}
}
}
@@ -77,7 +77,7 @@ public class GccRttiAnalysisScript extends GhidraScript {
symbolTable = currentProgram.getSymbolTable();
globalNamespace = (GlobalNamespace) currentProgram.getGlobalNamespace();
// create the path for the data type manager root/ClassDataTypes folder
classDataTypesCategoryPath =
createDataTypeCategoryPath(CategoryPath.ROOT, DTM_CLASS_DATA_FOLDER_NAME);
@@ -201,7 +201,7 @@ public class GccRttiAnalysisScript extends GhidraScript {
// find the three special vtables and replace the incorrectly made array with
// data types found in vtable
boolean continueProcessing = createSpecialVtables();
if(!continueProcessing) {
if (!continueProcessing) {
return;
}
// find all typeinfo symbols and get their class namespace and create RecoveredClass object
@@ -264,9 +264,11 @@ public class GccRttiAnalysisScript extends GhidraScript {
return false;
}
}
if(class_type_info_vtable == null && si_class_type_info_vtable == null && vmi_class_type_info_vtable == null) {
println("Since there are no class typeinfo tables this program does not appear to have RTTI.");
if (class_type_info_vtable == null && si_class_type_info_vtable == null &&
vmi_class_type_info_vtable == null) {
println(
"Since there are no class typeinfo tables this program does not appear to have RTTI.");
return false;
}
return true;
@@ -378,7 +380,7 @@ public class GccRttiAnalysisScript extends GhidraScript {
// Except for the first one which should have a symbol, if there is a symbol at the
// address, stop making longs because it there are no references into the vtable longs
if (offset > 0 && symbolTable.getSymbols(address).length > 0) {
if (offset > 0 && symbolTable.getPrimarySymbol(address) != null) {
return numLongs;
}
@@ -499,8 +501,11 @@ public class GccRttiAnalysisScript extends GhidraScript {
private void setIsGcc() {
isGcc =
currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase(
"gcc");
currentProgram.getCompilerSpec()
.getCompilerSpecID()
.getIdAsString()
.equalsIgnoreCase(
"gcc");
}
private void createTypeinfoStructs(List<Symbol> typeinfoSymbols) throws CancelledException {
@@ -684,7 +689,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
*/
private void processVtables() throws Exception {
// find all vtable symbols
List<Symbol> listOfVtableSymbols = getListOfSymbolsInAddressSet(
currentProgram.getAddressFactory().getAddressSet(), VTABLE_LABEL, false);
@@ -700,7 +704,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
processVtable(vtableAddress, vtableNamespace, true);
}
return;
}
@@ -756,7 +759,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
return;
}
int numFunctionPointers = getNumFunctionPointers(vftableAddress, true, true);
// if at least one function pointer make vftable label - the createVftable method will
@@ -791,7 +793,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
}
}
// check for an internal vtable and make a symbol there if there is one
// will process them later
Address possibleInternalVtableAddress =
@@ -1160,7 +1161,6 @@ public class GccRttiAnalysisScript extends GhidraScript {
}
}
private Address findNextTypeinfoRef(Address startAddress) {
int offset = 0;
@@ -1275,4 +1275,3 @@ public class GccRttiAnalysisScript extends GhidraScript {
}
}
@@ -970,10 +970,11 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer {
return false;
}
// See if the tested address is contained in memory
// if the reference is not in memory or to a well known location, then don't create it
// because we are not sure it is correct
if (!memory.contains(testAddr)) {
Symbol syms[] = program.getSymbolTable().getSymbols(testAddr);
if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) {
Symbol symbol = program.getSymbolTable().getPrimarySymbol(testAddr);
if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
return false;
}
}
@@ -56,7 +56,7 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
private static final int MAX_NEG_ENTRIES = 32;
private int alignment = 4;
private TaskMonitor monitor;
public ScalarOperandAnalyzer() {
@@ -78,7 +78,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
}
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor taskMonitor, MessageLog log) {
public boolean added(Program program, AddressSetView set, TaskMonitor taskMonitor,
MessageLog log) {
int count = 0;
monitor = taskMonitor;
@@ -88,14 +89,15 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
// Evaluate each operand
//
Listing listing = program.getListing();
InstructionIterator iter = listing.getInstructions(set, true);
while (iter.hasNext() && !monitor.isCancelled()) {
Instruction instr = iter.next();
monitor.setProgress(++count);
checkOperands(program, instr);
}
} finally {
}
finally {
monitor = null; // get rid of the reference to it
}
@@ -123,22 +125,26 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
try {
switch (scalar.bitLength()) {
case 8:
if (program.getMemory().getByte(addr) == scalar.getSignedValue()) {
if (program.getMemory().getByte(addr) == scalar
.getSignedValue()) {
found = true;
}
break;
case 16:
if (program.getMemory().getShort(addr) == scalar.getSignedValue()) {
if (program.getMemory().getShort(addr) == scalar
.getSignedValue()) {
found = true;
}
break;
case 32:
if (program.getMemory().getInt(addr) == scalar.getSignedValue()) {
if (program.getMemory().getInt(addr) == scalar
.getSignedValue()) {
found = true;
}
break;
case 64:
if (program.getMemory().getLong(addr) == scalar.getSignedValue()) {
if (program.getMemory().getLong(addr) == scalar
.getSignedValue()) {
found = true;
}
break;
@@ -162,7 +168,8 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
}
// check the address in this space first
if (addReference(program, instr, i, instr.getMinAddress().getAddressSpace(), scalar)) {
if (addReference(program, instr, i, instr.getMinAddress().getAddressSpace(),
scalar)) {
continue;
}
@@ -209,10 +216,11 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
return false;
}
//check that memory contains the target address
// if the reference is not in memory or to a well known location, then don't create it
// because we are not sure it is correct
if (!program.getMemory().contains(addr)) {
Symbol syms[] = program.getSymbolTable().getSymbols(addr);
if (syms == null || syms.length == 0 || syms[0].getSource() == SourceType.DEFAULT) {
Symbol symbol = program.getSymbolTable().getPrimarySymbol(addr);
if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
return false;
}
}
@@ -284,8 +292,9 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled);
if (table != null) {
// add in an offcut reference
program.getReferenceManager().addOffsetMemReference(refInstr.getMinAddress(), offAddr,
-entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
program.getReferenceManager()
.addOffsetMemReference(refInstr.getMinAddress(), offAddr,
-entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
return;
}
@@ -321,8 +330,9 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
offAddr = lastGoodTable.getTopAddress();
// add in an offcut reference
program.getReferenceManager().addOffsetMemReference(instr.getMinAddress(), offAddr,
(i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
program.getReferenceManager()
.addOffsetMemReference(instr.getMinAddress(), offAddr,
(i + 3) * entryLen, RefType.DATA, SourceType.ANALYSIS, opIndex);
return;
}
}
@@ -121,7 +121,7 @@ public class OperandLabelDialog extends DialogComponentProvider {
// the presentation at the call or jump instruction, it doesn't matter which symbol of the
// same name you pick.
private Symbol findSymbol(SymbolTable symTable, String currentLabel, Address symAddr) {
Symbol[] symbols = symTable.getSymbols(symAddr);
SymbolIterator symbols = symTable.getSymbolsAsIterator(symAddr);
for (Symbol symbol : symbols) {
if (symbol.getName(true).equals(currentLabel)) {
return symbol;
@@ -153,8 +153,9 @@ public class MakeStringsTask extends ProgramTask {
if (paddingLength != 0) {
try {
program.getListing().createData(address.add(length), new AlignmentDataType(),
paddingLength);
program.getListing()
.createData(address.add(length), new AlignmentDataType(),
paddingLength);
}
catch (Exception e) {
// don't care that padding failed
@@ -241,7 +242,7 @@ public class MakeStringsTask extends ProgramTask {
private boolean labelAlreadyExists(Address addr, String name) {
SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(addr);
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(addr);
for (Symbol symbol : symbols) {
if (symbol.getName().equals(name)) {
return true;
@@ -287,11 +287,7 @@ class SymbolTableModel extends AddressBasedTableModel<Symbol> {
CompoundCmd cmd = new CompoundCmd("Delete symbol(s)");
for (Symbol symbol : rowObjects) {
if (symbol.isDynamic()) {
Symbol[] symbols = symbolTable.getSymbols(symbol.getAddress());
if (symbols.length == 1) {
tool.setStatusInfo("Unable to delete symbol: " + symbol.getName());
continue;//can't delete dynamic symbols...
}
continue;//can't delete dynamic symbols...
}
deleteList.add(symbol);
@@ -370,11 +370,9 @@ public class AddEditDialog extends DialogComponentProvider {
private FunctionSymbol getFunctionSymbol(Address address) {
SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(address);
for (Symbol localSymbol : symbols) {
if (localSymbol instanceof FunctionSymbol) {
return (FunctionSymbol) localSymbol;
}
Symbol primary = symbolTable.getPrimarySymbol(address);
if (primary instanceof FunctionSymbol) {
return (FunctionSymbol) primary;
}
return null;
}
@@ -395,10 +393,8 @@ public class AddEditDialog extends DialogComponentProvider {
pinnedCheckBox.setEnabled(true);
pinnedCheckBox.setSelected(false);
Symbol[] symbols = symbolTable.getSymbols(address);
FunctionSymbol functionSymbol = getFunctionSymbol(address);
if (functionSymbol == null && symbols.length == 0) {
Symbol primarySymbol = symbolTable.getPrimarySymbol(address);
if (primarySymbol == null) {
primaryCheckBox.setSelected(true);
primaryCheckBox.setEnabled(false);
}
@@ -463,9 +459,8 @@ public class AddEditDialog extends DialogComponentProvider {
nameBorder.setTitle("Enter Label:");
entryPointCheckBox.setEnabled(true);
entryPointCheckBox.setSelected(symbolTable.isExternalEntryPoint(addr));
Symbol[] symbols = symbolTable.getSymbols(addr);
primaryCheckBox.setSelected(s.isPrimary());
primaryCheckBox.setEnabled(!s.isPrimary() && symbols.length > 1);
primaryCheckBox.setEnabled(!s.isPrimary());
pinnedCheckBox.setEnabled(true);
pinnedCheckBox.setSelected(s.isPinned());
namespaceChoices.setEnabled(true);
@@ -234,7 +234,7 @@ public class ElfDefaultGotPltMarkup {
long symbolSearchSpacing; // nominal PLT entry size for computing maxSymbolSearchAddress
Address firstPltEntryAddr = null; // may be offcut within first PLT entry
if (pltSpacing == 0) { // Entries have same original bytes which refer to PLT head
Function pltHeadFunc = elfLoadHelper.createOneByteFunction(null, pltAddr1, false);
if (pltHeadFunc.getSymbol().getSource() == SourceType.DEFAULT) {
@@ -537,8 +537,9 @@ public class ElfDefaultGotPltMarkup {
// Stop on first error but discard error bookmark since
// some plt sections are partly empty and must rely
// on normal flow disassembly during analysis
prog.getBookmarkManager().removeBookmarks(set, BookmarkType.ERROR,
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
prog.getBookmarkManager()
.removeBookmarks(set, BookmarkType.ERROR,
Disassembler.ERROR_BOOKMARK_CATEGORY, monitor);
break;//we did not disassemble anything...
}
set.delete(disset);
@@ -604,11 +605,8 @@ public class ElfDefaultGotPltMarkup {
if (memory.contains(refAddr)) {
return true;
}
Symbol syms[] = program.getSymbolTable().getSymbols(refAddr);
if (syms != null && syms.length > 0 && syms[0].getSource() != SourceType.DEFAULT) {
return true;
}
return false;
Symbol primary = program.getSymbolTable().getPrimarySymbol(refAddr);
return primary != null && primary.getSource() != SourceType.DEFAULT;
}
private void removeMemRefs(Data data) {
@@ -1570,7 +1570,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
return address;
}
/**
* Find memory register with matching name (ignoring leading and trailing underscore chars).
* @param elfSymbol ELF symbol
@@ -1586,7 +1586,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
}
return regAddr;
}
private Address getMemoryRegister(String name, long value) {
Register reg = program.getRegister(name);
if (reg != null && reg.getAddress().isMemoryAddress()) {
@@ -2360,9 +2360,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
.addMemoryReference(valueData.getAddress(), refAddr, RefType.DATA,
SourceType.ANALYSIS, 0);
if (label != null) {
// add label if a non-default label does not exist
Symbol[] symbols = program.getSymbolTable().getSymbols(refAddr);
if (symbols.length == 0 || symbols[0].getSource() == SourceType.DEFAULT) {
// add label if no label exists of there is just a default label
Symbol symbol = program.getSymbolTable().getPrimarySymbol(refAddr);
if (symbol == null || symbol.getSource() == SourceType.DEFAULT) {
createSymbol(refAddr, "_" + label, false, false, null);
}
}
@@ -1377,7 +1377,7 @@ public class FlatProgramAPI {
*/
@Deprecated
public final Symbol getSymbolAt(Address address, String name) {
Symbol[] symbols = currentProgram.getSymbolTable().getSymbols(address);
SymbolIterator symbols = currentProgram.getSymbolTable().getSymbolsAsIterator(address);
for (Symbol symbol : symbols) {
if (symbol.getName().equals(name)) {
return symbol;
@@ -199,7 +199,28 @@ public class SymbolManagerTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(!s.isGlobal());
assertTrue(s.getSource() == SourceType.USER_DEFINED);
assertTrue(s.isPrimary());
}
@Test
public void testGetSymbolIteratorByAddress() throws Exception {
createSymbol(addr(100), "A");
createSymbol(addr(100), "fred");
createSymbol(addr(100), "joe");
Namespace scope = st.createNameSpace(null, "MyNamespace", SourceType.USER_DEFINED);
createSymbol(addr(200), "fred", scope);
SymbolIterator it = st.getSymbolsAsIterator(addr(100));
assertTrue(it.hasNext());
assertEquals("A", it.next().getName());
assertTrue(it.hasNext());
assertEquals("fred", it.next().getName());
assertTrue(it.hasNext());
assertEquals("joe", it.next().getName());
assertFalse(it.hasNext());
}
@Test
@@ -166,8 +166,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
byte[] gccBytes = { (byte) 0x47, (byte) 0x43, (byte) 0x43, (byte) 0x3a };
byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
Address found = program.getMemory().findBytes(commentBlock.getStart(),
commentBlock.getEnd(), gccBytes, maskBytes, true, monitor);
Address found = program.getMemory()
.findBytes(commentBlock.getStart(),
commentBlock.getEnd(), gccBytes, maskBytes, true, monitor);
if (found == null) {
return false;
}
@@ -256,7 +257,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
updateClassesWithParentsAndFlags(typeinfoSymbols);
// update the vftable offset map
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
while (recoveredClassIterator.hasNext()) {
@@ -417,7 +417,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (specialTypeinfoRef.equals(vmi_class_type_info) ||
specialTypeinfoRef.equals(vmi_class_type_info_vtable)) {
List<RecoveredClass> parents =
addGccClassParentsFromVmiStruct(recoveredClass, typeinfoAddress);
@@ -493,7 +492,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
for (Address typeinfoRef : typeinfoReferencesNotInTypeinfoStructs) {
monitor.checkCanceled();
Address typeinfoAddress = extraUtils.getPointer(typeinfoRef);
if (typeinfoAddress == null) {
@@ -524,14 +522,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (!typeinfoSymbol.getName().equals("typeinfo")) {
continue;
}
// check for construction table and make new namespace if so
Namespace classNamespace = typeinfoSymbol.getParentNamespace();
if (classNamespace.equals(globalNamespace)) {
throw new Exception("typeinfo has global namespace " + typeinfoAddress);
}
try {
Symbol vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
@@ -617,8 +614,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return false;
}
private Namespace createConstructionNamespace(Symbol vtableSymbol, Symbol vttSymbol)
throws Exception {
@@ -635,7 +630,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
try {
Namespace newNamespace =
NamespaceUtils.createNamespaceHierarchy(name, vtableNamespace,
program, SourceType.ANALYSIS);
program, SourceType.ANALYSIS);
return newNamespace;
}
catch (InvalidInputException e) {
@@ -722,7 +717,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Data dataContainingTypeinfoRef = prog.getListing().getDefinedDataContaining(addr);
Instruction instructionContainingAddr =
prog.getListing().getInstructionContaining(addr);
@@ -863,8 +857,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
api.setPlateComment(vtableAddress, "construction vtable " + n +
" for class " +
vttSymbolBeforeConstructionVtable.getParentNamespace().getName(
true));
vttSymbolBeforeConstructionVtable.getParentNamespace()
.getName(
true));
}
catch (InvalidInputException e) {
@@ -897,7 +892,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
int numFunctionPointers = getNumFunctionPointers(possibleVftableAddress, true, true);
if (numFunctionPointers == 0) {
// if not a vftable check for an internal vtable
boolean isInternalVtable =
@@ -1190,7 +1185,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return false;
}
return true;
}
@@ -1402,7 +1396,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// Except for the first one which should have a symbol, if there is a symbol at the
// address, stop making longs because it there are no references into the vtable longs
if (offset > 0 && symbolTable.getSymbols(address).length > 0) {
if (offset > 0 && symbolTable.getPrimarySymbol(address) != null) {
return numLongs;
}
@@ -1489,33 +1483,34 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// create a "no inheritance" struct here
if (specialTypeinfoRef.equals(class_type_info) ||
specialTypeinfoRef.equals(class_type_info_vtable)) {
newStructure = applyTypeinfoStructure(classTypeInfoStructure, typeinfoAddress);
}
// create a "single inheritance" struct here
else if (specialTypeinfoRef.equals(si_class_type_info) ||
specialTypeinfoRef.equals(si_class_type_info_vtable)) {
newStructure = applyTypeinfoStructure(siClassTypeInfoStructure, typeinfoAddress);
}
// create a "virtual multip inheritance" struct here
else if (specialTypeinfoRef.equals(vmi_class_type_info) ||
specialTypeinfoRef.equals(vmi_class_type_info_vtable)) {
Structure vmiClassTypeinfoStructure =
getOrCreateVmiTypeinfoStructure(typeinfoAddress, baseClassTypeInfoStructure);
if (vmiClassTypeinfoStructure != null) {
newStructure = applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress);
newStructure =
applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress);
}
}
if (newStructure == null) {
throw new Exception(
"ERROR: Could not apply typeinfo structure to " + typeinfoAddress);
}
// check for existing symbol and if none, demangle the name and apply
Symbol typeinfoSymbol = api.getSymbolAt(typeinfoAddress);
if (typeinfoSymbol == null || typeinfoSymbol.getSource() == SourceType.DEFAULT) {
@@ -1840,7 +1835,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return specialTypeinfoRefs;
}
/**
* Method to call the various methods to determine whether the functions that make references to
* the vftables are constructors, destructors, deleting destructors, clones, or vbase functions
@@ -1985,7 +1979,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
DataType pointer = dataTypeManager.getPointer(null);
DataType charPointer = dataTypeManager.getPointer(characterDT);
vmiClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null);
vmiClassTypeInfoStructure.add(charPointer, "typeinfoName", null);
vmiClassTypeInfoStructure.add(unsignedIntDT, "flags", null);
@@ -2011,7 +2004,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private List<RecoveredClass> addGccClassParentsFromVmiStruct(RecoveredClass recoveredClass,
Address typeinfoAddress) throws Exception {
Structure vmiTypeinfoStructure = getTypeinfoStructure(typeinfoAddress);
if (vmiTypeinfoStructure == null ||
!vmiTypeinfoStructure.getName().contains(VMI_CLASS_TYPE_INFO_STRUCTURE)) {
@@ -2150,8 +2142,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
parentClass.setIsPublicClass(isPublic);
// from doc:
//All but the lower 8 bits of __offset_flags are a signed offset. For a
//non-virtual base, this is the offset in the object of the base subobject.
@@ -2168,7 +2158,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
continue;
}
if (DEBUG) {
@@ -2893,7 +2882,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return;
}
if (!recoveredClass.hasVftable()) {
createSimpleClassStructure(recoveredClass, null);
// return in this case because if there is no vftable for a class the script cannot
@@ -3018,7 +3006,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
" : structure should exist but doesn't.");
}
if (structUtils.canAdd(classStructureDataType, parentOffset,
baseClassStructure.getLength(), monitor)) {
classStructureDataType =
@@ -3049,7 +3036,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) {
if (classStructureDataType.getNumComponents() == classStructureDataType
.getNumDefinedComponents()) {
classStructureDataType.setPackingEnabled(true);
}
@@ -56,11 +56,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
private static final String VFTABLE_META_PTR_LABEL = "vftable_meta_ptr";
private static final String VFTABLE_LABEL = "vftable";
private static final String CLASS_VTABLE_STRUCT_NAME = "_vbtable";
private static final String CLASS_VTABLE_PTR_FIELD_EXT = "vftablePtr";
private static final int CHD_MULTINH = 0x00000001; //Multiple inheritance
private static final int CHD_VIRTINH = 0x00000002; //Virtual inheritance
private static final int CHD_AMBIGUOUS = 0x00000004; //Multiple inheritance with repeated base classes
@@ -91,7 +89,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return true;
}
@Override
public boolean isValidProgramType() {
if (!isVisualStudioOrClangPe()) {
@@ -100,7 +97,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return true;
}
@Override
public void fixUpProgram() {
@@ -184,10 +180,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
determineParentClassInfoFromBaseClassArray(recoveredClasses);
assignParentClassToVftables(recoveredClasses);
// using all the information found above, create the class structures, add the constructor,
// destructor, vfunctions to class which finds the appropriate class structure and assigns
// to "this" param
@@ -205,7 +199,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
//println("Removing erroneous FID namespaces and corresponding class data types");
removeEmptyClassesAndStructures();
}
return recoveredClasses;
}
catch (CancelledException e) {
@@ -219,14 +213,12 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
}
private boolean isVisualStudioOrClangPe() {
return program.getExecutableFormat().equals(PeLoader.PE_NAME) &&
(program.getCompiler().equals(CompilerEnum.VisualStudio.toString()) ||
program.getCompiler().equals(CompilerEnum.Clang.toString()));
}
private boolean hasTypeInfoVftable() throws CancelledException {
List<Symbol> vftableSymbols = getListOfVftableSymbols();
@@ -474,8 +466,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4));
Data baseClassDescriptor = extraUtils.getDataAt(baseClassDescriptorAddress);
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType()
.getName()
.equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
int num1 = extraUtils.getInt(baseClassDescriptorAddress.add(8));
int num2 = extraUtils.getInt(baseClassDescriptorAddress.add(12));
@@ -563,8 +557,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
Data classHierarchyStructure = extraUtils.getDataAt(classHierarchyDescriptorAddress);
if (classHierarchyStructure != null &&
classHierarchyStructure.getDataType().getName().equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
classHierarchyStructure.getDataType()
.getName()
.equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
return classHierarchyDescriptorAddress;
}
@@ -803,7 +799,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
private Symbol getGivenSymbol(Address address, String name, Namespace namespace)
throws CancelledException {
Symbol[] symbols = symbolTable.getSymbols(address);
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol sym : symbols) {
monitor.checkCanceled();
if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) {
@@ -884,10 +880,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
findFunctionsUsingAtexit();
}
/**
* Method to recover the class information for each vftable symbol on the list
* * For each virtual function table:
@@ -923,7 +915,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) {
classNamespace = promoteToClassNamespace(classNamespace);
if(classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) {
if (classNamespace.getSymbol().getSymbolType() != SymbolType.CLASS) {
Msg.debug(this,
classHierarchyDescriptorAddress.toString() + " Could not promote " +
classNamespace.getName(true) + " to a class namespace.");
@@ -963,11 +955,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
List<RecoveredClass> classesWithVftablesInNamespace =
recoverClassesFromVftables(vftableSymbolsInNamespace, false, false);
if (classesWithVftablesInNamespace.size() == 0) {
Msg.debug(this,"No class recovered for namespace " + classNamespace.getName());
Msg.debug(this, "No class recovered for namespace " + classNamespace.getName());
continue;
}
if (classesWithVftablesInNamespace.size() > 1) {
Msg.debug(this,"Unexpected multiple classes recovered for namespace " +
Msg.debug(this, "Unexpected multiple classes recovered for namespace " +
classNamespace.getName());
continue;
}
@@ -1372,7 +1364,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
}
/**
* Method to recover parent information, including class offsets, vbase structure and its offset and address if applicable, and whether
* the parent is regularly or virtually inherited
@@ -2142,14 +2133,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
}
/**
* Method to call create and apply class structures method starting with top parent classes
* and non-virtual classes then the children and their children until all classes are processed.
@@ -2493,7 +2476,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
Structure recoveredClassDataStruct =
createClassMemberDataStructure(recoveredClass,
classStructureDataType, dataLen, dataOffset);
classStructureDataType, dataLen, dataOffset);
if (recoveredClassDataStruct != null) {
classStructureDataType = structUtils.addDataTypeToStructure(
@@ -2502,7 +2485,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
}
if (classStructureDataType.getNumComponents() == classStructureDataType.getNumDefinedComponents()) {
if (classStructureDataType.getNumComponents() == classStructureDataType
.getNumDefinedComponents()) {
classStructureDataType.setPackingEnabled(true);
}
@@ -2590,7 +2574,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
return classStructureDataType;
}
/**
* Method to apply the given class's vbtable structure
* @param recoveredClass the given RecoveredClass object which, if applicable, contains the address and structure to apply
@@ -2615,6 +2598,4 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
recoveredClass.getClassNamespace().getName(true) + "::vbtable");
}
}
@@ -169,7 +169,6 @@ public class RecoveredClassUtils {
decompilerUtils = new DecompilerScriptUtils(program, tool, monitor);
structUtils = new EditStructureUtils();
dataTypeManager = program.getDataTypeManager();
symbolTable = program.getSymbolTable();
@@ -236,7 +235,7 @@ public class RecoveredClassUtils {
}
}
}
public List<Address> getVftableReferences(Function function) {
return functionToVftableRefsMap.get(function);
}
@@ -522,8 +521,6 @@ public class RecoveredClassUtils {
return allInlinedDestructors;
}
/**
* Method to determine if referenced vftables are from the same class
* @param vftableReferences list of vftable references
@@ -907,7 +904,7 @@ public class RecoveredClassUtils {
*/
public Address getStoredVftableAddress(List<OffsetPcodeOpPair> storedPcodeOps)
throws CancelledException {
if (storedPcodeOps.size() > 0) {
Iterator<OffsetPcodeOpPair> iterator = storedPcodeOps.iterator();
// figure out if vftable is referenced
@@ -1288,8 +1285,6 @@ public class RecoveredClassUtils {
}
/**
* Method to determine if the given possible ancestor is an ancestor of any of the listed classes
* @param recoveredClasses List of classes
@@ -2658,7 +2653,6 @@ public class RecoveredClassUtils {
return false;
}
/**
* Method to create a new recovered class object and add it to the namespaceToClassMap
* @param namespace the namespace to put the new class in
@@ -2724,7 +2718,7 @@ public class RecoveredClassUtils {
}
continue;
}
// get only the functions from the ones that are not already processed structures
// return null if not an unprocessed table
List<Function> virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol,
@@ -2766,7 +2760,6 @@ public class RecoveredClassUtils {
Map<Address, Function> vftableReferenceToFunctionMapping =
createVftableReferenceToFunctionMapping(referencesToVftable);
//vftableReferenceToFunctionMapping
List<Function> possibleConstructorDestructorsForThisClass =
findPossibleConstructorDestructors(vftableReferenceToFunctionMapping);
@@ -2910,8 +2903,6 @@ public class RecoveredClassUtils {
return cdFunctions;
}
/**
* Method to get functions from vftable
* @param vftableAddress the address of the vftable
@@ -3890,8 +3881,8 @@ public class RecoveredClassUtils {
String simpleName = extraUtils.removeTemplate(name);
Symbol[] symbols = symbolTable.getSymbols(address);
for (Symbol symbol : symbols) {
SymbolIterator it = symbolTable.getSymbolsAsIterator(address);
for (Symbol symbol : it) {
monitor.checkCanceled();
String simpleSymbolName = extraUtils.removeTemplate(symbol.getName());
@@ -4541,7 +4532,7 @@ public class RecoveredClassUtils {
if (nameField.contains("purecall")) {
nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber;
comment = recoveredClass.getName() + " pure " + comment;
}
PointerDataType functionPointerDataType =
@@ -4932,10 +4923,11 @@ public class RecoveredClassUtils {
//TODO: remove after testing
if (!classVftableRef.equals(otherWayRef)) {
if (DEBUG) {
Msg.debug(this,
recoveredClass.getName() + " function " +
functionContainingInline.getEntryPoint().toString() + " first ref: " +
classVftableRef.toString() + " other way ref: " + otherWayRef.toString());
Msg.debug(this,
recoveredClass.getName() + " function " +
functionContainingInline.getEntryPoint().toString() + " first ref: " +
classVftableRef.toString() + " other way ref: " +
otherWayRef.toString());
}
}
@@ -5056,8 +5048,9 @@ public class RecoveredClassUtils {
Function firstCalledFunction =
extraUtils.getCalledFunctionByCallOrder(deletingDestructor, 1);
if (firstCalledFunction == null ||
!recoveredClass.getConstructorOrDestructorFunctions().contains(
firstCalledFunction)) {
!recoveredClass.getConstructorOrDestructorFunctions()
.contains(
firstCalledFunction)) {
return null;
}
@@ -5201,11 +5194,14 @@ public class RecoveredClassUtils {
return;
}
if (parentDestructorClasses.size() == 1) {
if (!parentDestructorClasses.get(0).getDestructorList().contains(
parentDestructor)) {
if (!parentDestructorClasses.get(0)
.getDestructorList()
.contains(
parentDestructor)) {
addDestructorToClass(parentDestructorClasses.get(0), parentDestructor);
parentDestructorClasses.get(0).removeIndeterminateConstructorOrDestructor(
parentDestructor);
parentDestructorClasses.get(0)
.removeIndeterminateConstructorOrDestructor(
parentDestructor);
}
}
// if more than one parent class for this function then let either inline or multi-class
@@ -5390,8 +5386,10 @@ public class RecoveredClassUtils {
*/
public boolean isClassOffsetToVftableMapComplete(RecoveredClass recoveredClass) {
if (recoveredClass.getClassOffsetToVftableMap().values().containsAll(
recoveredClass.getVftableAddresses())) {
if (recoveredClass.getClassOffsetToVftableMap()
.values()
.containsAll(
recoveredClass.getVftableAddresses())) {
return true;
}
return false;
@@ -5434,8 +5432,9 @@ public class RecoveredClassUtils {
Function secondCalledFunction =
extraUtils.getCalledFunctionByCallOrder(vFunction, 2);
if (firstCalledFunction != null && secondCalledFunction != null &&
!recoveredClass.getConstructorOrDestructorFunctions().contains(
firstCalledFunction) &&
!recoveredClass.getConstructorOrDestructorFunctions()
.contains(
firstCalledFunction) &&
secondCalledFunction.equals(operator_delete) &&
!getAllConstructorsAndDestructors().contains(vFunction)) {
recoveredClass.addDeletingDestructor(vFunction);
@@ -6903,7 +6902,6 @@ public class RecoveredClassUtils {
}
}
return changedItems;
}
@@ -7419,12 +7417,12 @@ public class RecoveredClassUtils {
private Structure getParentClassStructure(Structure childClassStructure, String nameOfParent)
throws CancelledException {
DataTypeComponent[] components = childClassStructure.getComponents();
for (DataTypeComponent component : components) {
monitor.checkCanceled();
DataType componentDataType = component.getDataType();
if(componentDataType.getName().equals(nameOfParent)) {
if (componentDataType.getName().equals(nameOfParent)) {
return (Structure) componentDataType;
}
}
@@ -7520,22 +7518,24 @@ public class RecoveredClassUtils {
DataTypeComponent[] vfunctionComponents = vfunctionStructure.getComponents();
for (DataTypeComponent vfunctionComponent : vfunctionComponents) {
monitor.checkCanceled();
Object changedItem = updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress);
if(changedItem != null && !changedItems.contains(changedItem)) {
Object changedItem =
updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress);
if (changedItem != null && !changedItems.contains(changedItem)) {
changedItems.add(changedItem);
FunctionDefinition newFunctionDefinition = getComponentFunctionDefinition(vfunctionComponent);
if(newFunctionDefinition == null) {
FunctionDefinition newFunctionDefinition =
getComponentFunctionDefinition(vfunctionComponent);
if (newFunctionDefinition == null) {
continue;
}
List<Object> changedStructs =
applyNewFunctionDefinitionToComponents(vfunctionComponent,
newFunctionDefinition);
applyNewFunctionDefinitionToComponents(vfunctionComponent,
newFunctionDefinition);
if (changedStructs.isEmpty()) {
continue;
}
changedItems = updateList(changedItems, changedStructs);
}
}
@@ -7604,7 +7604,6 @@ public class RecoveredClassUtils {
return null;
}
boolean changed = updateFunctionSignature(vfunction, newFunctionDefinition);
if (changed) {
return vfunction;
@@ -502,7 +502,7 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer {
offset = ((Address) dataValue).getOffset();
if (offset == address.getOffset()) {
// Self-referencing pointer
name = null;
name = null;
}
else {
name = getNameFromOffset(program, offset, input, isClass, isMethod);
@@ -671,23 +671,18 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer {
}
private String getLabelFromUndefinedData(Program program, Address address) {
Symbol[] symbols = program.getSymbolTable().getSymbols(address);
if (symbols.length == 0) {
Symbol primary = program.getSymbolTable().getPrimarySymbol(address);
if (primary == null) {
return null;
}
for (Symbol symbol : symbols) {
if (symbol.isPrimary()) {
String symbolName = symbol.getName();
if (symbolName.contains("_OBJC_CLASS_$_")) {
symbolName = symbolName.substring("_OBJC_CLASS_$_".length());
}
else if (symbolName.contains("_objc_msgSend")) {
return null;
}
return symbolName;
}
String symbolName = primary.getName();
if (symbolName.contains("_OBJC_CLASS_$_")) {
symbolName = symbolName.substring("_OBJC_CLASS_$_".length());
}
return null;
else if (symbolName.contains("_objc_msgSend")) {
return null;
}
return symbolName;
}
private String getClassName(Program program, Address toAddress) {
@@ -764,14 +764,10 @@ public class FGProvider extends VisualGraphComponentProvider<FGVertex, FGEdge, F
SymbolTable symbolTable = currentProgram.getSymbolTable();
AddressSetView vertexAddresses = destinationVertex.getAddresses();
Address minAddress = vertexAddresses.getMinAddress();
Symbol[] symbols = symbolTable.getSymbols(minAddress);
if (symbols.length > 1) {
return; // real user symbols
}
else if (symbols.length == 1) {
if (!symbols[0].isDynamic()) {
return; // real user symbol
}
Symbol primary = symbolTable.getPrimarySymbol(minAddress);
if (!primary.isDynamic()) {
return;
}
ReferenceManager referenceManager = currentProgram.getReferenceManager();
File diff suppressed because it is too large Load Diff
@@ -278,7 +278,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand {
private boolean hasUserOrImportedSymbols(Function function) {
Program program = function.getProgram();
SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(function.getEntryPoint());
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(function.getEntryPoint());
for (Symbol symbol : symbols) {
SourceType sourceType = symbol.getSource();
if (sourceType == SourceType.USER_DEFINED || sourceType == SourceType.IMPORTED) {
@@ -297,39 +297,26 @@ public class ApplyFidEntriesCommand extends BackgroundCommand {
}
/**
* Delete a symbol of the given name and address, knowing there are multiple Symbols at the address.
* If the symbol is primary, make another Symbol at the address primary before deleting
* Delete a symbol of the given name at the given address.
*
* @param matchName is the given Symbol name
* @param addr is the given Address
* @param program is the Program
* @return the number of Symbols remaining at the address
*/
private int deleteSymbol(String matchName, Address addr, Program program) {
int numSymbols = 0;
for (int i = 0; i < 2; ++i) { // Try to find non-primary matching Symbol at most twice
Symbol[] symbols = program.getSymbolTable().getSymbols(addr);
numSymbols = symbols.length;
if (numSymbols <= 1) {
Symbol[] symbols = program.getSymbolTable().getSymbols(addr);
int numSymbols = symbols.length;
if (numSymbols <= 1) {
return numSymbols;
}
// find the matching symbol and delete it
for (Symbol sym : symbols) {
if (sym.getName().equals(matchName)) {
sym.delete();
numSymbols -= 1;
break;
}
for (Symbol sym : symbols) { // Among Symbols at the Address
if (sym.getName().equals(matchName)) { // Find one with matching name
if (!sym.isPrimary()) { // If it is not primary
sym.delete(); // delete it immediately
numSymbols -= 1;
break; // and we are done
}
Symbol otherSym = symbols[0];
if (otherSym == sym) { // Otherwise find another Symbol, which must not be primary
otherSym = symbols[1];
}
// Set the other symbol to primary
SetLabelPrimaryCmd cmd = new SetLabelPrimaryCmd(addr, otherSym.getName(),
otherSym.getParentNamespace());
cmd.applyTo(program);
break;
}
}
}
return numSymbols;
}
@@ -390,7 +377,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand {
BookmarkManager bookmarkManager = function.getProgram().getBookmarkManager();
bookmarkManager.setBookmark(addr, BookmarkType.ANALYSIS,
FIDCONFLICT_BOOKMARK_CATEGORY,
"Multiple likely matching functions");
"Multiple likely matching functions");
}
}
}
@@ -460,14 +460,9 @@ class FidServiceLibraryIngest {
}
private static String grabSymbol(SymbolTable symbolTable, Address address) {
Symbol[] symbols = symbolTable.getSymbols(address);
if (symbols == null || symbols.length == 0) {
return null;
}
for (Symbol symbol : symbols) {
if (symbol.isPrimary()) {
return symbol.getName();
}
Symbol primary = symbolTable.getPrimarySymbol(address);
if (primary != null) {
return primary.getName();
}
return null;
}
@@ -264,8 +264,10 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
Address baseClassDescriptorAddress = getReferencedAddress(address.add(i * 4));
Data baseClassDescriptor = getDataAt(baseClassDescriptorAddress);
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType().getName().equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
if (baseClassDescriptor == null || !baseClassDescriptor.getDataType()
.getName()
.equals(
RTTI_BASE_CLASS_DESCRIPTOR_DATA_NAME)) {
int num1 = getInt(baseClassDescriptorAddress.add(8));
int num2 = getInt(baseClassDescriptorAddress.add(12));
@@ -352,8 +354,10 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
Data classHierarchyStructure = getDataAt(classHierarchyDescriptorAddress);
if (classHierarchyStructure != null &&
classHierarchyStructure.getDataType().getName().equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
classHierarchyStructure.getDataType()
.getName()
.equals(
RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME)) {
return classHierarchyDescriptorAddress;
}
@@ -588,7 +592,7 @@ public class FixUpRttiAnalysisScript extends GhidraScript {
private Symbol getGivenSymbol(Address address, String name, Namespace namespace)
throws CancelledException {
Symbol[] symbols = symbolTable.getSymbols(address);
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol sym : symbols) {
monitor.checkCanceled();
if (sym.getName().contains(name) && sym.getParentNamespace().equals(namespace)) {
@@ -278,7 +278,7 @@ public class EHDataTypeUtilities {
dataTypeName = SymbolUtilities.replaceInvalidChars(dataTypeName, true);
SymbolTable symbolTable = program.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(address);
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(address);
for (Symbol symbol : symbols) {
if (symbol.getName().contains(dataTypeName)) {
return null; // Already have one with dataTypeName.
@@ -65,7 +65,7 @@ public class RttiUtil {
*/
static boolean createSymbolFromDemangledType(Program program, Address rttiAddress,
TypeDescriptorModel typeDescriptorModel, String rttiSuffix) {
rttiSuffix = SymbolUtilities.replaceInvalidChars(rttiSuffix, true);
// Get or create the namespace for this RTTI's type descriptor.
@@ -97,7 +97,7 @@ public class RttiUtil {
return false;
}
// Don't create it if a similar symbol already exists at the address of the data.
Symbol[] symbols = symbolTable.getSymbols(rttiAddress);
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(rttiAddress);
for (Symbol symbol : symbols) {
String name = symbol.getName();
if (name.contains(rttiSuffix)) {
@@ -159,7 +159,7 @@ public class RttiUtil {
}
// check in .text and .nep if either exists
if ( textBlock != null || nepBlock != null) {
if (textBlock != null || nepBlock != null) {
MemoryBlock refedBlock = memory.getBlock(referencedAddress);
boolean inTextBlock = ((textBlock != null) && textBlock.equals(refedBlock));
boolean inNepBlock = ((nepBlock != null) && nepBlock.equals(refedBlock));
@@ -168,12 +168,12 @@ public class RttiUtil {
break; // Not pointing to good section.
}
}
// any references after the first one ends the table
if (tableSize > 0 && referenceManager.hasReferencesTo(currentVfPointerAddress)) {
break;
}
Function function = functionManager.getFunctionAt(referencedAddress);
if (function == null &&
@@ -212,12 +212,12 @@ public class RttiUtil {
boolean terminationRequest = false;
Address commonVftableAddress = null;
Program program;
public CommonRTTIMatchCounter(Program program) {
this.program = program;
defaultPointerSize = program.getDefaultPointerSize();
}
public Address getinfoVfTable() {
return commonVftableAddress;
}
@@ -249,10 +249,10 @@ public class RttiUtil {
}
matchingAddrCount = 0;
}
commonVftableAddress = possibleVftableAddress;
matchingAddrCount++;
if (matchingAddrCount > MIN_MATCHING_VFTABLE_PTRS) {
// done finding good addresses have at Minimum matching number
terminationRequest = true;
@@ -261,7 +261,7 @@ public class RttiUtil {
return;
}
}
/**
* Method to figure out the type_info vftable address using pointed to value by all RTTI classes
* @param program the current program
@@ -293,7 +293,7 @@ public class RttiUtil {
dataBlocks, set, monitor);
infoVftableAddress = vfTableAddrChecker.getinfoVfTable();
}
// cache result of search
vftableMap.put(program, infoVftableAddress);
@@ -308,18 +308,18 @@ public class RttiUtil {
private static Address findTypeInfoVftableLabel(Program program) {
SymbolTable symbolTable = program.getSymbolTable();
Namespace typeinfoNamespace =
symbolTable.getNamespace(TYPE_INFO_NAMESPACE, program.getGlobalNamespace());
symbolTable.getNamespace(TYPE_INFO_NAMESPACE, program.getGlobalNamespace());
Symbol vftableSymbol =
symbolTable.getLocalVariableSymbol("vftable", typeinfoNamespace);
symbolTable.getLocalVariableSymbol("vftable", typeinfoNamespace);
if (vftableSymbol != null) {
return vftableSymbol.getAddress();
}
vftableSymbol = symbolTable.getLocalVariableSymbol("`vftable'", typeinfoNamespace);
if (vftableSymbol != null) {
return vftableSymbol.getAddress();
}
vftableSymbol = symbolTable.getLocalVariableSymbol("type_info", typeinfoNamespace);
if (vftableSymbol != null) {
return vftableSymbol.getAddress();
@@ -358,7 +358,8 @@ public class RttiUtil {
}
// check to see if symbol already exists both non-pdb and pdb versions
Symbol vftableSymbol = symbolTable.getSymbol(TYPE_INFO_NAMESPACE, address, typeinfoNamespace);
Symbol vftableSymbol =
symbolTable.getSymbol(TYPE_INFO_NAMESPACE, address, typeinfoNamespace);
if (vftableSymbol != null) {
return;
}
@@ -57,6 +57,7 @@ public class BlockGraphTask extends Task {
private ColorizingService colorizingService;
private final static String ENTRY_NEXUS_NAME = "Entry Points";
private static final int MAX_SYMBOLS = 10;
private CodeBlockModel blockModel;
private AddressSetView selection;
private ProgramLocation location;
@@ -417,14 +418,20 @@ public class BlockGraphTask extends Task {
}
private void addSymbolAttribute(AttributedVertex vertex, CodeBlock bb) {
Symbol[] symbols = program.getSymbolTable().getSymbols(bb.getMinAddress());
if (symbols.length != 0) {
SymbolIterator it = program.getSymbolTable().getSymbolsAsIterator(bb.getMinAddress());
int count = 0;
if (it.hasNext()) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < symbols.length; i++) {
if (i != 0) {
for (Symbol symbol : it) {
if (count != 0) {
buf.append('\n');
}
buf.append(symbols[i].getName());
// limit the number of symbols to include (there can be a ridiculous # of symbols)
if (count++ > MAX_SYMBOLS) {
buf.append("...");
break;
}
buf.append(symbol.getName());
}
vertex.setAttribute(SYMBOLS_ATTRIBUTE, buf.toString());
}
@@ -15,8 +15,7 @@
*/
package ghidra.feature.vt.api.markuptype;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_LABELS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.LABELS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
import java.util.*;
@@ -232,10 +231,6 @@ public class LabelMarkupType extends VTMarkupType {
LabelMarkupUtils.removeAllLabels(getDestinationProgram(association),
destinationAddress);
}
else if (replaceDefault) {
LabelMarkupUtils.removeDefaultLabels(getDestinationProgram(association),
destinationAddress);
}
Program destinationProgram = getDestinationProgram(association);
try {
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,31 +23,15 @@ import ghidra.program.model.symbol.SymbolTable;
public class LabelMarkupUtils {
public static void removeDefaultLabels( Program destinationProgram, Address address ) {
SymbolTable symbolTable = destinationProgram.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols( address );
for ( Symbol symbol : symbols ) {
if ( symbol instanceof FunctionSymbol ) {
continue;
}
if ( !symbol.isDynamic() ) {
continue;
}
symbolTable.removeSymbolSpecial( symbol );
}
}
public static void removeAllLabels( Program destinationProgram, Address address ) {
SymbolTable symbolTable = destinationProgram.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols( address );
for ( Symbol symbol : symbols ) {
if ( symbol instanceof FunctionSymbol ) {
continue;
}
symbolTable.removeSymbolSpecial( symbol );
}
}
public static void removeAllLabels(Program destinationProgram, Address address) {
SymbolTable symbolTable = destinationProgram.getSymbolTable();
Symbol[] symbols = symbolTable.getSymbols(address);
for (Symbol symbol : symbols) {
if (symbol instanceof FunctionSymbol) {
continue;
}
symbolTable.removeSymbolSpecial(symbol);
}
}
}
@@ -401,7 +401,7 @@ public class NamespaceUtils {
return null;
}
Symbol[] symbols = program.getSymbolTable().getSymbols(address);
SymbolIterator symbols = program.getSymbolTable().getSymbolsAsIterator(address);
for (Symbol symbol : symbols) {
if (symbol.getSymbolType() == SymbolType.FUNCTION &&
symbolPath.matchesPathOf(symbol)) {
@@ -757,16 +757,14 @@ public class PseudoDisassembler {
for (Address flow : flows) {
// does this reference a valid function?
if (program != null) {
Symbol[] syms = program.getSymbolTable().getSymbols(flow);
for (Symbol sym : syms) {
if (sym.getSymbolType() == SymbolType.FUNCTION) {
didCallValidSubroutine = true;
break;
}
Symbol primary = program.getSymbolTable().getPrimarySymbol(flow);
if (primary.getSymbolType() == SymbolType.FUNCTION) {
didCallValidSubroutine = true;
}
}
// if respecting execute flag on memory, test to make sure we did flow into non-execute memory
if (respectExecuteFlag && !execSet.isEmpty() && !execSet.contains(flow)) {
if (respectExecuteFlag && !execSet.isEmpty() &&
!execSet.contains(flow)) {
if (!flow.isExternalAddress()) {
MemoryBlock block = memory.getBlock(flow);
// flowing into non-executable, but readable memory is bad
@@ -782,7 +780,9 @@ public class PseudoDisassembler {
target = newTarget;
}
}
catch (InsufficientBytesException e) {
catch (
InsufficientBytesException e) {
return false;
}
catch (UnknownInstructionException e) {
@@ -270,16 +270,21 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
try {
checkIsValid();
ReferenceManager rm = symbolMgr.getReferenceManager();
ReferenceIterator iter = rm.getReferencesTo(address);
boolean isPrimary = this.isPrimary();
Symbol[] symbols = symbolMgr.getSymbols(address);
if (symbols.length == 1) {
// if there is only one symbol, then all the references to this address count
if (hasExactlyOneSymbolAtAddress(address)) {
return rm.getReferenceCountTo(address);
}
// search through references and see which ones apply specifically to this symbol
ReferenceIterator iter = rm.getReferencesTo(address);
int count = 0;
boolean isPrimary = this.isPrimary();
while (iter.hasNext()) {
Reference ref = iter.next();
long symbolID = ref.getSymbolID();
// references refer to me if it matches my key or I'm primary and it doesn't
// specify a specific symbol id
if (symbolID == key || (isPrimary && symbolID < 0)) {
count++;
}
@@ -291,6 +296,15 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
}
}
private boolean hasExactlyOneSymbolAtAddress(Address addr) {
SymbolIterator it = symbolMgr.getSymbolsAsIterator(addr);
if (!it.hasNext()) {
return false;
}
it.next();
return !it.hasNext();
}
@Override
public Reference[] getReferences(TaskMonitor monitor) {
lock.acquire();
@@ -600,7 +600,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
if (sym.getSymbolType() == SymbolType.FUNCTION) {
Address addr = sym.getAddress();
Function f = (Function) sym.getObject();
Symbol nextPrimary = getNextPrimarySymbol(this, addr);
Symbol nextPrimary = findFirstNonPrimarySymbol(addr);
String name;
Namespace parentNamespace;
SourceType source;
@@ -636,20 +636,14 @@ public class SymbolManager implements SymbolTable, ManagerDB {
}
}
// @Override
// public boolean removeSymbol(Symbol sym) {
// return removeSymbolSpecial(sym);
// }
private Symbol getNextPrimarySymbol(SymbolManager sm, Address addr2) {
Symbol[] symbols = sm.getSymbols(addr2);
Symbol next = null;
for (int i = symbols.length - 1; i >= 0; i--) {
if (!symbols[i].isPrimary()) {
return symbols[i]; // For now return the last non-primary found.
private Symbol findFirstNonPrimarySymbol(Address address) {
SymbolIterator it = getSymbolsAsIterator(address);
for (Symbol symbol : it) {
if (!symbol.isPrimary()) {
return symbol; // return the first non-primary symbol we find
}
}
return next;
return null;
}
void removeChildren(SymbolDB sym) {
@@ -804,6 +798,21 @@ public class SymbolManager implements SymbolTable, ManagerDB {
return false;
}
public SymbolIterator getSymbolsAsIterator(Address addr) {
lock.acquire();
try {
RecordIterator iterator = adapter.getSymbols(addr, addr, true);
return new SymbolRecordIterator(iterator, true, true);
}
catch (IOException e) {
program.dbError(e);
}
finally {
lock.release();
}
return new SymbolRecordIterator(new EmptyRecordIterator(), true, true);
}
@Override
public Symbol[] getSymbols(Address addr) {
lock.acquire();
@@ -932,14 +941,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override
public Symbol getGlobalSymbol(String name, Address addr) {
Symbol[] symbols = getSymbols(addr);
for (Symbol symbol : symbols) {
// there can be only one global symbol with a name at an address
if (symbol.getName().equals(name) && symbol.isGlobal()) {
return symbol;
}
}
return null;
return getSymbol(name, addr, program.getGlobalNamespace());
}
@Override
@@ -1714,9 +1716,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
private void findNextDynamicSymbol() {
while (addrIt.hasNext()) {
Symbol[] symbols = getSymbols(addrIt.next());
if (symbols.length == 1 && symbols[0].isDynamic()) {
nextDynamicSymbol = symbols[0];
Symbol symbol = getPrimarySymbol(addrIt.next());
if (symbol != null && symbol.isDynamic()) {
nextDynamicSymbol = symbol;
return;
}
}
@@ -3062,28 +3064,3 @@ public class SymbolManager implements SymbolTable, ManagerDB {
return getFirstSymbol(name, namespace, s -> s.getSymbolType() == type);
}
}
class SymbolMatcher implements Predicate<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;
}
}
@@ -353,11 +353,26 @@ public interface SymbolTable {
* the primary symbol will be returned in array slot 0.
* WARNING! Use of this method with a Variable address is highly discouraged since
* a single Variable address could be used multiple times by many functions.
* Note that unless all the symbols are needed at once, you should consider using
* the {@link #getSymbolsAsIterator(Address)} method instead.
* @param addr the address at which to retrieve all symbols.
* @return a zero-length array when no symbols are defined at address.
* @see #getSymbolsAsIterator(Address)
*/
public Symbol[] getSymbols(Address addr);
/**
* Returns a symbol iterator over all the symbols at the given address. Use this instead of
* {@link #getSymbols(Address)} when you do not need to get all symbols, but rather are
* searching for a particular symbol. This method prevents all symbols at the given address
* from being loaded up front.
*
* @param addr the address at which to retrieve all symbols
* @return an iterator over all the symbols at the given address
* @see #getSymbols(Address)
*/
public SymbolIterator getSymbolsAsIterator(Address addr);
/**
* Returns an array of all user defined symbols at the given address
* @param addr the address at which to retrieve all user defined symbols.
@@ -1032,7 +1032,7 @@ public class SymbolUtilities {
if (namespace.isGlobal()) {
// do not add global symbol if same name already exists at address
for (Symbol s : program.getSymbolTable().getSymbols(address)) {
for (Symbol s : program.getSymbolTable().getSymbolsAsIterator(address)) {
if (name.equals(s.getName())) {
return null;
}