GP-4812 update vfunctions to use void* this instead of formal signature

This commit is contained in:
ghidra007 2024-08-02 20:39:03 +00:00
parent 7e9a24c6bc
commit 12fcbe63bc

View file

@ -432,9 +432,11 @@ public class RecoveredClassHelper {
continue; continue;
} }
Address functionAddress = reference.getFromAddress(); Address functionAddress = reference.getFromAddress();
Function secondHalfOfFunction = extendedFlatAPI.getReferencedFunction(functionAddress); Function secondHalfOfFunction =
extendedFlatAPI.getReferencedFunction(functionAddress);
if (secondHalfOfFunction != null) { if (secondHalfOfFunction != null) {
Map<Address,Function> functionCallMap2 = getFunctionCallMap(secondHalfOfFunction,false); Map<Address, Function> functionCallMap2 =
getFunctionCallMap(secondHalfOfFunction, false);
for (Address addr : functionCallMap2.keySet()) { for (Address addr : functionCallMap2.keySet()) {
monitor.checkCancelled(); monitor.checkCancelled();
functionCallMap.put(addr, functionCallMap2.get(addr)); functionCallMap.put(addr, functionCallMap2.get(addr));
@ -2264,7 +2266,8 @@ public class RecoveredClassHelper {
for (Function calledFunction : calledFunctions) { for (Function calledFunction : calledFunctions) {
monitor.checkCancelled(); monitor.checkCancelled();
if (getAllConstructors().contains(calledFunction) || getAllInlinedConstructors().contains(calledFunction)) { if (getAllConstructors().contains(calledFunction) ||
getAllInlinedConstructors().contains(calledFunction)) {
return true; return true;
} }
} }
@ -2272,8 +2275,6 @@ public class RecoveredClassHelper {
return false; return false;
} }
/** /**
* Method to determine if the given function calls a known denstructor or inlined destructor * Method to determine if the given function calls a known denstructor or inlined destructor
* @param Set of called functions * @param Set of called functions
@ -2286,7 +2287,8 @@ public class RecoveredClassHelper {
for (Function calledFunction : calledFunctions) { for (Function calledFunction : calledFunctions) {
monitor.checkCancelled(); monitor.checkCancelled();
if (getAllDestructors().contains(calledFunction) || getAllInlinedDestructors().contains(calledFunction)) { if (getAllDestructors().contains(calledFunction) ||
getAllInlinedDestructors().contains(calledFunction)) {
return true; return true;
} }
} }
@ -2294,7 +2296,8 @@ public class RecoveredClassHelper {
return false; return false;
} }
private boolean callsOwnFunction(RecoveredClass recoveredClass, Set<Function> calledFunctions) throws CancelledException { private boolean callsOwnFunction(RecoveredClass recoveredClass, Set<Function> calledFunctions)
throws CancelledException {
for (Function calledFunction : calledFunctions) { for (Function calledFunction : calledFunctions) {
monitor.checkCancelled(); monitor.checkCancelled();
@ -2306,10 +2309,8 @@ public class RecoveredClassHelper {
return false; return false;
} }
private Set<Function> getCalledFunctions(Function callingFunction) throws CancelledException { private Set<Function> getCalledFunctions(Function callingFunction) throws CancelledException {
Set<Function> calledFunctions = new HashSet<Function>(); Set<Function> calledFunctions = new HashSet<Function>();
InstructionIterator instructions = callingFunction.getProgram() InstructionIterator instructions = callingFunction.getProgram()
@ -2571,7 +2572,8 @@ public class RecoveredClassHelper {
* @param recoveredClass the given class object * @param recoveredClass the given class object
* @return true if class has a vbase destructor, false if not * @return true if class has a vbase destructor, false if not
*/ */
private boolean hasValidVbaseDestructor(RecoveredClass recoveredClass) throws CancelledException { private boolean hasValidVbaseDestructor(RecoveredClass recoveredClass)
throws CancelledException {
Function vBaseDestructor = recoveredClass.getVBaseDestructor(); Function vBaseDestructor = recoveredClass.getVBaseDestructor();
StringBuffer string = new StringBuffer(); StringBuffer string = new StringBuffer();
@ -4453,7 +4455,7 @@ public class RecoveredClassHelper {
String nameField = vfunction.getName(); String nameField = vfunction.getName();
FunctionDefinition functionDataType = FunctionDefinition functionDataType =
new FunctionDefinitionDataType(vfunction, true); new FunctionDefinitionDataType(vfunction, false);
if (!vfunction.getName().equals(functionDefName)) { if (!vfunction.getName().equals(functionDefName)) {
functionDataType.setName(functionDefName); functionDataType.setName(functionDefName);
@ -4467,24 +4469,38 @@ public class RecoveredClassHelper {
nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber; nameField = DEFAULT_VFUNCTION_PREFIX + vfunctionNumber;
// get function sig from child class // get function sig from a child class
Function childVirtualFunction = Function childVirtualFunction =
getChildVirtualFunction(recoveredClass, vftableAddress, vfunctionNumber); getChildVirtualFunction(recoveredClass, vfunctionNumber);
// if it is null it will just use the purecall function definition since
// it can't find a child one to use to replace it
if (childVirtualFunction != null) { if (childVirtualFunction != null) {
functionDataType = functionDataType =
new FunctionDefinitionDataType(childVirtualFunction, true); new FunctionDefinitionDataType(childVirtualFunction, false);
functionDataType.setReturnType(childVirtualFunction.getReturnType()); functionDataType.setReturnType(childVirtualFunction.getReturnType());
Symbol childFunctionSymbol = Symbol childFunctionSymbol =
symbolTable.getPrimarySymbol(childVirtualFunction.getEntryPoint()); symbolTable.getPrimarySymbol(childVirtualFunction.getEntryPoint());
// if the child function has a default name, rename the function definition // if the child function has a default name, rename the function definition
// data type to the "vfunction<vfunctionNumber>" name // data type to the "vfunction<vfunctionNumber>" name
if (childFunctionSymbol.getSource() == SourceType.DEFAULT) { if (childFunctionSymbol.getSource() != SourceType.DEFAULT) {
nameField = childFunctionSymbol.getName();
}
}
functionDataType.setName(nameField); functionDataType.setName(nameField);
}
}
comment = recoveredClass.getName() + " pure " + comment; comment = recoveredClass.getName() + " pure " + comment;
}
ParameterDefinition[] arguments = functionDataType.getArguments();
// if the vfunction is a thiscall then replace the classStruct* this with voidPtr
// so that it can be used generically for all related members of the class family
if (arguments.length > 0 && arguments[0].getName().equals("this")) {
VoidDataType voidDT = new VoidDataType();
PointerDataType voidPtr = new PointerDataType(voidDT);
ParameterDefinition parameterDefinition = arguments[0];
parameterDefinition.setDataType(voidPtr);
} }
PointerDataType functionPointerDataType = PointerDataType functionPointerDataType =
@ -4515,9 +4531,12 @@ public class RecoveredClassHelper {
* @param recoveredClass the given class * @param recoveredClass the given class
* @param virtualFunctionNumber the virtual function offset into the table * @param virtualFunctionNumber the virtual function offset into the table
* @return a child class virtual function at the given offset * @return a child class virtual function at the given offset
* @throws CancelledException if cancelled
*/ */
private Function getChildVirtualFunction(RecoveredClass recoveredClass, Address vftableAddress, private Function getChildVirtualFunction(RecoveredClass recoveredClass,
int virtualFunctionNumber) { int virtualFunctionNumber) throws CancelledException {
Function nonThisFunction = null;
List<RecoveredClass> childClasses = recoveredClass.getChildClasses(); List<RecoveredClass> childClasses = recoveredClass.getChildClasses();
if (childClasses.isEmpty()) { if (childClasses.isEmpty()) {
@ -4526,16 +4545,18 @@ public class RecoveredClassHelper {
// The child functions should all have the same function signature so just get any one of them // 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 // if for some reason they don't, still have to pick one and let user decide how to update
RecoveredClass childClass = childClasses.get(0); for (RecoveredClass childClass : childClasses) {
monitor.checkCancelled();
List<Address> childVftableAddresses = childClass.getVftableAddresses(); List<Address> childVftableAddresses = childClass.getVftableAddresses();
if (childVftableAddresses.isEmpty()) { if (childVftableAddresses.isEmpty()) {
return null; continue;
} }
// get the correct child vftable for the given parent class // get the correct child vftable for the given parent class
for (Address childVftableAddress : childVftableAddresses) { for (Address childVftableAddress : childVftableAddresses) {
RecoveredClass parentForVftable = childClass.getVftableBaseClass(childVftableAddress); RecoveredClass parentForVftable =
childClass.getVftableBaseClass(childVftableAddress);
if (parentForVftable == null) { if (parentForVftable == null) {
continue; continue;
} }
@ -4543,12 +4564,23 @@ public class RecoveredClassHelper {
List<Function> childVirtualFunctionsForGivenParent = List<Function> childVirtualFunctionsForGivenParent =
childClass.getVirtualFunctions(childVftableAddress); childClass.getVirtualFunctions(childVftableAddress);
if (childVirtualFunctionsForGivenParent.size() < virtualFunctionNumber) { if (childVirtualFunctionsForGivenParent.size() < virtualFunctionNumber) {
return null; continue;
} }
return childVirtualFunctionsForGivenParent.get(virtualFunctionNumber - 1); Function vfunction =
childVirtualFunctionsForGivenParent.get(virtualFunctionNumber - 1);
Parameter[] parameters = vfunction.getParameters();
if (parameters.length == 0) {
continue;
}
if (parameters[0].getName().equals("this")) {
return vfunction;
}
nonThisFunction = vfunction;
} }
} }
return null; }
return nonThisFunction; //or null if no vfunctions at all which should never happen
} }
/** /**
@ -5436,11 +5468,13 @@ public class RecoveredClassHelper {
} }
} }
private boolean callsOwnConstructorOrDestructor(RecoveredClass recoveredClass, Function function) throws CancelledException { private boolean callsOwnConstructorOrDestructor(RecoveredClass recoveredClass,
Function function) throws CancelledException {
Set<Function> calledFunctions = getCalledFunctions(function); Set<Function> calledFunctions = getCalledFunctions(function);
List<Function> constructorOrDestructorFunctions = recoveredClass.getConstructorOrDestructorFunctions(); List<Function> constructorOrDestructorFunctions =
recoveredClass.getConstructorOrDestructorFunctions();
for (Function cdFunction : constructorOrDestructorFunctions) { for (Function cdFunction : constructorOrDestructorFunctions) {
monitor.checkCancelled(); monitor.checkCancelled();
@ -7622,7 +7656,7 @@ public class RecoveredClassHelper {
return null; return null;
} }
FunctionSignature listingFunctionSignature = vfunction.getSignature(true); FunctionSignature listingFunctionSignature = vfunction.getSignature(false);
FunctionDefinition componentFunctionDefinition = FunctionDefinition componentFunctionDefinition =
getComponentFunctionDefinition(structureComponent); getComponentFunctionDefinition(structureComponent);
@ -8195,7 +8229,7 @@ public class RecoveredClassHelper {
vfunction = vfunction.getThunkedFunction(true); vfunction = vfunction.getThunkedFunction(true);
} }
FunctionSignature listingFunctionSignature = vfunction.getSignature(true); FunctionSignature listingFunctionSignature = vfunction.getSignature(false);
if (listingFunctionSignature.getName().contains("purecall")) { if (listingFunctionSignature.getName().contains("purecall")) {
return null; return null;