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