Skip to content

Commit

Permalink
GP-1464 RecoverClassesFromRTTIScript now consistently applies its cla…
Browse files Browse the repository at this point in the history
…ss structures in programs that have PDB information applied. Also, an option was added so users can decide whether to replace existing class data in thiscall functions regardless of whether they originated as PDB or not.
  • Loading branch information
ghidra007 committed Nov 10, 2021
1 parent 2c561c8 commit 0766c30
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void run() throws Exception {
}

RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
state.getTool(), this, false, false, false, monitor);
state.getTool(), this, false, false, false, false, monitor);

Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
if (classNamespace == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void run() throws Exception {
}

RecoveredClassUtils classUtils = new RecoveredClassUtils(currentProgram, currentLocation,
state.getTool(), this, false, false, false, monitor);
state.getTool(), this, false, false, false, false, monitor);

Namespace classNamespace = classUtils.getClassNamespace(currentAddress);
if (classNamespace == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// show shortened class template names in class structure field names
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 CONSTRUCTOR_BOOKMARK = "CONSTRUCTOR";
Expand Down Expand Up @@ -162,6 +168,7 @@ public void run() throws Exception {
recoverClassesFromRTTI = new RTTIWindowsClassRecoverer(currentProgram,
currentLocation, state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, hasDebugSymbols,
REPLACE_EXISTING_CLASS_STRUCTURES,
monitor);
}
else if (isGcc()) {
Expand All @@ -182,6 +189,7 @@ else if (isGcc()) {
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, currentLocation,
state.getTool(), this, BOOKMARK_FOUND_FUNCTIONS,
USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS, nameVfunctions, hasDebugSymbols,
REPLACE_EXISTING_CLASS_STRUCTURES,
monitor);
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ public class RTTIClassRecoverer extends RecoveredClassUtils {
TaskMonitor monitor;
boolean hasDebugSymbols;


RTTIClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions, boolean hasDebugSymbols,
boolean nameVfunctions, boolean hasDebugSymbols, boolean replaceClassStructures,
TaskMonitor monitor) {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
replaceClassStructures,
monitor);

this.program = program;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,19 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
new HashMap<RecoveredClass, Map<RecoveredClass, Long>>();

boolean isDwarfLoaded;
boolean replaceClassStructs;

public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions, boolean isDwarfLoaded, TaskMonitor monitor) {
boolean nameVfunctions, boolean isDwarfLoaded, boolean replaceExistingClassStructures,
TaskMonitor monitor) {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
replaceExistingClassStructures,
isDwarfLoaded,
monitor);
this.isDwarfLoaded = isDwarfLoaded;
this.replaceClassStructs = replaceExistingClassStructures;
}

@Override
Expand Down Expand Up @@ -2898,12 +2902,14 @@ private void processDataTypes(RecoveredClass recoveredClass)
Structure classStruct = createSimpleClassStructure(recoveredClass, vfPointerDataTypes);

// check for DWARF -- if none add c/d/etc to class
//TODO: if decide to replace dwarf data types then remove this check so the replaces
// in the following methods can replace the dwarf data types
if (!isDwarfLoaded) {

// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass);
addDestructorsToClassNamespace(recoveredClass, classStruct);
// addNonThisDestructorsToClassNamespace(recoveredClass);
// addVbaseDestructorsToClassNamespace(recoveredClass);
// addVbtableToClassNamespace(recoveredClass);
Expand All @@ -2914,15 +2920,16 @@ private void processDataTypes(RecoveredClass recoveredClass)
// createIndeterminateInlineComments(recoveredClass);

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass);
createIndeterminateLabels(recoveredClass, classStruct);
}

// This is done after the class structure is created and added to the dtmanager
// because if done before the class structures are created
// then empty classes will get auto-created in the wrong place
// when the vfunctions are put in the class

fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes);
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
classStruct);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {

public RTTIWindowsClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVFunctions, boolean isPDBLoaded,
boolean nameVFunctions, boolean isPDBLoaded, boolean replaceClassStructures,
TaskMonitor monitor) throws CancelledException {

super(program, location, tool, api, createBookmarks, useShortTemplates, nameVFunctions,
isPDBLoaded, monitor);
isPDBLoaded, replaceClassStructures, monitor);

this.isPDBLoaded = isPDBLoaded;

Expand Down Expand Up @@ -2245,32 +2245,35 @@ private void processDataTypes(RecoveredClass recoveredClass)

applyVbtableStructure(recoveredClass);

// pdb already has good names so only name if no pdb
if (!isPDBLoaded) {

// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass);
// Now that we have a class data type
// name constructor and destructor functions and put into the class namespace
// checks are internal for hasDebugSymbols since there
// are also replace methods that need to be called either way
addConstructorsToClassNamespace(recoveredClass, classStruct);
addDestructorsToClassNamespace(recoveredClass, classStruct);
addVbaseDestructorsToClassNamespace(recoveredClass, classStruct);

if (!hasDebugSymbols) {
addNonThisDestructorsToClassNamespace(recoveredClass);
addVbaseDestructorsToClassNamespace(recoveredClass);

addVbtableToClassNamespace(recoveredClass);

// add secondary label on functions with inlined constructors or destructors
createInlinedConstructorComments(recoveredClass);
createInlinedDestructorComments(recoveredClass);
createIndeterminateInlineComments(recoveredClass);

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass);
}

// add label on constructor destructor functions that could not be determined which were which
createIndeterminateLabels(recoveredClass, classStruct);

// This is done after the class structure is created and added to the dtmanager
// because if done before the class structures are created
// then empty classes will get auto-created in the wrong place
// when the vfunctions are put in the class

fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes);
fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
classStruct);

}

Expand Down
Loading

0 comments on commit 0766c30

Please sign in to comment.