mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-1073 updating uses of getSymbols(address) to be more efficient where possible
This commit is contained in:
parent
e2ea7320e1
commit
a8da2b761a
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
|
@Override
|
||||||
public Symbol[] getUserSymbols(Address addr) {
|
public Symbol[] getUserSymbols(Address addr) {
|
||||||
try (LockHold hold = program.trace.lockRead()) {
|
try (LockHold hold = program.trace.lockRead()) {
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -53,9 +53,8 @@ public class AutoRenameLabelsScript extends GhidraScript {
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7520,11 +7518,13 @@ 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 =
|
||||||
|
updateListingVfunctionSignature(data, vfunctionComponent, vftableAddress);
|
||||||
if (changedItem != null && !changedItems.contains(changedItem)) {
|
if (changedItem != null && !changedItems.contains(changedItem)) {
|
||||||
changedItems.add(changedItem);
|
changedItems.add(changedItem);
|
||||||
|
|
||||||
FunctionDefinition newFunctionDefinition = getComponentFunctionDefinition(vfunctionComponent);
|
FunctionDefinition newFunctionDefinition =
|
||||||
|
getComponentFunctionDefinition(vfunctionComponent);
|
||||||
if (newFunctionDefinition == null) {
|
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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -155,7 +156,8 @@ public class FidStatistics extends GhidraScript {
|
||||||
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);
|
||||||
|
@ -234,7 +236,8 @@ public class FidStatistics extends GhidraScript {
|
||||||
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");
|
||||||
|
@ -248,15 +251,20 @@ public class FidStatistics extends GhidraScript {
|
||||||
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");
|
||||||
|
@ -265,25 +273,31 @@ public class FidStatistics extends GhidraScript {
|
||||||
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",
|
||||||
|
"?CopyCharsOverlapped@?$CSimpleStringT@_W$0A@@ATL@@SAXPA_WIPB_WH@Z");
|
||||||
addEquivSymbols("?StringCbCopyA@@YGJPADIPBD@Z", "_StringCbCopyA@12");
|
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",
|
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");
|
||||||
|
@ -299,26 +313,34 @@ public class FidStatistics extends GhidraScript {
|
||||||
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",
|
||||||
|
"?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("??$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",
|
||||||
|
"??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ");
|
||||||
addEquivSymbols("?IsEqualGUID@@YAHAEBU_GUID@@0@Z", "IsEqualGUID");
|
addEquivSymbols("?IsEqualGUID@@YAHAEBU_GUID@@0@Z", "IsEqualGUID");
|
||||||
addEquivSymbols("??1?$CAtlSafeAllocBufferManager@V_CCRTAllocator@_ATL_SAFE_ALLOCA_IMPL@ATL@@@_ATL_SAFE_ALLOCA_IMPL@ATL@@QEAA@XZ",
|
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",
|
||||||
|
"??_G_Locimp@locale@std@@MEAAPEAXI@Z");
|
||||||
addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z", "StringCchCopyW");
|
addEquivSymbols("?StringCchCopyW@@YAJPEAG_KPEBG@Z", "StringCchCopyW");
|
||||||
addEquivSymbols("StringCchPrintfA", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ");
|
addEquivSymbols("StringCchPrintfA", "?StringCbPrintfA@@YAJPEAD_KPEBDZZ");
|
||||||
addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA");
|
addEquivSymbols("?StringCchCatA@@YAJPEAD_KPEBD@Z", "StringCchCatA");
|
||||||
|
@ -329,7 +351,8 @@ public class FidStatistics extends GhidraScript {
|
||||||
addEquivSymbols("WPP_SF_ii", "WPP_SF_qq");
|
addEquivSymbols("WPP_SF_ii", "WPP_SF_qq");
|
||||||
addEquivSymbols("WPP_SF_DDDDD", "WPP_SF_ddddd");
|
addEquivSymbols("WPP_SF_DDDDD", "WPP_SF_ddddd");
|
||||||
addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z", "FDIDestroy");
|
addEquivSymbols("?FDIDestroy@@$$J0YAHPEAX@Z", "FDIDestroy");
|
||||||
addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ","??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ");
|
addEquivSymbols("??1?$CTempBuffer@G$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ",
|
||||||
|
"??1?$CTempBuffer@D$0IA@VCCRTAllocator@ATL@@@ATL@@QEAA@XZ");
|
||||||
addEquivSymbols("WPP_SF_xx", "WPP_SF_qq");
|
addEquivSymbols("WPP_SF_xx", "WPP_SF_qq");
|
||||||
addEquivSymbols("WPP_SF_iii", "WPP_SF_qqq");
|
addEquivSymbols("WPP_SF_iii", "WPP_SF_qqq");
|
||||||
addEquivSymbols("RtlStringCchCopyW", "StringCchCopyW");
|
addEquivSymbols("RtlStringCchCopyW", "StringCchCopyW");
|
||||||
|
@ -369,14 +392,13 @@ public class FidStatistics extends GhidraScript {
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +503,8 @@ public class FidStatistics extends GhidraScript {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processProgram(Program program,FidQueryService queryService) throws MemoryAccessException, CancelledException, VersionException, IOException {
|
private void processProgram(Program program, FidQueryService queryService)
|
||||||
|
throws MemoryAccessException, CancelledException, VersionException, IOException {
|
||||||
FidProgramSeeker programSeeker = service.getProgramSeeker(program, queryService, 10.0f);
|
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());
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,22 +23,6 @@ import ghidra.program.model.symbol.SymbolTable;
|
||||||
|
|
||||||
public class LabelMarkupUtils {
|
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) {
|
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);
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue