mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-1581 Recover classes script deleting destructor and clone discovery improvements.
This commit is contained in:
parent
a9c928bb14
commit
22d4c2069b
5 changed files with 969 additions and 728 deletions
|
@ -36,7 +36,7 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
|||
|
||||
final int defaultPointerSize;
|
||||
|
||||
ExtendedFlatProgramAPI(Program program, TaskMonitor taskMonitor) {
|
||||
public ExtendedFlatProgramAPI(Program program, TaskMonitor taskMonitor) {
|
||||
|
||||
super(program, taskMonitor);
|
||||
defaultPointerSize = program.getDefaultPointerSize();
|
||||
|
@ -668,30 +668,31 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
|||
* Get the nth called function from calling function
|
||||
* @param callingFunction The calling function
|
||||
* @param callIndex the called function index (ie 1 = first called function)
|
||||
* @param getThunkedFunction if true get the thunked function, if false get the thunk itself, if
|
||||
* there is a thunk
|
||||
* @return the nth called function in calling function
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
public Function getCalledFunctionByCallOrder(Function callingFunction, int callIndex)
|
||||
throws CancelledException {
|
||||
public Function getCalledFunctionByCallOrder(Function callingFunction, int callIndex,
|
||||
boolean getThunkedFunction) throws CancelledException {
|
||||
|
||||
List<ReferenceAddressPair> orderedReferenceAddressPairsFromCallingFunction =
|
||||
getOrderedReferenceAddressPairsFromCallingFunction(callingFunction);
|
||||
if (callIndex > orderedReferenceAddressPairsFromCallingFunction.size()) {
|
||||
return null;
|
||||
int callNumber = 0;
|
||||
InstructionIterator instructions = callingFunction.getProgram()
|
||||
.getListing()
|
||||
.getInstructions(callingFunction.getBody(), true);
|
||||
while (instructions.hasNext() && callNumber < callIndex) {
|
||||
monitor.checkCanceled();
|
||||
Instruction instruction = instructions.next();
|
||||
if (instruction.getFlowType().isCall()) {
|
||||
callNumber++;
|
||||
if (callNumber == callIndex) {
|
||||
Function referencedFunction =
|
||||
getReferencedFunction(instruction.getMinAddress(), getThunkedFunction);
|
||||
return referencedFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceAddressPair referenceAddressPair =
|
||||
orderedReferenceAddressPairsFromCallingFunction.get(callIndex - 1);
|
||||
Address calledFunctionAddress = referenceAddressPair.getDestination();
|
||||
Function calledFunction = getFunctionAt(calledFunctionAddress);
|
||||
if (calledFunction == null) {
|
||||
return null;
|
||||
}
|
||||
if (calledFunction.isThunk()) {
|
||||
calledFunction = calledFunction.getThunkedFunction(true);
|
||||
}
|
||||
return calledFunction;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -885,11 +886,8 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
|||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCanceled();
|
||||
Address referenceAddress = referenceIterator.next();
|
||||
Address referencedAddress = getSingleReferencedAddress(referenceAddress);
|
||||
if (referencedAddress == null) {
|
||||
continue;
|
||||
}
|
||||
Function function = getFunctionAt(referencedAddress);
|
||||
|
||||
Function function = getReferencedFunction(referenceAddress, true);
|
||||
|
||||
// skip the ones that reference a vftable
|
||||
if (function != null) {
|
||||
|
@ -905,30 +903,43 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
|||
* @param address the given address
|
||||
* @param getThunkedFunction if true and referenced function is a thunk, get the thunked function
|
||||
* @return the referenced function or null if no function is referenced
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
public Function getReferencedFunction(Address address, boolean getThunkedFunction) {
|
||||
public Function getReferencedFunction(Address address, boolean getThunkedFunction)
|
||||
throws CancelledException {
|
||||
|
||||
Address referencedAddress = getSingleReferencedAddress(address);
|
||||
Reference[] referencesFrom = getReferencesFrom(address);
|
||||
|
||||
if (referencedAddress == null) {
|
||||
if (referencesFrom.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Function function = getFunctionAt(referencedAddress);
|
||||
for (Reference referenceFrom : referencesFrom) {
|
||||
|
||||
if (function == null) {
|
||||
return null;
|
||||
}
|
||||
monitor.checkCanceled();
|
||||
|
||||
if (!getThunkedFunction) {
|
||||
Address referencedAddress = referenceFrom.getToAddress();
|
||||
if (referencedAddress == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Function function = getFunctionAt(referencedAddress);
|
||||
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!getThunkedFunction) {
|
||||
return function;
|
||||
}
|
||||
|
||||
if (function.isThunk()) {
|
||||
function = function.getThunkedFunction(true);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
if (function.isThunk()) {
|
||||
function = function.getThunkedFunction(true);
|
||||
}
|
||||
|
||||
return function;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -258,7 +258,6 @@ public class RTTIClassRecoverer extends RecoveredClassHelper {
|
|||
memberFunctionsToProcess.addAll(recoveredClass.getConstructorList());
|
||||
memberFunctionsToProcess.addAll(recoveredClass.getDestructorList());
|
||||
memberFunctionsToProcess.addAll(recoveredClass.getIndeterminateList());
|
||||
|
||||
memberFunctionsToProcess.addAll(recoveredClass.getInlinedConstructorList());
|
||||
|
||||
Iterator<Function> memberFunctionIterator = memberFunctionsToProcess.iterator();
|
||||
|
|
|
@ -1077,20 +1077,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
|
|||
return true;
|
||||
}
|
||||
|
||||
private Data createVftableArray(Address vftableAddress, int numFunctionPointers)
|
||||
throws Exception {
|
||||
|
||||
api.clearListing(vftableAddress,
|
||||
vftableAddress.add((numFunctionPointers * defaultPointerSize - 1)));
|
||||
|
||||
DataType pointerDataType = dataTypeManager.getPointer(null);
|
||||
ArrayDataType vftableArrayDataType =
|
||||
new ArrayDataType(pointerDataType, numFunctionPointers, defaultPointerSize);
|
||||
|
||||
Data vftableArrayData = api.createData(vftableAddress, vftableArrayDataType);
|
||||
return vftableArrayData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check for a valid vtable at the given address
|
||||
* @param vtableAddress the given address
|
||||
|
|
|
@ -132,6 +132,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
return recoveredClasses;
|
||||
}
|
||||
|
||||
//TODO: decide whether to update to only include possible cds not all functions that
|
||||
// have ref to vftable
|
||||
// if decide to be more restrictive then need to move the method that weeds out inlines and
|
||||
// from the class cd lists
|
||||
createCalledFunctionMap(recoveredClasses);
|
||||
|
||||
// figure out class hierarchies using either RTTI or vftable refs
|
||||
|
@ -154,9 +158,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
// otherwise figure everything out from scratch
|
||||
else {
|
||||
monitor.setMessage("Figuring out class method types");
|
||||
// println(
|
||||
// "Figuring out class method types (constructor, destructor, inline constructor, " +
|
||||
// "inline destructor, deleting destructor, clone) ...");
|
||||
processConstructorAndDestructors(recoveredClasses);
|
||||
|
||||
}
|
||||
|
@ -171,7 +172,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
// using all the information found above, create the class structures, add the constructor,
|
||||
// destructor, vfunctions to class which finds the appropriate class structure and assigns
|
||||
// to "this" param
|
||||
//println("Creating class data types and applying class structures...");
|
||||
monitor.setMessage("Creating class data types and applying class structures");
|
||||
figureOutClassDataMembers(recoveredClasses);
|
||||
|
||||
|
@ -184,7 +184,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
if (!isPDBLoaded) {
|
||||
// create better vftable labels for multi vftable classes
|
||||
updateMultiVftableLabels(recoveredClasses);
|
||||
//println("Removing erroneous FID namespaces and corresponding class data types");
|
||||
removeEmptyClassesAndStructures();
|
||||
}
|
||||
|
||||
|
@ -463,10 +462,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
num1 + "," + num2 + "," + num3 + "," + num4 + ")",
|
||||
classNamespace, SourceType.ANALYSIS);
|
||||
}
|
||||
// else {
|
||||
// println(
|
||||
// "Failed to create a baseClassDescArray structure at " + address.toString());
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -553,8 +548,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
classHierarchyStructure = createClassHierarchyStructure(classHierarchyDescriptorAddress);
|
||||
|
||||
if (classHierarchyStructure == null) {
|
||||
// println("Failed to create a classHierarchyDescriptor structure at " +
|
||||
// classHierarchyDescriptorAddress.toString());
|
||||
symbolTable.removeSymbolSpecial(classHierarchySymbol);
|
||||
return null;
|
||||
}
|
||||
|
@ -729,12 +722,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
for (Reference refTo : referencesTo) {
|
||||
Address vftableMetaPointer = refTo.getFromAddress();
|
||||
if (vftableMetaPointer == null) {
|
||||
//println("can't retrieve meta address");
|
||||
continue;
|
||||
}
|
||||
Address vftableAddress = vftableMetaPointer.add(defaultPointerSize);
|
||||
if (vftableAddress == null) {
|
||||
//println("can't retrieve vftable address");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -905,8 +896,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
}
|
||||
}
|
||||
|
||||
List<Symbol> vftableSymbolsInNamespace =
|
||||
getVftablesInNamespace(vftableSymbols, classNamespace);
|
||||
List<Symbol> vftableSymbolsInNamespace = getClassVftableSymbols(classNamespace);
|
||||
|
||||
//if there are no vftables in this class then create a new class object and make it
|
||||
// non-vftable class
|
||||
|
@ -1204,7 +1194,6 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
}
|
||||
else if (symbols.size() > 1) {
|
||||
//TODO: throw exception?
|
||||
//println(recoveredClass.getName() + " has more than one base class array");
|
||||
}
|
||||
return classHierarchy;
|
||||
}
|
||||
|
@ -1292,7 +1281,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
private void processConstructorAndDestructors(List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException, InvalidInputException, DuplicateNameException, Exception {
|
||||
|
||||
// find deleting destructors using various mechanisms
|
||||
// update the global lists and class lists to narrow the cd lists
|
||||
trimConstructorDestructorLists(recoveredClasses);
|
||||
|
||||
// find deleting destructors
|
||||
findDeletingDestructors(recoveredClasses);
|
||||
|
||||
// use atexit param list to find more destructors
|
||||
|
@ -1316,9 +1308,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
// ones that could not be determined in earlier stages
|
||||
processRemainingIndeterminateConstructorsAndDestructors(recoveredClasses);
|
||||
|
||||
// use the known constructors and known vfunctions to figure out
|
||||
// clone functions
|
||||
findCloneFunctions(recoveredClasses);
|
||||
// use the known constructors and known vfunctions to figure out basic clone functions
|
||||
findBasicCloneFunctions(recoveredClasses);
|
||||
|
||||
// This has to be here. It needs all the info from the previously run methods to do this.
|
||||
// Finds the constructors that have multiple basic blocks, reference the vftable not in the
|
||||
|
@ -1338,6 +1329,8 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Method to recover parent information, including class offsets, vbase structure and its offset and address if applicable, and whether
|
||||
* the parent is regularly or virtually inherited
|
||||
|
@ -1845,11 +1838,10 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
getParentOrderMap(recoveredClass, ancestorsAllowedToMap);
|
||||
|
||||
if (sortedOrder.size() != parentOrderMap.size()) {
|
||||
// if (DEBUG) {
|
||||
// println(recoveredClass.getName() +
|
||||
// " has mismatch between vftable and parent order map sizes " +
|
||||
// sortedOrder.size() + " vs " + parentOrderMap.size());
|
||||
// }
|
||||
Msg.debug(this,
|
||||
recoveredClass.getName() +
|
||||
" has mismatch between vftable and parent order map sizes " +
|
||||
sortedOrder.size() + " vs " + parentOrderMap.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1955,6 +1947,7 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||
|
||||
Function referencedFunction =
|
||||
extendedFlatAPI.getReferencedFunction(classReferenceAddress, true);
|
||||
|
||||
if (referencedFunction == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue