mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-1311 In RecoverClassesFromRTTIScript support, removed the 'this *' from vfunction definitions to enable generic class assignment and allowed purecall vfunction pointer to be replaced with pointers to correct class vfunction definition.
This commit is contained in:
parent
766ff7f72e
commit
a4349ba443
1 changed files with 91 additions and 23 deletions
|
@ -4529,14 +4529,40 @@ public class RecoveredClassUtils {
|
||||||
// of using the function name of "purecall" and prepend "pure" to the comment so
|
// of using the function name of "purecall" and prepend "pure" to the comment so
|
||||||
// they know it is pure virtual function, ie not actually implemented in the parent class
|
// they know it is pure virtual function, ie not actually implemented in the parent class
|
||||||
String nameField = vfunction.getName();
|
String nameField = vfunction.getName();
|
||||||
|
|
||||||
|
FunctionDefinition functionDataType =
|
||||||
|
new FunctionDefinitionDataType(vfunction, true);
|
||||||
|
|
||||||
|
functionDataType.setReturnType(vfunction.getReturnType());
|
||||||
|
|
||||||
|
// if the function is a purecall need to create the function definition using
|
||||||
|
// the equivalent child virtual function signature
|
||||||
if (nameField.contains("purecall")) {
|
if (nameField.contains("purecall")) {
|
||||||
|
|
||||||
nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber;
|
nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber;
|
||||||
|
|
||||||
|
// get function sig from child class
|
||||||
|
Function childVirtualFunction =
|
||||||
|
getChildVirtualFunction(recoveredClass, vftableAddress, vfunctionNumber);
|
||||||
|
if (childVirtualFunction != null) {
|
||||||
|
functionDataType =
|
||||||
|
new FunctionDefinitionDataType(childVirtualFunction, true);
|
||||||
|
functionDataType.setReturnType(childVirtualFunction.getReturnType());
|
||||||
|
Symbol childFunctionSymbol =
|
||||||
|
symbolTable.getPrimarySymbol(childVirtualFunction.getEntryPoint());
|
||||||
|
|
||||||
|
// if the child function has a default name, rename the function definition
|
||||||
|
// data type to the "vfunction<vfunctionNumber>" name
|
||||||
|
if (childFunctionSymbol.getSource() == SourceType.DEFAULT) {
|
||||||
|
functionDataType.setName(nameField);
|
||||||
|
}
|
||||||
|
}
|
||||||
comment = recoveredClass.getName() + " pure " + comment;
|
comment = recoveredClass.getName() + " pure " + comment;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerDataType functionPointerDataType =
|
PointerDataType functionPointerDataType =
|
||||||
createFunctionSignaturePointerDataType(vfunction, classPath);
|
createFunctionSignaturePointerDataType(functionDataType, classPath);
|
||||||
|
|
||||||
vftableStruct.add(functionPointerDataType, nameField,
|
vftableStruct.add(functionPointerDataType, nameField,
|
||||||
classCommentPrefix + " " + comment);
|
classCommentPrefix + " " + comment);
|
||||||
|
@ -4558,6 +4584,47 @@ public class RecoveredClassUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get a child class virtual function at the given offset into the correct virtual function table
|
||||||
|
* @param recoveredClass the given class
|
||||||
|
* @param virtualFunctionNumber the virtual function offset into the table
|
||||||
|
* @return a child class virtual function at the given offset
|
||||||
|
*/
|
||||||
|
private Function getChildVirtualFunction(RecoveredClass recoveredClass, Address vftableAddress,
|
||||||
|
int virtualFunctionNumber) {
|
||||||
|
|
||||||
|
List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
|
||||||
|
if (childClasses.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The child functions should all have the same function signature so just get any one of them
|
||||||
|
// if for some reason they don't, still have to pick one and let user decide how to update
|
||||||
|
RecoveredClass childClass = childClasses.get(0);
|
||||||
|
|
||||||
|
List<Address> childVftableAddresses = childClass.getVftableAddresses();
|
||||||
|
if (childVftableAddresses.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the correct child vftable for the given parent class
|
||||||
|
for (Address childVftableAddress : childVftableAddresses) {
|
||||||
|
RecoveredClass parentForVftable = childClass.getVftableBaseClass(childVftableAddress);
|
||||||
|
if (parentForVftable == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parentForVftable.equals(recoveredClass)) {
|
||||||
|
List<Function> childVirtualFunctionsForGivenParent =
|
||||||
|
childClass.getVirtualFunctions(childVftableAddress);
|
||||||
|
if (childVirtualFunctionsForGivenParent.size() < virtualFunctionNumber) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return childVirtualFunctionsForGivenParent.get(virtualFunctionNumber - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to give default names to the vfunctions in the given vftable if they don't have a name already. If they are a clone or deleting destructor name them accordingly.
|
* Method to give default names to the vfunctions in the given vftable if they don't have a name already. If they are a clone or deleting destructor name them accordingly.
|
||||||
* @param recoveredClass the given class
|
* @param recoveredClass the given class
|
||||||
|
@ -4764,14 +4831,22 @@ public class RecoveredClassUtils {
|
||||||
classHierarchyIterator = classHierarchy.iterator();
|
classHierarchyIterator = classHierarchy.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionDefinition functionDataType = new FunctionDefinitionDataType(vfunction, true);
|
||||||
|
|
||||||
|
functionDataType.setReturnType(vfunction.getReturnType());
|
||||||
|
|
||||||
while (classHierarchyIterator.hasNext()) {
|
while (classHierarchyIterator.hasNext()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
||||||
RecoveredClass currentClass = classHierarchyIterator.next();
|
RecoveredClass currentClass = classHierarchyIterator.next();
|
||||||
List<Function> virtualFunctions = currentClass.getAllVirtualFunctions();
|
|
||||||
if (virtualFunctions.contains(vfunction)) {
|
CategoryPath currentClassPath = currentClass.getClassPath();
|
||||||
classPath = currentClass.getClassPath();
|
DataType existingDataType =
|
||||||
|
dataTypeManager.getDataType(currentClassPath, functionDataType.getName());
|
||||||
|
if (existingDataType != null) {
|
||||||
|
return currentClassPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return classPath;
|
return classPath;
|
||||||
|
|
||||||
|
@ -4779,40 +4854,33 @@ public class RecoveredClassUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param vfunction the given function
|
* @param functionDefDataType the function definition
|
||||||
* @param classPath the given data type manager classPath
|
* @param classPath the given data type manager classPath
|
||||||
* @return pointer to function signature data type
|
* @return pointer to function signature data type
|
||||||
* @throws DuplicateNameException if try to create same symbol name already in namespace
|
* @throws DuplicateNameException if try to create same symbol name already in namespace
|
||||||
*/
|
*/
|
||||||
private PointerDataType createFunctionSignaturePointerDataType(Function vfunction,
|
private PointerDataType createFunctionSignaturePointerDataType(
|
||||||
CategoryPath classPath) throws DuplicateNameException {
|
FunctionDefinition functionDefDataType, CategoryPath classPath)
|
||||||
|
throws DuplicateNameException {
|
||||||
|
|
||||||
FunctionDefinition functionDataType = (FunctionDefinitionDataType) vfunction.getSignature();
|
|
||||||
|
|
||||||
DataType returnType = vfunction.getReturnType();
|
|
||||||
|
|
||||||
functionDataType.setReturnType(returnType);
|
|
||||||
|
|
||||||
// If this data type doesn't exist in this folder make a new one
|
|
||||||
// otherwise use the existing one
|
|
||||||
DataType existingDataType =
|
DataType existingDataType =
|
||||||
dataTypeManager.getDataType(classPath, functionDataType.getName());
|
dataTypeManager.getDataType(classPath, functionDefDataType.getName());
|
||||||
|
|
||||||
PointerDataType functionPointerDataType;
|
PointerDataType functionPointerDataType;
|
||||||
|
|
||||||
|
// If the given function definition doesn't exist in this folder make a new one and
|
||||||
|
// make a pointer to it
|
||||||
if (existingDataType == null) {
|
if (existingDataType == null) {
|
||||||
functionDataType.setCategoryPath(classPath);
|
functionDefDataType.setCategoryPath(classPath);
|
||||||
functionDataType = (FunctionDefinition) dataTypeManager.addDataType(functionDataType,
|
functionPointerDataType = new PointerDataType(functionDefDataType, dataTypeManager);
|
||||||
DataTypeConflictHandler.DEFAULT_HANDLER);
|
|
||||||
functionPointerDataType = new PointerDataType(functionDataType);
|
|
||||||
}
|
}
|
||||||
|
// otherwise return a pointer to the existing one
|
||||||
else {
|
else {
|
||||||
functionPointerDataType = new PointerDataType(existingDataType);
|
functionPointerDataType = new PointerDataType(existingDataType);
|
||||||
}
|
}
|
||||||
return functionPointerDataType;
|
return functionPointerDataType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to add precomment inside functions containing inlined constructors at approximate
|
* Method to add precomment inside functions containing inlined constructors at approximate
|
||||||
* address of start of inlined function
|
* address of start of inlined function
|
||||||
|
@ -6868,7 +6936,7 @@ public class RecoveredClassUtils {
|
||||||
vfunction = thunkedFunction;
|
vfunction = thunkedFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionSignature listingFunctionSignature = vfunction.getSignature();
|
FunctionSignature listingFunctionSignature = vfunction.getSignature(true);
|
||||||
|
|
||||||
DataTypeComponent structureComponent = vfunctionStructure.getComponent(vfunctionIndex);
|
DataTypeComponent structureComponent = vfunctionStructure.getComponent(vfunctionIndex);
|
||||||
|
|
||||||
|
@ -7584,7 +7652,7 @@ public class RecoveredClassUtils {
|
||||||
vfunction = vfunction.getThunkedFunction(true);
|
vfunction = vfunction.getThunkedFunction(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionSignature listingFunctionSignature = vfunction.getSignature();
|
FunctionSignature listingFunctionSignature = vfunction.getSignature(true);
|
||||||
|
|
||||||
DataType componentDataType = structureComponent.getDataType();
|
DataType componentDataType = structureComponent.getDataType();
|
||||||
if (!(componentDataType instanceof Pointer)) {
|
if (!(componentDataType instanceof Pointer)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue