mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-2010 updated to use preferred root class folder and removed code that
replaced other class structs
This commit is contained in:
parent
d7fc209657
commit
37f87c4874
8 changed files with 28 additions and 248 deletions
|
@ -47,7 +47,7 @@ public class ApplyClassFunctionDefinitionUpdatesScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
||||||
state.getTool(), this, false, false, false, false, monitor);
|
state.getTool(), this, false, false, false, monitor);
|
||||||
|
|
||||||
DataTypeManagerService dtms = state.getTool().getService(DataTypeManagerService.class);
|
DataTypeManagerService dtms = state.getTool().getService(DataTypeManagerService.class);
|
||||||
List<DataType> selectedDatatypes = dtms.getSelectedDatatypes();
|
List<DataType> selectedDatatypes = dtms.getSelectedDatatypes();
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class ApplyClassFunctionSignatureUpdatesScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
||||||
state.getTool(), this, false, false, false, false, monitor);
|
state.getTool(), this, false, false, false, monitor);
|
||||||
|
|
||||||
if(currentAddress == null) {
|
if(currentAddress == null) {
|
||||||
println("Cursor must be in a class function.");
|
println("Cursor must be in a class function.");
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class FindOperatorDeletesAndNewsScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
RecoveredClassHelper classHelper = new RecoveredClassHelper(currentProgram, currentLocation,
|
||||||
state.getTool(), this, false, false, false, false, monitor);
|
state.getTool(), this, false, false, false, monitor);
|
||||||
|
|
||||||
List<Address> discoveredOperatorDeletes =
|
List<Address> discoveredOperatorDeletes =
|
||||||
getFunctionAddressList(classHelper.findOperatorDeletes());
|
getFunctionAddressList(classHelper.findOperatorDeletes());
|
||||||
|
|
|
@ -130,12 +130,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
// show shortened class template names in class structure field names
|
// show shortened class template names in class structure field names
|
||||||
private static final boolean USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS = true;
|
private static final boolean USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS = true;
|
||||||
|
|
||||||
// replace defined existing class structures (ie pdb, fid, demangler, or other)with ones created by
|
|
||||||
// this script and rename the existing ones with a _REPLACED suffix
|
|
||||||
// NOTE: currently does not replace DWARF
|
|
||||||
// NEW OPTION:
|
|
||||||
private static final boolean REPLACE_EXISTING_CLASS_STRUCTURES = true;
|
|
||||||
|
|
||||||
private static final String CLASS_DATA_STRUCT_NAME = "_data";
|
private static final String CLASS_DATA_STRUCT_NAME = "_data";
|
||||||
|
|
||||||
private static final String CONSTRUCTOR_BOOKMARK = "CONSTRUCTOR";
|
private static final String CONSTRUCTOR_BOOKMARK = "CONSTRUCTOR";
|
||||||
|
@ -143,30 +137,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
|
|
||||||
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
|
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
|
||||||
|
|
||||||
// DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES
|
|
||||||
// If replacedClassStructuresOption is set to the following, no replaced structures will be removed
|
|
||||||
// from the data type manager
|
|
||||||
|
|
||||||
// REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES
|
|
||||||
// If replacedClassStructuresOption is set to the following, only empty existing class structures
|
|
||||||
// that were replaced by this script will be removed from the data type manager
|
|
||||||
|
|
||||||
// REMOVE_ALL_REPLACED_CLASS_STRUCTURES
|
|
||||||
// If replacedClassStructuresOption is set to the following, all existing class structures that
|
|
||||||
// were replaced by this script, including non-emtpy ones, will be removed from the data type
|
|
||||||
// manager
|
|
||||||
private static enum removeOption {
|
|
||||||
DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES,
|
|
||||||
REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES,
|
|
||||||
REMOVE_ALL_REPLACED_CLASS_STRUCTURES
|
|
||||||
}
|
|
||||||
|
|
||||||
// NEW OPTION -
|
|
||||||
// This option allows the user to decide whether and how to remove replaced existing class structures
|
|
||||||
// using one of the above three flags
|
|
||||||
removeOption replacedClassStructuresOption =
|
|
||||||
removeOption.DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES;
|
|
||||||
|
|
||||||
boolean programHasRTTIApplied = false;
|
boolean programHasRTTIApplied = false;
|
||||||
boolean hasDebugSymbols;
|
boolean hasDebugSymbols;
|
||||||
boolean isGcc = false;
|
boolean isGcc = false;
|
||||||
|
@ -198,7 +168,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
recoverClassesFromRTTI =
|
recoverClassesFromRTTI =
|
||||||
new RTTIWindowsClassRecoverer(currentProgram, currentLocation, state.getTool(),
|
new RTTIWindowsClassRecoverer(currentProgram, currentLocation, state.getTool(),
|
||||||
this, BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
this, BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
||||||
nameVfunctions, hasDebugSymbols, REPLACE_EXISTING_CLASS_STRUCTURES, monitor);
|
nameVfunctions, hasDebugSymbols, monitor);
|
||||||
}
|
}
|
||||||
else if (isGcc()) {
|
else if (isGcc()) {
|
||||||
|
|
||||||
|
@ -221,7 +191,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
recoverClassesFromRTTI =
|
recoverClassesFromRTTI =
|
||||||
new RTTIGccClassRecoverer(currentProgram, currentLocation, state.getTool(), this,
|
new RTTIGccClassRecoverer(currentProgram, currentLocation, state.getTool(), this,
|
||||||
BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
|
||||||
nameVfunctions, hasDebugSymbols, REPLACE_EXISTING_CLASS_STRUCTURES, monitor);
|
nameVfunctions, hasDebugSymbols, monitor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
println("This script will not work on this program type");
|
println("This script will not work on this program type");
|
||||||
|
@ -265,6 +235,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
out = new PrintWriter(outputFile);
|
out = new PrintWriter(outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentProgram.setPreferredRootNamespaceCategoryPath(
|
||||||
|
"/" + RecoveredClassHelper.DTM_CLASS_DATA_FOLDER_NAME);
|
||||||
|
|
||||||
if (FIXUP_PROGRAM) {
|
if (FIXUP_PROGRAM) {
|
||||||
println(
|
println(
|
||||||
"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 " +
|
||||||
|
@ -313,17 +286,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
showGraph(graph);
|
showGraph(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replacedClassStructuresOption == removeOption.REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES) {
|
|
||||||
println("Removing all empty replaced class structures from the data type manager");
|
|
||||||
recoverClassesFromRTTI.removeReplacedClassStructures(recoveredClasses, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (replacedClassStructuresOption == removeOption.REMOVE_ALL_REPLACED_CLASS_STRUCTURES) {
|
|
||||||
println(
|
|
||||||
"Removing all replaced class structures from the data type manager, including non-empty ones");
|
|
||||||
recoverClassesFromRTTI.removeReplacedClassStructures(recoveredClasses, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
decompilerUtils.disposeDecompilerInterface();
|
decompilerUtils.disposeDecompilerInterface();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,9 @@ public class RTTIClassRecoverer extends RecoveredClassHelper {
|
||||||
|
|
||||||
RTTIClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
RTTIClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
||||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||||
boolean nameVfunctions, boolean hasDebugSymbols, boolean replaceClassStructures,
|
boolean nameVfunctions, boolean hasDebugSymbols, TaskMonitor monitor) throws Exception {
|
||||||
TaskMonitor monitor) throws Exception {
|
|
||||||
|
|
||||||
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
|
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
|
||||||
replaceClassStructures,
|
|
||||||
monitor);
|
monitor);
|
||||||
|
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
|
|
@ -76,13 +76,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
||||||
|
|
||||||
public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
||||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||||
boolean nameVfunctions, boolean isDwarfLoaded, boolean replaceExistingClassStructures,
|
boolean nameVfunctions, boolean isDwarfLoaded,
|
||||||
TaskMonitor monitor) throws Exception {
|
TaskMonitor monitor) throws Exception {
|
||||||
|
|
||||||
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
|
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
|
||||||
replaceExistingClassStructures, isDwarfLoaded, monitor);
|
isDwarfLoaded, monitor);
|
||||||
this.isDwarfLoaded = isDwarfLoaded;
|
this.isDwarfLoaded = isDwarfLoaded;
|
||||||
this.replaceClassStructs = replaceExistingClassStructures;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -69,11 +69,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||||
|
|
||||||
public RTTIWindowsClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
public RTTIWindowsClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
|
||||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||||
boolean nameVFunctions, boolean isPDBLoaded, boolean replaceClassStructures,
|
boolean nameVFunctions, boolean isPDBLoaded, TaskMonitor monitor) throws Exception {
|
||||||
TaskMonitor monitor) throws Exception {
|
|
||||||
|
|
||||||
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
|
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
|
||||||
isPDBLoaded, replaceClassStructures, monitor);
|
isPDBLoaded, monitor);
|
||||||
|
|
||||||
this.isPDBLoaded = isPDBLoaded;
|
this.isPDBLoaded = isPDBLoaded;
|
||||||
|
|
||||||
|
|
|
@ -144,11 +144,10 @@ public class RecoveredClassHelper {
|
||||||
boolean createBookmarks;
|
boolean createBookmarks;
|
||||||
boolean useShortTemplates;
|
boolean useShortTemplates;
|
||||||
boolean nameVfunctions;
|
boolean nameVfunctions;
|
||||||
boolean replaceClassStructures;
|
|
||||||
|
|
||||||
public RecoveredClassHelper(Program program, ProgramLocation location, PluginTool tool,
|
public RecoveredClassHelper(Program program, ProgramLocation location, PluginTool tool,
|
||||||
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
|
||||||
boolean nameVunctions, boolean replaceClassStructures, TaskMonitor monitor)
|
boolean nameVunctions, TaskMonitor monitor)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
|
@ -165,7 +164,6 @@ public class RecoveredClassHelper {
|
||||||
this.createBookmarks = createBookmarks;
|
this.createBookmarks = createBookmarks;
|
||||||
this.useShortTemplates = useShortTemplates;
|
this.useShortTemplates = useShortTemplates;
|
||||||
this.nameVfunctions = nameVunctions;
|
this.nameVfunctions = nameVunctions;
|
||||||
this.replaceClassStructures = replaceClassStructures;
|
|
||||||
|
|
||||||
globalNamespace = (GlobalNamespace) program.getGlobalNamespace();
|
globalNamespace = (GlobalNamespace) program.getGlobalNamespace();
|
||||||
|
|
||||||
|
@ -3276,13 +3274,6 @@ public class RecoveredClassHelper {
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the "this" data type is an empty placeholder for the class
|
|
||||||
// structure and replace it with the one that was just created by the script
|
|
||||||
//NEW
|
|
||||||
if (replaceClassStructures) {
|
|
||||||
replaceClassStructure(constructorFunction, className, classStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if current decompiler function return type is a pointer then set the return type
|
// if current decompiler function return type is a pointer then set the return type
|
||||||
// to a pointer to the class structure, otherwise if it is a void, make it a void so the
|
// to a pointer to the class structure, otherwise if it is a void, make it a void so the
|
||||||
// listing has void too, otherwise, leave it as is, probably a void
|
// listing has void too, otherwise, leave it as is, probably a void
|
||||||
|
@ -3314,6 +3305,20 @@ public class RecoveredClassHelper {
|
||||||
DataType classPointerDataType = dataTypeManager.getPointer(classStruct);
|
DataType classPointerDataType = dataTypeManager.getPointer(classStruct);
|
||||||
constructorFunction.setReturnType(classPointerDataType, SourceType.ANALYSIS);
|
constructorFunction.setReturnType(classPointerDataType, SourceType.ANALYSIS);
|
||||||
}
|
}
|
||||||
|
// if neither and it is a FID function change it to undefined so the decompiler will
|
||||||
|
// recompute it
|
||||||
|
else if (isFidFunction(constructorFunction)) {
|
||||||
|
DataType undefinedDT = null;
|
||||||
|
if (defaultPointerSize == 4) {
|
||||||
|
undefinedDT = new Undefined4DataType();
|
||||||
|
}
|
||||||
|
if (defaultPointerSize == 8) {
|
||||||
|
undefinedDT = new Undefined8DataType();
|
||||||
|
}
|
||||||
|
if (undefinedDT != null) {
|
||||||
|
constructorFunction.setReturnType(undefinedDT, SourceType.ANALYSIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3358,13 +3363,6 @@ public class RecoveredClassHelper {
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the "this" data type is an empty placeholder for the class
|
|
||||||
// structure and replace it with the one that was just created by the script
|
|
||||||
//NEW
|
|
||||||
if (replaceClassStructures) {
|
|
||||||
replaceClassStructure(destructorFunction, className, classStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
destructorFunction.setReturnType(new VoidDataType(), SourceType.ANALYSIS);
|
destructorFunction.setReturnType(new VoidDataType(), SourceType.ANALYSIS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3412,14 +3410,6 @@ public class RecoveredClassHelper {
|
||||||
true, true);
|
true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the "this" data type is an empty placeholder for the class
|
|
||||||
// structure and replace it with the one that was just created by the script
|
|
||||||
//NEW
|
|
||||||
if (replaceClassStructures) {
|
|
||||||
replaceClassStructure(vbaseDestructorFunction, recoveredClass.getName(),
|
|
||||||
classStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
vbaseDestructorFunction.setReturnType(new VoidDataType(), SourceType.ANALYSIS);
|
vbaseDestructorFunction.setReturnType(new VoidDataType(), SourceType.ANALYSIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3527,161 +3517,6 @@ public class RecoveredClassHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to replace the program's current class structure, only if an empty placeholder structure,
|
|
||||||
* with the one generated by this script
|
|
||||||
* @param function a class method with current class structure applied
|
|
||||||
* @param className the given class name
|
|
||||||
* @param newClassStructure the new structure to replace the old with
|
|
||||||
* @throws DataTypeDependencyException if there is a data dependency exception when replacing
|
|
||||||
* @throws CancelledException if cancelled
|
|
||||||
*/
|
|
||||||
public void replaceClassStructure(Function function, String className,
|
|
||||||
Structure newClassStructure) throws DataTypeDependencyException, CancelledException {
|
|
||||||
|
|
||||||
Parameter thisParam = function.getParameter(0);
|
|
||||||
if (thisParam == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataType dataType = thisParam.getDataType();
|
|
||||||
if (dataType instanceof Pointer) {
|
|
||||||
Pointer ptr = (Pointer) dataType;
|
|
||||||
DataType baseDataType = ptr.getDataType();
|
|
||||||
if (!baseDataType.equals(newClassStructure) &&
|
|
||||||
baseDataType.getName().equals(className)) {
|
|
||||||
|
|
||||||
// check if fid demangler or pdb - don't replace user ones
|
|
||||||
if (!isReplaceableType(function.getEntryPoint(), baseDataType)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// create copy of existing one
|
|
||||||
DataType baseDataTypeCopy = baseDataType.copy(dataTypeManager);
|
|
||||||
|
|
||||||
renameDataType(baseDataTypeCopy, baseDataType.getName() + "_REPLACED");
|
|
||||||
|
|
||||||
// replace the other with the new one
|
|
||||||
dataTypeManager.replaceDataType(baseDataType, newClassStructure, false);
|
|
||||||
|
|
||||||
// // remove original folder if it is empty after the replace
|
|
||||||
// in future if decide to just remove the other ones, then do the following
|
|
||||||
// CategoryPath originalPath = baseDataType.getCategoryPath();
|
|
||||||
// Category category = dataTypeManager.getCategory(originalPath);
|
|
||||||
// Category parentCategory = category.getParent();
|
|
||||||
// if (parentCategory != null) {
|
|
||||||
// parentCategory.removeEmptyCategory(category.getName(), monitor);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renameDataType(DataType dataType, String name) throws CancelledException {
|
|
||||||
|
|
||||||
boolean renamed = false;
|
|
||||||
int oneup = 2;
|
|
||||||
while (!renamed) {
|
|
||||||
monitor.checkCanceled();
|
|
||||||
try {
|
|
||||||
dataType.setName(name);
|
|
||||||
dataTypeManager.resolve(dataType, DataTypeConflictHandler.DEFAULT_HANDLER);
|
|
||||||
renamed = true;
|
|
||||||
}
|
|
||||||
catch (InvalidNameException | DuplicateNameException e) {
|
|
||||||
name = name + oneup++;
|
|
||||||
renamed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isReplaceableType(Address address, DataType dataType) {
|
|
||||||
|
|
||||||
// return false if it isn't even a structure
|
|
||||||
if (!(dataType instanceof Structure)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String categoryPath = dataType.getPathName();
|
|
||||||
if (categoryPath.startsWith("/Demangler")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (categoryPath.contains(".pdb")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (categoryPath.contains("DWARF")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// test to see if the data type is an empty structure with "PlaceHolder Class Structure" in
|
|
||||||
// the description
|
|
||||||
Structure structure = (Structure) dataType;
|
|
||||||
if (structure.isNotYetDefined() &&
|
|
||||||
structure.getDescription().equals("PlaceHolder Class Structure")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program.getBookmarkManager()
|
|
||||||
.getBookmark(address, BookmarkType.ANALYSIS, "Function ID Analyzer") != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to remove existing class structures from the data type manager that were replaced by
|
|
||||||
* newly created class structures and that have the "_REPLACED" suffix on them
|
|
||||||
* @param recoveredClasses list of given recovered classes
|
|
||||||
* @param removeNonEmpty if true, remove not only the empty replaced class structures but
|
|
||||||
* also the non-empty ones.
|
|
||||||
* @throws CancelledException if cancelled
|
|
||||||
*/
|
|
||||||
public void removeReplacedClassStructures(List<RecoveredClass> recoveredClasses,
|
|
||||||
boolean removeNonEmpty) throws CancelledException {
|
|
||||||
|
|
||||||
if (recoveredClasses.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
|
||||||
monitor.checkCanceled();
|
|
||||||
|
|
||||||
// first get the new class structure and verify it exists - don't remove others if
|
|
||||||
// new one doesn't exist
|
|
||||||
DataType classStructureDataType = dataTypeManager
|
|
||||||
.getDataType(recoveredClass.getClassPath(), recoveredClass.getName());
|
|
||||||
if (classStructureDataType == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// then find all class structures with name "<className>_REPLACED"
|
|
||||||
List<DataType> replacedClassDataTypes = new ArrayList<DataType>();
|
|
||||||
dataTypeManager.findDataTypes(recoveredClass.getName() + "_REPLACED",
|
|
||||||
replacedClassDataTypes);
|
|
||||||
|
|
||||||
if (replacedClassDataTypes.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DataType replacedClassDataType : replacedClassDataTypes) {
|
|
||||||
monitor.checkCanceled();
|
|
||||||
|
|
||||||
if (!(replacedClassDataType instanceof Structure)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeNonEmpty) {
|
|
||||||
dataTypeManager.remove(replacedClassDataType, monitor);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Structure replacedStructure = (Structure) replacedClassDataType;
|
|
||||||
if (replacedStructure.isNotYetDefined()) {
|
|
||||||
dataTypeManager.remove(replacedClassDataType, monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a new symbol at the given function
|
* Method to create a new symbol at the given function
|
||||||
|
@ -4546,13 +4381,6 @@ public class RecoveredClassHelper {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the "this" data type is an empty placeholder for the class
|
|
||||||
// structure and replace it with the one that was just created by the script
|
|
||||||
//NEW
|
|
||||||
if (replaceClassStructures) {
|
|
||||||
replaceClassStructure(vfunction, recoveredClass.getName(), classStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
String forClassSuffix = getForClassSuffix(vftableStructureName);
|
String forClassSuffix = getForClassSuffix(vftableStructureName);
|
||||||
String functionDefName = vfunction.getName();
|
String functionDefName = vfunction.getName();
|
||||||
int indexOfSuffix = functionDefName.indexOf(forClassSuffix);
|
int indexOfSuffix = functionDefName.indexOf(forClassSuffix);
|
||||||
|
@ -5091,12 +4919,6 @@ public class RecoveredClassHelper {
|
||||||
className + "_Constructor_or_Destructor", classNamespace, false, false);
|
className + "_Constructor_or_Destructor", classNamespace, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the "this" data type is an empty placeholder for the class
|
|
||||||
// structure and replace it with the one that was just created by the script
|
|
||||||
//NEW
|
|
||||||
if (replaceClassStructures) {
|
|
||||||
replaceClassStructure(indeterminateFunction, className, classStruct);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue