GP-1921 corrected analysisMode usage in recover class script

This commit is contained in:
ghidra007 2022-10-13 14:54:30 +00:00
parent 11ceae4cae
commit c4f4208f63

View file

@ -54,11 +54,20 @@
import java.io.File; import java.io.File;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import classrecovery.*; import classrecovery.DecompilerScriptUtils;
import classrecovery.RTTIClassRecoverer;
import classrecovery.RTTIGccClassRecoverer;
import classrecovery.RTTIWindowsClassRecoverer;
import classrecovery.RecoveredClass;
import classrecovery.RecoveredClassHelper;
import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompInterface;
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
import ghidra.app.plugin.core.analysis.DecompilerFunctionAnalyzer; import ghidra.app.plugin.core.analysis.DecompilerFunctionAnalyzer;
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.app.services.Analyzer; import ghidra.app.services.Analyzer;
@ -72,11 +81,28 @@ import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.ElfLoader; import ghidra.app.util.opinion.ElfLoader;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.address.AddressSet;
import ghidra.program.model.listing.*; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.Structure;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Parameter;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryBlock;
import ghidra.service.graph.*; import ghidra.service.graph.AttributedEdge;
import ghidra.service.graph.AttributedGraph;
import ghidra.service.graph.AttributedVertex;
import ghidra.service.graph.GraphDisplay;
import ghidra.service.graph.GraphDisplayOptions;
import ghidra.service.graph.GraphDisplayOptionsBuilder;
import ghidra.service.graph.GraphDisplayProvider;
import ghidra.service.graph.GraphType;
import ghidra.service.graph.GraphTypeBuilder;
import ghidra.service.graph.VertexShape;
import ghidra.util.WebColors; import ghidra.util.WebColors;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.GraphException; import ghidra.util.exception.GraphException;
@ -152,6 +178,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
boolean nameVfunctions = false; boolean nameVfunctions = false;
AnalysisMode analysisMode = AnalysisMode.SUSPENDED;
@Override @Override
public void run() throws Exception { public void run() throws Exception {
@ -243,8 +271,13 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
"Checking for missing RTTI information and undefined constructor/destructor functions and creating if possible " + "Checking for missing RTTI information and undefined constructor/destructor functions and creating if possible " +
"to find entry point..."); "to find entry point...");
AddressSetView beforeScriptChanges = currentProgram.getChanges().getAddressSet(); AddressSetView beforeScriptChanges = currentProgram.getChanges().getAddressSet();
analysisMode = AnalysisMode.ENABLED;
recoverClassesFromRTTI.fixUpProgram(); recoverClassesFromRTTI.fixUpProgram();
analyzeProgramChanges(beforeScriptChanges); analyzeProgramChanges(beforeScriptChanges);
analysisMode = AnalysisMode.SUSPENDED;
} }
println("Recovering classes using RTTI..."); println("Recovering classes using RTTI...");
@ -365,10 +398,16 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
@Override @Override
public AnalysisMode getScriptAnalysisMode() { public AnalysisMode getScriptAnalysisMode() {
return AnalysisMode.SUSPENDED; return analysisMode;
} }
@Override
public void analyzeChanges(Program program) {
AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager(program);
mgr.startAnalysis(monitor, false);
}
/** /**
* Method to create a class hierarchy graph where the parents are at the top of the graph and * Method to create a class hierarchy graph where the parents are at the top of the graph and
@ -393,12 +432,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
AttributedGraph g = new AttributedGraph("Recovered Classes Graph", graphType); AttributedGraph g = new AttributedGraph("Recovered Classes Graph", graphType);
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
AttributedVertex classVertex = AttributedVertex classVertex =
g.addVertex(recoveredClass.getClassPath().getPath(), recoveredClass.getName()); g.addVertex(recoveredClass.getClassPath().getPath(), recoveredClass.getName());
@ -428,11 +464,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
Map<RecoveredClass, Boolean> parentToBaseTypeMap = Map<RecoveredClass, Boolean> parentToBaseTypeMap =
recoveredClass.getParentToBaseTypeMap(); recoveredClass.getParentToBaseTypeMap();
Iterator<RecoveredClass> parentIterator = parents.iterator(); for (RecoveredClass parent : parents) {
while (parentIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass parent = parentIterator.next();
AttributedVertex parentVertex = AttributedVertex parentVertex =
g.addVertex(parent.getClassPath().getPath(), parent.getName()); g.addVertex(parent.getClassPath().getPath(), parent.getName());
@ -505,17 +538,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void printClassHierarchyLists(List<RecoveredClass> recoveredClasses) private void printClassHierarchyLists(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
List<RecoveredClass> classHierarchyList = recoveredClass.getClassHierarchy(); List<RecoveredClass> classHierarchyList = recoveredClass.getClassHierarchy();
Iterator<RecoveredClass> classHierarchyIterator = classHierarchyList.iterator(); for (RecoveredClass currentClass : classHierarchyList) {
while (classHierarchyIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass currentClass = classHierarchyIterator.next();
println(currentClass.getName()); println(currentClass.getName());
} }
@ -688,12 +716,10 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
} }
// otherwise have to split into various lines for the multiple parents // otherwise have to split into various lines for the multiple parents
else { else {
Iterator<RecoveredClass> parentIterator = classHierarchyMap.keySet().iterator();
stringBuffer.append(" : "); stringBuffer.append(" : ");
int lastColon = stringBuffer.lastIndexOf(":"); int lastColon = stringBuffer.lastIndexOf(":");
while (parentIterator.hasNext()) { for (RecoveredClass parentClass : classHierarchyMap.keySet()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass parentClass = parentIterator.next();
if (classHierarchyMap.size() == 1) { if (classHierarchyMap.size() == 1) {
//stringBuffer.append(" : "); //stringBuffer.append(" : ");
getSimpleClassHierarchyString(stringBuffer, parentClass); getSimpleClassHierarchyString(stringBuffer, parentClass);
@ -749,11 +775,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void bookmarkConstructors(List<RecoveredClass> recoveredClasses) private void bookmarkConstructors(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassesIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassesIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassesIterator.next();
bookmarkFunctionsOnList(recoveredClass.getConstructorList(), CONSTRUCTOR_BOOKMARK); bookmarkFunctionsOnList(recoveredClass.getConstructorList(), CONSTRUCTOR_BOOKMARK);
} }
} }
@ -766,11 +789,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void bookmarkDestructors(List<RecoveredClass> recoveredClasses) private void bookmarkDestructors(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassesIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassesIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassesIterator.next();
bookmarkFunctionsOnList(recoveredClass.getDestructorList(), DESTRUCTOR_BOOKMARK); bookmarkFunctionsOnList(recoveredClass.getDestructorList(), DESTRUCTOR_BOOKMARK);
bookmarkFunctionsOnList(recoveredClass.getNonThisDestructors(), DESTRUCTOR_BOOKMARK); bookmarkFunctionsOnList(recoveredClass.getNonThisDestructors(), DESTRUCTOR_BOOKMARK);
} }
@ -784,12 +804,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void bookmarkRemainingIndeterminateConstructorsAndDestructors( private void bookmarkRemainingIndeterminateConstructorsAndDestructors(
List<RecoveredClass> recoveredClasses) throws CancelledException { List<RecoveredClass> recoveredClasses) throws CancelledException {
Iterator<RecoveredClass> recoveredClassesIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassesIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassesIterator.next();
bookmarkFunctionsOnList(recoveredClass.getIndeterminateList(), INDETERMINATE_BOOKMARK); bookmarkFunctionsOnList(recoveredClass.getIndeterminateList(), INDETERMINATE_BOOKMARK);
} }
} }
@ -808,10 +824,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
return; return;
} }
Iterator<Function> functionIterator = functions.iterator(); for (Function function : functions) {
while (functionIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function function = functionIterator.next();
Address address = function.getEntryPoint(); Address address = function.getEntryPoint();
recoverClassesFromRTTI.bookmarkAddress(address, comment); recoverClassesFromRTTI.bookmarkAddress(address, comment);
} }
@ -872,11 +886,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
*/ */
private void printClassDefinitions(List<RecoveredClass> recoveredClasses) private void printClassDefinitions(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasParentClass()) { if (!recoveredClass.hasParentClass()) {
println(createClassDefinitionString(recoveredClass).toString()); println(createClassDefinitionString(recoveredClass).toString());
} }
@ -886,11 +897,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void outputClassDefinitions(List<RecoveredClass> recoveredClasses, PrintWriter out) private void outputClassDefinitions(List<RecoveredClass> recoveredClasses, PrintWriter out)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasParentClass()) { if (!recoveredClass.hasParentClass()) {
out.append(createClassDefinitionString(recoveredClass)); out.append(createClassDefinitionString(recoveredClass));
} }
@ -906,11 +914,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
* @throws CancelledException if cancelled * @throws CancelledException if cancelled
*/ */
private void printClassInfo(List<RecoveredClass> recoveredClasses) throws CancelledException { private void printClassInfo(List<RecoveredClass> recoveredClasses) throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasParentClass()) { if (!recoveredClass.hasParentClass()) {
println(createClassInfoString(recoveredClass).toString()); println(createClassInfoString(recoveredClass).toString());
} }
@ -919,18 +924,13 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void printClassParents(List<RecoveredClass> recoveredClasses) private void printClassParents(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
String printString = new String("\n" + recoveredClass.getName() + "\n"); String printString = new String("\n" + recoveredClass.getName() + "\n");
if (recoveredClass.hasParentClass()) { if (recoveredClass.hasParentClass()) {
List<RecoveredClass> parentList = recoveredClass.getParentList(); List<RecoveredClass> parentList = recoveredClass.getParentList();
Iterator<RecoveredClass> parentIterator = parentList.iterator(); for (RecoveredClass parent : parentList) {
while (parentIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass parent = parentIterator.next();
printString = printString.concat("\t" + parent.getName() + "\n"); printString = printString.concat("\t" + parent.getName() + "\n");
} }
} }
@ -950,12 +950,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
StringBuffer wholeBuffer = new StringBuffer(); StringBuffer wholeBuffer = new StringBuffer();
wholeBuffer.append("\r\n"); wholeBuffer.append("\r\n");
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasChildClass()) { if (!recoveredClass.hasChildClass()) {
StringBuffer stringBuffer = new StringBuffer(); StringBuffer stringBuffer = new StringBuffer();
@ -981,11 +977,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
StringBuffer wholeBuffer = new StringBuffer(); StringBuffer wholeBuffer = new StringBuffer();
wholeBuffer.append("\r\n"); wholeBuffer.append("\r\n");
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasChildClass()) { if (!recoveredClass.hasChildClass()) {
StringBuffer stringBuffer = new StringBuffer(); StringBuffer stringBuffer = new StringBuffer();
wholeBuffer.append( wholeBuffer.append(
@ -1005,11 +998,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void outputClassInfo(List<RecoveredClass> recoveredClasses, PrintWriter out) private void outputClassInfo(List<RecoveredClass> recoveredClasses, PrintWriter out)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
if (!recoveredClass.hasParentClass()) { if (!recoveredClass.hasParentClass()) {
out.append(createClassInfoString(recoveredClass).toString()); out.append(createClassInfoString(recoveredClass).toString());
} }
@ -1071,10 +1061,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
throws CancelledException { throws CancelledException {
int total = 0; int total = 0;
Iterator<RecoveredClass> classIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (classIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = classIterator.next();
List<Function> constructorList = recoveredClass.getConstructorOrDestructorFunctions(); List<Function> constructorList = recoveredClass.getConstructorOrDestructorFunctions();
total += constructorList.size(); total += constructorList.size();
} }
@ -1091,10 +1079,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
throws CancelledException { throws CancelledException {
int total = 0; int total = 0;
Iterator<RecoveredClass> classIterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (classIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = classIterator.next();
List<Function> inlineList = recoveredClass.getInlinedConstructorList(); List<Function> inlineList = recoveredClass.getInlinedConstructorList();
total += inlineList.size(); total += inlineList.size();
} }
@ -1107,10 +1093,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
* @throws CancelledException if cancelled * @throws CancelledException if cancelled
*/ */
private void printAddresses(List<Address> addresses) throws CancelledException { private void printAddresses(List<Address> addresses) throws CancelledException {
Iterator<Address> iterator = addresses.iterator(); for (Address element : addresses) {
while (iterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
println(iterator.next().toString()); println(element.toString());
} }
} }
@ -1124,10 +1109,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void outputClassParentsAndChildren(List<RecoveredClass> recoveredClasses, private void outputClassParentsAndChildren(List<RecoveredClass> recoveredClasses,
PrintWriter out) throws CancelledException { PrintWriter out) throws CancelledException {
Iterator<RecoveredClass> iterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (iterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = iterator.next();
out.append(printClassParentsandChildren(recoveredClass)); out.append(printClassParentsandChildren(recoveredClass));
} }
} }
@ -1140,10 +1123,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
private void printClassesParentsAndChilren(List<RecoveredClass> recoveredClasses) private void printClassesParentsAndChilren(List<RecoveredClass> recoveredClasses)
throws CancelledException { throws CancelledException {
Iterator<RecoveredClass> iterator = recoveredClasses.iterator(); for (RecoveredClass recoveredClass : recoveredClasses) {
while (iterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass recoveredClass = iterator.next();
println(printClassParentsandChildren(recoveredClass).toString()); println(printClassParentsandChildren(recoveredClass).toString());
} }
} }
@ -1167,10 +1148,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
stringBuffer.append("parent class(es):\r\n"); stringBuffer.append("parent class(es):\r\n");
if (recoveredClass.hasParentClass()) { if (recoveredClass.hasParentClass()) {
Set<RecoveredClass> keySet = recoveredClass.getClassHierarchyMap().keySet(); Set<RecoveredClass> keySet = recoveredClass.getClassHierarchyMap().keySet();
Iterator<RecoveredClass> parentIterator = keySet.iterator(); for (RecoveredClass parent : keySet) {
while (parentIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass parent = parentIterator.next();
stringBuffer.append("\t" + parent.getName() + "\r\n"); stringBuffer.append("\t" + parent.getName() + "\r\n");
} }
} }
@ -1180,10 +1159,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
stringBuffer.append("child class(es):\r\n"); stringBuffer.append("child class(es):\r\n");
if (recoveredClass.hasChildClass()) { if (recoveredClass.hasChildClass()) {
List<RecoveredClass> childClasses = recoveredClass.getChildClasses(); List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
Iterator<RecoveredClass> childClassIterator = childClasses.iterator(); for (RecoveredClass element : childClasses) {
while (childClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
stringBuffer.append("\t" + childClassIterator.next().getName() + "\r\n"); stringBuffer.append("\t" + element.getName() + "\r\n");
} }
} }
@ -1221,10 +1199,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
Map<RecoveredClass, Boolean> parentToBaseTypeMap = Map<RecoveredClass, Boolean> parentToBaseTypeMap =
recoveredClass.getParentToBaseTypeMap(); recoveredClass.getParentToBaseTypeMap();
Set<RecoveredClass> ancestors = parentToBaseTypeMap.keySet(); Set<RecoveredClass> ancestors = parentToBaseTypeMap.keySet();
Iterator<RecoveredClass> ancestorIterator = ancestors.iterator(); for (RecoveredClass ancestor : ancestors) {
while (ancestorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
RecoveredClass ancestor = ancestorIterator.next();
if (directParents.contains(ancestor)) { if (directParents.contains(ancestor)) {
Boolean isVirtualParent = parentToBaseTypeMap.get(ancestor); Boolean isVirtualParent = parentToBaseTypeMap.get(ancestor);
@ -1249,10 +1225,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
stringBuffer.append("child class(es):\r\n"); stringBuffer.append("child class(es):\r\n");
if (recoveredClass.hasChildClass()) { if (recoveredClass.hasChildClass()) {
List<RecoveredClass> childClasses = recoveredClass.getChildClasses(); List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
Iterator<RecoveredClass> childClassIterator = childClasses.iterator(); for (RecoveredClass element : childClasses) {
while (childClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
stringBuffer.append("\t" + childClassIterator.next().getName() + "\r\n"); stringBuffer.append("\t" + element.getName() + "\r\n");
} }
} }
@ -1261,10 +1236,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print constructors // print constructors
stringBuffer.append("constructor(s):\r\n"); stringBuffer.append("constructor(s):\r\n");
List<Function> constructorList = recoveredClass.getConstructorList(); List<Function> constructorList = recoveredClass.getConstructorList();
Iterator<Function> constructorIterator = constructorList.iterator(); for (Function constructorFunction : constructorList) {
while (constructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function constructorFunction = constructorIterator.next();
stringBuffer.append("\t" + constructorFunction.getName() + " " + stringBuffer.append("\t" + constructorFunction.getName() + " " +
constructorFunction.getEntryPoint().toString() + "\r\n"); constructorFunction.getEntryPoint().toString() + "\r\n");
} }
@ -1274,10 +1247,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
List<Function> inlinedConstructorList = recoveredClass.getInlinedConstructorList(); List<Function> inlinedConstructorList = recoveredClass.getInlinedConstructorList();
if (inlinedConstructorList.size() > 0) { if (inlinedConstructorList.size() > 0) {
stringBuffer.append("inlined constructor(s):\r\n"); stringBuffer.append("inlined constructor(s):\r\n");
Iterator<Function> inlinedConstructorIterator = inlinedConstructorList.iterator(); for (Function inlinedConstructorFunction : inlinedConstructorList) {
while (inlinedConstructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function inlinedConstructorFunction = inlinedConstructorIterator.next();
stringBuffer.append("\t" + inlinedConstructorFunction.getName() + " " + stringBuffer.append("\t" + inlinedConstructorFunction.getName() + " " +
inlinedConstructorFunction.getEntryPoint().toString() + "\r\n"); inlinedConstructorFunction.getEntryPoint().toString() + "\r\n");
} }
@ -1287,10 +1258,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print destructors // print destructors
stringBuffer.append("destructor(s):\r\n"); stringBuffer.append("destructor(s):\r\n");
List<Function> destructorList = recoveredClass.getDestructorList(); List<Function> destructorList = recoveredClass.getDestructorList();
Iterator<Function> destructorIterator = destructorList.iterator(); for (Function destructorFunction : destructorList) {
while (destructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function destructorFunction = destructorIterator.next();
stringBuffer.append("\t" + destructorFunction.getName() + " " + stringBuffer.append("\t" + destructorFunction.getName() + " " +
destructorFunction.getEntryPoint().toString() + "\r\n"); destructorFunction.getEntryPoint().toString() + "\r\n");
} }
@ -1300,10 +1269,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
List<Function> inlinedDestructorList = recoveredClass.getInlinedDestructorList(); List<Function> inlinedDestructorList = recoveredClass.getInlinedDestructorList();
if (inlinedDestructorList.size() > 0) { if (inlinedDestructorList.size() > 0) {
stringBuffer.append("inlined destructor(s):\r\n"); stringBuffer.append("inlined destructor(s):\r\n");
Iterator<Function> inlinedDestructorIterator = inlinedDestructorList.iterator(); for (Function inlinedDestructorFunction : inlinedDestructorList) {
while (inlinedDestructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function inlinedDestructorFunction = inlinedDestructorIterator.next();
stringBuffer.append("\t" + inlinedDestructorFunction.getName() + " " + stringBuffer.append("\t" + inlinedDestructorFunction.getName() + " " +
inlinedDestructorFunction.getEntryPoint().toString() + "\r\n"); inlinedDestructorFunction.getEntryPoint().toString() + "\r\n");
} }
@ -1313,10 +1280,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
List<Function> indeterminateList = recoveredClass.getIndeterminateList(); List<Function> indeterminateList = recoveredClass.getIndeterminateList();
if (indeterminateList.size() > 0) { if (indeterminateList.size() > 0) {
stringBuffer.append("\r\nindeterminate constructor(s) or destructor(s):\r\n"); stringBuffer.append("\r\nindeterminate constructor(s) or destructor(s):\r\n");
Iterator<Function> indeterminateIterator = indeterminateList.iterator(); for (Function indeterminateFunction : indeterminateList) {
while (indeterminateIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function indeterminateFunction = indeterminateIterator.next();
stringBuffer.append("\t" + indeterminateFunction.getName() + " " + stringBuffer.append("\t" + indeterminateFunction.getName() + " " +
indeterminateFunction.getEntryPoint().toString() + "\r\n"); indeterminateFunction.getEntryPoint().toString() + "\r\n");
} }
@ -1327,11 +1292,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print virtual function signatures // print virtual function signatures
stringBuffer.append("member function(s):\r\n"); stringBuffer.append("member function(s):\r\n");
List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions(); List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions();
//List<Function> dedupedVirtualFunctions = removeDuplicateFunctions(virtualFunctions); for (Function vfunction : virtualFunctions) {
Iterator<Function> vfunctionIter = virtualFunctions.iterator();
while (vfunctionIter.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function vfunction = vfunctionIter.next();
stringBuffer.append("\t" + vfunction.getName() + " " + stringBuffer.append("\t" + vfunction.getName() + " " +
vfunction.getEntryPoint().toString() + "\r\n"); vfunction.getEntryPoint().toString() + "\r\n");
} }
@ -1361,10 +1323,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// Then recursively process the child classes // Then recursively process the child classes
if (recoveredClass.hasChildClass()) { if (recoveredClass.hasChildClass()) {
List<RecoveredClass> childClasses = recoveredClass.getChildClasses(); List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
Iterator<RecoveredClass> childClassIterator = childClasses.iterator(); for (RecoveredClass element : childClasses) {
while (childClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
stringBuffer.append(createClassInfoString(childClassIterator.next())); stringBuffer.append(createClassInfoString(element));
} }
} }
@ -1448,10 +1409,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print constructor signature(s) // print constructor signature(s)
stringBuffer.append("constructor(s):\r\n"); stringBuffer.append("constructor(s):\r\n");
List<Function> constructorList = recoveredClass.getConstructorList(); List<Function> constructorList = recoveredClass.getConstructorList();
Iterator<Function> constructorIterator = constructorList.iterator(); for (Function constructorFunction : constructorList) {
while (constructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function constructorFunction = constructorIterator.next();
String functionSignatureString = String functionSignatureString =
getFunctionSignatureString(constructorFunction, true); getFunctionSignatureString(constructorFunction, true);
@ -1462,10 +1421,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print destructor signature // print destructor signature
stringBuffer.append("\r\ndestructor(s):\r\n"); stringBuffer.append("\r\ndestructor(s):\r\n");
List<Function> destructorList = recoveredClass.getDestructorList(); List<Function> destructorList = recoveredClass.getDestructorList();
Iterator<Function> destructorIterator = destructorList.iterator(); for (Function destructorFunction : destructorList) {
while (destructorIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function destructorFunction = destructorIterator.next();
String functionSignatureString = String functionSignatureString =
getFunctionSignatureString(destructorFunction, true); getFunctionSignatureString(destructorFunction, true);
stringBuffer.append(functionSignatureString); stringBuffer.append(functionSignatureString);
@ -1476,10 +1433,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
List<Function> indeterminateList = recoveredClass.getIndeterminateList(); List<Function> indeterminateList = recoveredClass.getIndeterminateList();
if (indeterminateList.size() > 0) { if (indeterminateList.size() > 0) {
stringBuffer.append("\r\nindeterminate constructor or destructor function(s):\r\n"); stringBuffer.append("\r\nindeterminate constructor or destructor function(s):\r\n");
Iterator<Function> indeterminateIterator = indeterminateList.iterator(); for (Function indeterminateFunction : indeterminateList) {
while (indeterminateIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function indeterminateFunction = indeterminateIterator.next();
String functionSignatureString = String functionSignatureString =
getFunctionSignatureString(indeterminateFunction, true); getFunctionSignatureString(indeterminateFunction, true);
stringBuffer.append(functionSignatureString); stringBuffer.append(functionSignatureString);
@ -1490,10 +1445,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// print virtual function signature(s) // print virtual function signature(s)
stringBuffer.append("\r\nmember function(s):\r\n"); stringBuffer.append("\r\nmember function(s):\r\n");
List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions(); List<Function> virtualFunctions = recoveredClass.getAllVirtualFunctions();
Iterator<Function> vfunctionIter = virtualFunctions.iterator(); for (Function vfunction : virtualFunctions) {
while (vfunctionIter.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
Function vfunction = vfunctionIter.next();
String functionSignatureString = String functionSignatureString =
getFunctionSignatureString(vfunction, true); getFunctionSignatureString(vfunction, true);
stringBuffer.append(functionSignatureString); stringBuffer.append(functionSignatureString);
@ -1525,10 +1478,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// Then recursively process the child classes // Then recursively process the child classes
if (recoveredClass.hasChildClass()) { if (recoveredClass.hasChildClass()) {
List<RecoveredClass> childClasses = recoveredClass.getChildClasses(); List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
Iterator<RecoveredClass> childClassIterator = childClasses.iterator(); for (RecoveredClass element : childClasses) {
while (childClassIterator.hasNext()) {
monitor.checkCanceled(); monitor.checkCanceled();
stringBuffer.append(createClassDefinitionString(childClassIterator.next())); stringBuffer.append(createClassDefinitionString(element));
} }
} }