diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java index 555dfec4b0..f24230306d 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java @@ -111,7 +111,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { TaskMonitor monitor) throws Exception { super(program, serviceProvider, api, createBookmarks, useShortTemplates, nameVfunctions, - makeVfunctionsThisCalls,isDwarfLoaded, monitor); + makeVfunctionsThisCalls, isDwarfLoaded, monitor); this.isDwarfLoaded = isDwarfLoaded; @@ -213,6 +213,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { Msg.debug(this, "Processing constructors and destructors"); processConstructorAndDestructors(); + identifyPureVirtualFunction(recoveredClasses); + Msg.debug(this, "Creating vftable order maps"); createVftableOrderMap(recoveredClasses); diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java index 1231e4039b..1d32ee1009 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java @@ -4505,7 +4505,7 @@ public class RecoveredClassHelper { // if the function is a purecall need to create the function definition using // the equivalent child virtual function signature - if (nameField.contains("purecall")) { + if (nameField.contains("purecall") || nameField.contains("pure_virtual")) { nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber; @@ -4583,15 +4583,11 @@ public class RecoveredClassHelper { List
processedVftables = new ArrayList
(); // get references to purecall function to figure out which classes to process - ReferenceIterator purecallRefs = - program.getReferenceManager().getReferencesTo(purecall.getEntryPoint()); + HashSet
purecallRefs = getPurecallRefs(); - while (purecallRefs.hasNext()) { + for (Address fromAddress : purecallRefs) { monitor.checkCancelled(); - Reference purecallRef = purecallRefs.next(); - Address fromAddress = purecallRef.getFromAddress(); - // get data containing the purecall reference to get the vftable structure Data data = program.getListing().getDataContaining(fromAddress); @@ -4662,6 +4658,33 @@ public class RecoveredClassHelper { } + // get references to purecall function to figure out which classes to process + HashSet
getPurecallRefs() throws CancelledException { + + HashSet
purecalls = new HashSet<>(); + ReferenceIterator purecallRefs = + program.getReferenceManager().getReferencesTo(purecall.getEntryPoint()); + + while (purecallRefs.hasNext()) { + monitor.checkCancelled(); + purecalls.add(purecallRefs.next().getFromAddress()); + } + + Address[] functionThunkAddresses = purecall.getFunctionThunkAddresses(true); + if (functionThunkAddresses != null) { + for (Address purecallThunk : functionThunkAddresses) { + monitor.checkCancelled(); + purecallRefs = + program.getReferenceManager().getReferencesTo(purecallThunk); + while (purecallRefs.hasNext()) { + monitor.checkCancelled(); + purecalls.add(purecallRefs.next().getFromAddress()); + } + } + } + return purecalls; + } + /** * Method to get a child class virtual function at the given offset into the correct virtual function table * @param recoveredClass the given class