mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch
'origin/GP-1315_add_option_to_remove_replaced_class_structures--SQUASHED' into Ghidra_10.1 (Closes #3443)
This commit is contained in:
commit
f22e05af3f
2 changed files with 84 additions and 0 deletions
|
@ -134,6 +134,24 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
|
|
||||||
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
|
private static final String INDETERMINATE_BOOKMARK = "INDETERMINATE";
|
||||||
|
|
||||||
|
// If replacedClassStructuresOption is set to the following, no replaced structures will be removed
|
||||||
|
// from the data type manager
|
||||||
|
private static final int DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES = 0;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
private static final int REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES = 1;
|
||||||
|
|
||||||
|
// 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 final int REMOVE_ALL_REPLACED_CLASS_STRUCTURES = 2;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
int replacedClassStructuresOption = DO_NOT_REMOVE_REPLACED_CLASS_STRUCTURES;
|
||||||
|
|
||||||
boolean programHasRTTIApplied = false;
|
boolean programHasRTTIApplied = false;
|
||||||
boolean hasDebugSymbols;
|
boolean hasDebugSymbols;
|
||||||
boolean isGcc = false;
|
boolean isGcc = false;
|
||||||
|
@ -283,6 +301,17 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
||||||
showGraph(graph);
|
showGraph(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (replacedClassStructuresOption == REMOVE_EMPTY_REPLACED_CLASS_STRUCTURES) {
|
||||||
|
println("Removing all empty replaced class structures from the data type manager");
|
||||||
|
recoverClassesFromRTTI.removeReplacedClassStructures(recoveredClasses, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replacedClassStructuresOption == 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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3536,6 +3536,7 @@ public class RecoveredClassUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
<<<<<<< HEAD
|
||||||
* Method to replace the program's current class structure, only if an empty placeholder structure,
|
* Method to replace the program's current class structure, only if an empty placeholder structure,
|
||||||
* with the one generated by this script
|
* with the one generated by this script
|
||||||
* @param function a class method with current class structure applied
|
* @param function a class method with current class structure applied
|
||||||
|
@ -3632,7 +3633,61 @@ public class RecoveredClassUtils {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue