This is my first time writing Java code in years and I'm working on a Ghidra script that Maps system call symbols to their calling functions.
private HashMap<Symbol, Reference[]> symbolRefs = new HashMap<Symbol, Reference[]>();
private HashMap<Symbol, List<Function>> callerFuncs = new HashMap<Symbol, List<Function>>();
.
.
.
private void mapSysCallToCallerFunctions(FunctionManager funcMan) throws Exception {
List<Function> funcs = new ArrayList<Function>();
for(HashMap.Entry<Symbol, Reference[]> entry: this.symbolRefs.entrySet()) {
for(Reference ref : entry.getValue()) {
Function caller = funcMan.getFunctionContaining(ref.getFromAddress());
if(caller != null) {
funcs.add(caller);
}
}
this.callerFuncs.put(entry.getKey(), funcs);
funcs.clear();
}
}
My problem is that I want to clear the "funcs" list, so that I can use the empty list again for the next iteration. This causes the Function List in my HashMap to be empty, too, for some unknown reason. If I print my HashMap here:
private void printCallerSymbolMap() throws Exception {
for(HashMap.Entry<Symbol, List<Function>> entry: this.callerFuncs.entrySet()) {
printf("Symbol %s:\n", entry.getKey().toString());
for(Function func : entry.getValue()) {
printf("Called by function %s\n", func.getName());
}
}
}
I just get the output:
INFO Symbol system: (GhidraScript)
INFO Symbol system: (GhidraScript)
However, when I remove funcs.clear(), I get:
INFO Symbol system: (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Called by function main (GhidraScript)
INFO Symbol system: (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Called by function main (GhidraScript)
It should be like that though:
INFO Symbol system: (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Called by function system (GhidraScript)
INFO Symbol system: (GhidraScript)
INFO Called by function main (GhidraScript)
I have two system symbols as it is thunked.
Insted of clearing list, initialize the list every time.
private void mapSysCallToCallerFunctions(FunctionManager funcMan) throws Exception {
List<Function> funcs;
for(HashMap.Entry<Symbol, Reference[]> entry: this.symbolRefs.entrySet()) {
funcs = new ArrayList<Function>();
for(Reference ref : entry.getValue()) {
Function caller = funcMan.getFunctionContaining(ref.getFromAddress());
if(caller != null) {
funcs.add(caller);
}
}
this.callerFuncs.put(entry.getKey(), funcs);
}
}