GP-5500 add check that potential vftable address is in valid memory

block
This commit is contained in:
ghidra007 2025-03-18 18:11:33 +00:00
parent 6c00c68e2b
commit d43a827c7c

View file

@ -2711,11 +2711,11 @@ public class RecoveredClassHelper {
} }
// get only the functions from the ones that are not already processed structures // get only the functions from the ones that are not already processed structures
// return null if not an unprocessed table // return null if not an unprocessed table or if invalid
List<Function> virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol, List<Function> virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol,
allowNullFunctionPtrs, allowDefaultRefsInMiddle); allowNullFunctionPtrs, allowDefaultRefsInMiddle);
// the vftable has already been processed - skip it // the vftable has already been processed or invalid - skip it
if (virtualFunctions == null) { if (virtualFunctions == null) {
continue; continue;
} }
@ -2769,20 +2769,19 @@ public class RecoveredClassHelper {
return recoveredClasses; return recoveredClasses;
} }
//TODO: rework above method to call this so it works with both that and other calls
protected void updateClassWithVftable(RecoveredClass recoveredClass, Symbol vftableSymbol, protected void updateClassWithVftable(RecoveredClass recoveredClass, Symbol vftableSymbol,
boolean allowNullFunctionPtrs, boolean allowDefaultRefsInMiddle) throws Exception { boolean allowNullFunctionPtrs, boolean allowDefaultRefsInMiddle) throws Exception {
// get only the functions from the ones that are not already processed // get only the functions from the ones that are not already processed
// structures // structures
// return null if not an unprocessed table // return null if not an unprocessed table
Address vftableAddress = vftableSymbol.getAddress(); Address vftableAddress = vftableSymbol.getAddress();
Namespace vftableNamespace = vftableSymbol.getParentNamespace(); Namespace vftableNamespace = vftableSymbol.getParentNamespace();
List<Function> virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol, List<Function> virtualFunctions = getFunctionsFromVftable(vftableAddress, vftableSymbol,
allowNullFunctionPtrs, allowDefaultRefsInMiddle); allowNullFunctionPtrs, allowDefaultRefsInMiddle);
// the vftable has already been processed - skip it // the vftable has already been processed or is invalid - skip it
if (virtualFunctions == null) { if (virtualFunctions == null) {
return; return;
} }
@ -2797,15 +2796,10 @@ public class RecoveredClassHelper {
recoveredClass.addVftableAddress(vftableAddress); recoveredClass.addVftableAddress(vftableAddress);
recoveredClass.addVftableVfunctionsMapping(vftableAddress, virtualFunctions); recoveredClass.addVftableVfunctionsMapping(vftableAddress, virtualFunctions);
// add it to the running list of RecoveredClass objects
// recoveredClasses.add(recoveredClass);
} }
else { else {
recoveredClass.addVftableAddress(vftableAddress); recoveredClass.addVftableAddress(vftableAddress);
recoveredClass.addVftableVfunctionsMapping(vftableAddress, virtualFunctions); recoveredClass.addVftableVfunctionsMapping(vftableAddress, virtualFunctions);
// if (!recoveredClasses.contains(recoveredClass)) {
// recoveredClasses.add(recoveredClass);
// }
} }
@ -2975,9 +2969,9 @@ public class RecoveredClassHelper {
// pointing to are in the class already to determine size of array // pointing to are in the class already to determine size of array
// create vtable // create vtable
int numFunctionPointers = Integer numFunctionPointers =
createVftable(vftableAddress, allowNullFunctionPtrs, allowDefaultRefsInMiddle); createVftable(vftableAddress, allowNullFunctionPtrs, allowDefaultRefsInMiddle);
if (numFunctionPointers == 0) { if (numFunctionPointers == null || numFunctionPointers == 0) {
return null; return null;
} }
// make it an array // make it an array
@ -3043,16 +3037,28 @@ public class RecoveredClassHelper {
* @param vftableAddress the vftable address * @param vftableAddress the vftable address
* @param allowNullFunctionPtrs if true allow vftables to have null pointers * @param allowNullFunctionPtrs if true allow vftables to have null pointers
* @param allowDefaultRefsInMiddle if true allow default references into the middle of the table * @param allowDefaultRefsInMiddle if true allow default references into the middle of the table
* @return the created array of pointers Data or null * @return the number of functions in the table or null if none or in invalid block
* @throws CancelledException if cancelled * @throws CancelledException if cancelled
*/ */
public int createVftable(Address vftableAddress, boolean allowNullFunctionPtrs, public Integer createVftable(Address vftableAddress, boolean allowNullFunctionPtrs,
boolean allowDefaultRefsInMiddle) throws CancelledException { boolean allowDefaultRefsInMiddle) throws CancelledException {
int numFunctionPointers = 0; int numFunctionPointers = 0;
Address address = vftableAddress; Address address = vftableAddress;
MemoryBlock currentBlock = program.getMemory().getBlock(vftableAddress); MemoryBlock currentBlock = program.getMemory().getBlock(vftableAddress);
if (currentBlock == null) {
Msg.warn(this, "Cannot create vftable at " + vftableAddress.toString() +
" because it is in an invalid memory block.");
return null;
}
if (currentBlock.isExternalBlock() || !currentBlock.isInitialized()) {
Msg.warn(this, "Cannot create vftable at " + vftableAddress.toString() +
" because it is in an external or an uninitialized block.");
return null;
}
boolean stillInCurrentTable = true; boolean stillInCurrentTable = true;
while (address != null && currentBlock.contains(address) && stillInCurrentTable && while (address != null && currentBlock.contains(address) && stillInCurrentTable &&
extendedFlatAPI.isFunctionPointer(address, allowNullFunctionPtrs)) { extendedFlatAPI.isFunctionPointer(address, allowNullFunctionPtrs)) {