mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-05 06:32:34 +02:00
GP-4408 Refactor of FillOutStructureCmd. Added FillOutStructureHelper and additional DecompilerUtils methods.
This commit is contained in:
@@ -16,56 +16,26 @@
|
||||
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
|
||||
package classrecovery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd;
|
||||
import ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd.OffsetPcodeOpPair;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.component.DecompilerUtils;
|
||||
import ghidra.app.decompiler.util.FillOutStructureHelper;
|
||||
import ghidra.app.decompiler.util.FillOutStructureHelper.OffsetPcodeOpPair;
|
||||
import ghidra.app.util.opinion.PeLoader;
|
||||
import ghidra.app.util.opinion.PeLoader.CompilerOpinion.CompilerEnum;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.flatapi.FlatProgramAPI;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.Category;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeConflictHandler;
|
||||
import ghidra.program.model.data.IntegerDataType;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.program.model.listing.CircularDependencyException;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.FlowOverride;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.HighVariable;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.SymbolType;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
@@ -85,7 +55,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
private static final String RTTI_CLASS_HIERARCHY_DESCRIPTOR_DATA_NAME =
|
||||
"RTTIClassHierarchyDescriptor";
|
||||
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_PTR_FIELD_EXT = "vftablePtr";
|
||||
@@ -102,15 +72,14 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
boolean isPDBLoaded;
|
||||
|
||||
public RTTIWindowsClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
||||
public RTTIWindowsClassRecoverer(Program program, ServiceProvider serviceProvider,
|
||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||
boolean nameVFunctions, boolean isPDBLoaded, TaskMonitor monitor) throws Exception {
|
||||
|
||||
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
|
||||
super(program, serviceProvider, api, createBookmarks, useShortTemplates, nameVFunctions,
|
||||
isPDBLoaded, monitor);
|
||||
|
||||
this.isPDBLoaded = isPDBLoaded;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,60 +210,60 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to determine if the current program has RTTI data applied to it
|
||||
* @return true if the current program has RTTI data applied to it
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private boolean programHasRTTIApplied() throws CancelledException {
|
||||
|
||||
// First check to see if the RTTICompleteObjectLocator data type exists. If not there has
|
||||
// been no RTTI applied
|
||||
DataType completeObjLocatorDataType = dataTypeManager.getDataType(CategoryPath.ROOT,
|
||||
RTTI_BASE_COMPLETE_OBJECT_LOADER_DATA_NAME);
|
||||
if (completeObjLocatorDataType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Next check that a RTTICompleteObjectLocator has been applied somewhere to make sure that
|
||||
// we don't have the case where pdb ran and created the data type but rtti didn't run so didn't
|
||||
// apply any of the data types
|
||||
return hasSymbolAndDataType(RTTI_BASE_COMPLETE_OBJECT_LOADER_LABEL,
|
||||
completeObjLocatorDataType);
|
||||
}
|
||||
|
||||
private void runRTTIAnalyzer() throws Exception {
|
||||
// Analyzer analyzer = new RttiAnalyzer();
|
||||
// analyzer.added(program, program.getAddressFactory().getAddressSet(), monitor,
|
||||
// new MessageLog());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to find all the vftables in the program
|
||||
* @return list of all vftable symbols
|
||||
* @throws CancelledException when cancelled
|
||||
*/
|
||||
//TODO: pull into separate methods and check separately above
|
||||
private boolean hasSymbolAndDataType(String symbolName, DataType datatype)
|
||||
throws CancelledException {
|
||||
|
||||
String pdbName = "`" + symbolName + "'";
|
||||
SymbolIterator symbols =
|
||||
program.getSymbolTable().getSymbolIterator("*" + symbolName + "*", true);
|
||||
|
||||
while (symbols.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Symbol symbol = symbols.next();
|
||||
if (symbol.getName().equals(symbolName) || symbol.getName().equals(pdbName)) {
|
||||
Data dataAt = program.getListing().getDefinedDataAt(symbol.getAddress());
|
||||
if (dataAt.getDataType().equals(datatype)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// /**
|
||||
// * Method to determine if the current program has RTTI data applied to it
|
||||
// * @return true if the current program has RTTI data applied to it
|
||||
// * @throws CancelledException if cancelled
|
||||
// */
|
||||
// private boolean programHasRTTIApplied() throws CancelledException {
|
||||
//
|
||||
// // First check to see if the RTTICompleteObjectLocator data type exists. If not there has
|
||||
// // been no RTTI applied
|
||||
// DataType completeObjLocatorDataType = dataTypeManager.getDataType(CategoryPath.ROOT,
|
||||
// RTTI_BASE_COMPLETE_OBJECT_LOADER_DATA_NAME);
|
||||
// if (completeObjLocatorDataType == null) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // Next check that a RTTICompleteObjectLocator has been applied somewhere to make sure that
|
||||
// // we don't have the case where pdb ran and created the data type but rtti didn't run so didn't
|
||||
// // apply any of the data types
|
||||
// return hasSymbolAndDataType(RTTI_BASE_COMPLETE_OBJECT_LOADER_LABEL,
|
||||
// completeObjLocatorDataType);
|
||||
// }
|
||||
//
|
||||
// private void runRTTIAnalyzer() throws Exception {
|
||||
//// Analyzer analyzer = new RttiAnalyzer();
|
||||
//// analyzer.added(program, program.getAddressFactory().getAddressSet(), monitor,
|
||||
//// new MessageLog());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Method to find all the vftables in the program
|
||||
// * @return list of all vftable symbols
|
||||
// * @throws CancelledException when cancelled
|
||||
// */
|
||||
// //TODO: pull into separate methods and check separately above
|
||||
// private boolean hasSymbolAndDataType(String symbolName, DataType datatype)
|
||||
// throws CancelledException {
|
||||
//
|
||||
// String pdbName = "`" + symbolName + "'";
|
||||
// SymbolIterator symbols =
|
||||
// program.getSymbolTable().getSymbolIterator("*" + symbolName + "*", true);
|
||||
//
|
||||
// while (symbols.hasNext()) {
|
||||
// monitor.checkCancelled();
|
||||
// Symbol symbol = symbols.next();
|
||||
// if (symbol.getName().equals(symbolName) || symbol.getName().equals(pdbName)) {
|
||||
// Data dataAt = program.getListing().getDefinedDataAt(symbol.getAddress());
|
||||
// if (dataAt.getDataType().equals(datatype)) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public void fixUpRttiAnalysis() throws CancelledException, Exception {
|
||||
applyMissingRTTIStructures();
|
||||
@@ -512,10 +481,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
List<Address> classHierarchyDescriptorAddresses = new ArrayList<Address>();
|
||||
|
||||
Iterator<Symbol> baseClassDescriptorIterator = baseClassDescriptors.iterator();
|
||||
while (baseClassDescriptorIterator.hasNext()) {
|
||||
for (Symbol symbol : baseClassDescriptors) {
|
||||
monitor.checkCancelled();
|
||||
Symbol symbol = baseClassDescriptorIterator.next();
|
||||
Address classHierarchyDescriptorAddress = createClassHierarchyDescriptor(
|
||||
symbol.getAddress().add(24), symbol.getParentNamespace());
|
||||
|
||||
@@ -526,10 +493,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
}
|
||||
|
||||
Iterator<Symbol> completeObjectLocatorIterator = completeObjectLocators.iterator();
|
||||
while (completeObjectLocatorIterator.hasNext()) {
|
||||
for (Symbol symbol : completeObjectLocators) {
|
||||
monitor.checkCancelled();
|
||||
Symbol symbol = completeObjectLocatorIterator.next();
|
||||
Address classHierarchyDescriptorAddress = createClassHierarchyDescriptor(
|
||||
symbol.getAddress().add(16), symbol.getParentNamespace());
|
||||
if (classHierarchyDescriptorAddress != null &&
|
||||
@@ -621,13 +586,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
List<Address> baseClassArrayAddresses = new ArrayList<Address>();
|
||||
|
||||
Iterator<Address> classHierarchyDescriptorIterator = classHierarchyDescriptors.iterator();
|
||||
|
||||
while (classHierarchyDescriptorIterator.hasNext()) {
|
||||
for (Address classHierarchyDescriptorAddress : classHierarchyDescriptors) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
|
||||
Address classHierarchyDescriptorAddress = classHierarchyDescriptorIterator.next();
|
||||
Symbol classHierarchyDescriptorSymbol =
|
||||
symbolTable.getPrimarySymbol(classHierarchyDescriptorAddress);
|
||||
Namespace classNamespace = classHierarchyDescriptorSymbol.getParentNamespace();
|
||||
@@ -725,11 +687,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
List<Symbol> vftables = new ArrayList<Symbol>();
|
||||
|
||||
Iterator<Symbol> iterator = completeObjectLocatorSymbols.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
for (Symbol completeObjectLocatorSymbol : completeObjectLocatorSymbols) {
|
||||
monitor.checkCancelled();
|
||||
Symbol completeObjectLocatorSymbol = iterator.next();
|
||||
|
||||
Address completeObjectLocatorAddress = completeObjectLocatorSymbol.getAddress();
|
||||
|
||||
Namespace classNamespace = completeObjectLocatorSymbol.getParentNamespace();
|
||||
@@ -903,10 +862,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
List<Symbol> classHierarchyDescriptorList = getListOfClassHierarchyDescriptors();
|
||||
|
||||
Iterator<Symbol> classHierarchyDescriptorIterator = classHierarchyDescriptorList.iterator();
|
||||
while (classHierarchyDescriptorIterator.hasNext()) {
|
||||
for (Symbol classHierarchyDescriptorSymbol : classHierarchyDescriptorList) {
|
||||
monitor.checkCancelled();
|
||||
Symbol classHierarchyDescriptorSymbol = classHierarchyDescriptorIterator.next();
|
||||
Address classHierarchyDescriptorAddress = classHierarchyDescriptorSymbol.getAddress();
|
||||
|
||||
// Get class name from class vftable is in
|
||||
@@ -1000,16 +957,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
PointerDataType pointerDataType = new PointerDataType();
|
||||
|
||||
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
|
||||
while (recoveredClassIterator.hasNext()) {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||
|
||||
List<Address> vftableAddresses = recoveredClass.getVftableAddresses();
|
||||
Iterator<Address> vftableIterator = vftableAddresses.iterator();
|
||||
while (vftableIterator.hasNext()) {
|
||||
for (Address vftableAddress : vftableAddresses) {
|
||||
monitor.checkCancelled();
|
||||
Address vftableAddress = vftableIterator.next();
|
||||
Address ptrToColAddress = vftableAddress.subtract(defaultPointerSize);
|
||||
|
||||
Data pointerToCompleteObjLocator = extendedFlatAPI.getDataAt(vftableAddress);
|
||||
@@ -1396,12 +1348,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
private void determineParentClassInfoFromBaseClassArray(List<RecoveredClass> recoveredClasses)
|
||||
throws Exception {
|
||||
|
||||
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
|
||||
while (recoveredClassIterator.hasNext()) {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||
|
||||
boolean hasVirtualAncestor = false;
|
||||
int vbaseOffset = NONE;
|
||||
|
||||
@@ -1531,22 +1480,22 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Function> constructorIterator = constructorList.iterator();
|
||||
while (constructorIterator.hasNext()) {
|
||||
DecompileOptions decompileOptions =
|
||||
DecompilerUtils.getDecompileOptions(serviceProvider, program);
|
||||
FillOutStructureHelper fillStructHelper =
|
||||
new FillOutStructureHelper(program, decompileOptions, monitor);
|
||||
|
||||
for (Function constructor : constructorList) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
Function constructor = constructorIterator.next();
|
||||
|
||||
HighFunction highFunction = decompilerUtils.getHighFunction(constructor);
|
||||
|
||||
if (highFunction == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FillOutStructureCmd fillCmd = new FillOutStructureCmd(program, location, tool);
|
||||
|
||||
Address vbtableAddress = getVbtableAddressFromDecompiledFunction(fillCmd, highFunction,
|
||||
recoveredClass, constructor, vbtableOffset);
|
||||
Address vbtableAddress = getVbtableAddressFromDecompiledFunction(fillStructHelper,
|
||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||
|
||||
if (vbtableAddress != null) {
|
||||
return vbtableAddress;
|
||||
@@ -1561,22 +1510,17 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Function> indeterminateIterator = indeterminateList.iterator();
|
||||
while (indeterminateIterator.hasNext()) {
|
||||
for (Function constructor : indeterminateList) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
Function constructor = indeterminateIterator.next();
|
||||
|
||||
HighFunction highFunction = decompilerUtils.getHighFunction(constructor);
|
||||
|
||||
if (highFunction == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FillOutStructureCmd fillCmd = new FillOutStructureCmd(program, location, tool);
|
||||
|
||||
Address vbtableAddress = getVbtableAddressFromDecompiledFunction(fillCmd, highFunction,
|
||||
recoveredClass, constructor, vbtableOffset);
|
||||
Address vbtableAddress = getVbtableAddressFromDecompiledFunction(fillStructHelper,
|
||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||
|
||||
if (vbtableAddress != null) {
|
||||
return vbtableAddress;
|
||||
@@ -1589,7 +1533,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
/**
|
||||
* Method to find the address of the vbtable referenced at the given offset in the given function
|
||||
* @param fillCmd the decompiler's filled out structure for a particular variable
|
||||
* @param fillStructHelper a reusable {@link FillOutStructureHelper} instance to be used
|
||||
* with decompiler for a particular variable
|
||||
* @param highFunction the high function for the given function
|
||||
* @param recoveredClass the given class
|
||||
* @param function the given function
|
||||
@@ -1597,7 +1542,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
* @return the address of the found vbtable or null if none is found
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private Address getVbtableAddressFromDecompiledFunction(FillOutStructureCmd fillCmd,
|
||||
private Address getVbtableAddressFromDecompiledFunction(FillOutStructureHelper fillStructHelper,
|
||||
HighFunction highFunction, RecoveredClass recoveredClass, Function function, int offset)
|
||||
throws CancelledException {
|
||||
|
||||
@@ -1619,22 +1564,16 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<HighVariable> highVariableIterator = highVariables.iterator();
|
||||
for (HighVariable highVariable : highVariables) {
|
||||
|
||||
while (highVariableIterator.hasNext()) {
|
||||
|
||||
HighVariable highVariable = highVariableIterator.next();
|
||||
monitor.checkCancelled();
|
||||
|
||||
fillCmd.processStructure(highVariable, function);
|
||||
List<OffsetPcodeOpPair> stores = fillCmd.getStorePcodeOps();
|
||||
fillStructHelper.processStructure(highVariable, function, true, false);
|
||||
List<OffsetPcodeOpPair> stores = fillStructHelper.getStorePcodeOps();
|
||||
stores = removePcodeOpsNotInFunction(function, stores);
|
||||
|
||||
// this method checks the storedPcodeOps to see if one is a vftable address
|
||||
Iterator<OffsetPcodeOpPair> iterator = stores.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
for (OffsetPcodeOpPair offsetPcodeOpPair : stores) {
|
||||
monitor.checkCancelled();
|
||||
OffsetPcodeOpPair offsetPcodeOpPair = iterator.next();
|
||||
int pcodeOffset = offsetPcodeOpPair.getOffset().intValue();
|
||||
if (pcodeOffset == offset) {
|
||||
|
||||
@@ -1664,11 +1603,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
private void assignParentClassToVftables(List<RecoveredClass> recoveredClasses)
|
||||
throws Exception {
|
||||
|
||||
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
|
||||
while (recoveredClassIterator.hasNext()) {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||
|
||||
if (!recoveredClass.hasVftable()) {
|
||||
continue;
|
||||
}
|
||||
@@ -1726,10 +1662,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
// iterate over the hierarchy list and use it to get the order of the parentsParents and assign
|
||||
// to correct vftable
|
||||
List<RecoveredClass> classHierarchy = recoveredClass.getClassHierarchy();
|
||||
Iterator<RecoveredClass> classHierarchyIterator = classHierarchy.iterator();
|
||||
while (classHierarchyIterator.hasNext()) {
|
||||
for (RecoveredClass ancestor : classHierarchy) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass ancestor = classHierarchyIterator.next();
|
||||
if (grandParents.contains(ancestor)) {
|
||||
Integer index = sortedOrder.get(order);
|
||||
Address vftableAddress = orderToVftableMap.get(index);
|
||||
@@ -1817,12 +1751,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
List<RecoveredClass> classHierarchy = recoveredClass.getClassHierarchy();
|
||||
|
||||
Iterator<RecoveredClass> hierarchyIterator = classHierarchy.iterator();
|
||||
|
||||
while (hierarchyIterator.hasNext()) {
|
||||
for (RecoveredClass ancestorClass : classHierarchy) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass ancestorClass = hierarchyIterator.next();
|
||||
|
||||
RecoveredClass firstVirtuallyInheritedAncestorWithVfunctions =
|
||||
getVirtuallyInheritedParentWithVfunctions(ancestorClass);
|
||||
if (firstVirtuallyInheritedAncestorWithVfunctions != null) {
|
||||
@@ -1857,11 +1787,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
Map<RecoveredClass, Boolean> parentToBaseTypeMap = recoveredClass.getParentToBaseTypeMap();
|
||||
|
||||
List<RecoveredClass> parents = new ArrayList<RecoveredClass>(classHierarchyMap.keySet());
|
||||
Iterator<RecoveredClass> parentIterator = parents.iterator();
|
||||
|
||||
while (parentIterator.hasNext()) {
|
||||
for (RecoveredClass parent : parents) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass parent = parentIterator.next();
|
||||
Boolean isVirtuallyInherited = parentToBaseTypeMap.get(parent);
|
||||
|
||||
if (isVirtuallyInherited != null && isVirtuallyInherited && parent.hasVftable()) {
|
||||
@@ -1898,10 +1825,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<Integer> orderIterator = sortedOrder.iterator();
|
||||
while (orderIterator.hasNext()) {
|
||||
for (Integer order : sortedOrder) {
|
||||
monitor.checkCancelled();
|
||||
Integer order = orderIterator.next();
|
||||
Address vftableAddress = orderToVftableMap.get(order);
|
||||
RecoveredClass parentClass = parentOrderMap.get(order);
|
||||
recoveredClass.addVftableToBaseClassMapping(vftableAddress, parentClass);
|
||||
@@ -1970,13 +1895,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
return parentOrderMap;
|
||||
}
|
||||
|
||||
Iterator<Function> functionIterator = functionList.iterator();
|
||||
while (functionIterator.hasNext()) {
|
||||
for (Function function : functionList) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
|
||||
Function function = functionIterator.next();
|
||||
|
||||
parentOrderMap = new HashMap<Integer, RecoveredClass>();
|
||||
|
||||
Map<Address, RecoveredClass> referenceToParentMap =
|
||||
@@ -1986,12 +1908,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
new HashMap<Address, RecoveredClass>();
|
||||
|
||||
List<Address> classReferences = new ArrayList<Address>(referenceToParentMap.keySet());
|
||||
Iterator<Address> classReferenceIterator = classReferences.iterator();
|
||||
while (classReferenceIterator.hasNext()) {
|
||||
for (Address classReferenceAddress : classReferences) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
Address classReferenceAddress = classReferenceIterator.next();
|
||||
|
||||
// if the address refers to a vftable and that vftable is in the current class then it is not a parent class so do not add to map
|
||||
Address possibleVftable = getVftableAddress(classReferenceAddress);
|
||||
|
||||
@@ -2029,11 +1948,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
Collections.sort(parentReferences, Collections.reverseOrder());
|
||||
}
|
||||
|
||||
// iterate over the ordered parents and add to the order to parent map
|
||||
Iterator<Address> parentRefIterator = parentReferences.iterator();
|
||||
while (parentRefIterator.hasNext()) {
|
||||
// iterate over the ordered parents and add the order to the parent map
|
||||
for (Address refAddress : parentReferences) {
|
||||
monitor.checkCancelled();
|
||||
Address refAddress = parentRefIterator.next();
|
||||
RecoveredClass parentClass = referenceToParentMap.get(refAddress);
|
||||
parentOrderMap.put(order, parentClass);
|
||||
order++;
|
||||
@@ -2074,11 +1991,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
List<RecoveredClass> updatedParentClasses = new ArrayList<RecoveredClass>(parentClasses);
|
||||
|
||||
// now iterate over the direct parents and map that parent to each ancestor on the ancestor with vfunction list
|
||||
Iterator<RecoveredClass> parentIterator = parentClasses.iterator();
|
||||
while (parentIterator.hasNext()) {
|
||||
for (RecoveredClass parentClass : parentClasses) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
RecoveredClass parentClass = parentIterator.next();
|
||||
List<RecoveredClass> ancestors =
|
||||
new ArrayList<RecoveredClass>(parentClass.getClassHierarchy());
|
||||
ancestors.remove(parentClass);
|
||||
@@ -2088,12 +2003,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<RecoveredClass> ancestorIterator = ancestors.iterator();
|
||||
while (ancestorIterator.hasNext()) {
|
||||
for (RecoveredClass ancestor : ancestors) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
RecoveredClass ancestor = ancestorIterator.next();
|
||||
|
||||
List<RecoveredClass> decendentList = ancestorToCommonChild.get(ancestor);
|
||||
if (decendentList == null) {
|
||||
List<RecoveredClass> newDecendentList = new ArrayList<RecoveredClass>();
|
||||
@@ -2119,10 +2031,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
// now iterate over the ancestor map and update the parent list by adding any ancestor
|
||||
// that has common parents and removing those parents from the list
|
||||
Iterator<RecoveredClass> ancestorsIterator = keySet.iterator();
|
||||
while (ancestorsIterator.hasNext()) {
|
||||
for (RecoveredClass ancestor : keySet) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass ancestor = ancestorsIterator.next();
|
||||
List<RecoveredClass> commonChildList = ancestorToCommonChild.get(ancestor);
|
||||
if (commonChildList != null && commonChildList.size() >= 2) {
|
||||
if (!updatedParentClasses.contains(ancestor)) {
|
||||
|
||||
Reference in New Issue
Block a user