diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java b/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java index 2b9f24a1b3..953a53b9ec 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java @@ -208,6 +208,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript { return; } + //run fixup old elf relocations script + runScript("FixElfExternalOffsetDataRelocationScript.java"); + hasDebugSymbols = isDwarfLoadedInProgram(); if (hasDwarf() && !hasDebugSymbols) { println( diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java index bf591f09b6..02936f413b 100644 --- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java +++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java @@ -57,6 +57,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { Address si_class_type_info = null; Address vmi_class_type_info = null; + int componentOffset; + List nonInheritedGccClasses = new ArrayList(); List singleInheritedGccClasses = new ArrayList(); List multiAndOrVirtuallyInheritedGccClasses = new ArrayList(); @@ -104,6 +106,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { @Override public List createRecoveredClasses() throws CancelledException, Exception { + setComponentOffset(); + processGccRTTI(); if (recoveredClasses == null) { Msg.debug(this, "Could not recover gcc rtti classes"); @@ -132,6 +136,32 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { } + private void setComponentOffset() { + + String processor = program.getLanguage().getProcessor().toString(); + if (processor.equals("x86") || processor.equals("MIPS") || processor.equals("PowerPC") || + processor.equals("RISCV")) { + + if (defaultPointerSize == 4) { + componentOffset = 8; + return; + } + if (defaultPointerSize == 8) { + componentOffset = 16; + return; + } + } + if (processor.equals("AARCH64")) { + componentOffset = 16; + return; + } + if (processor.equals("ARM")) { + componentOffset = 8; + return; + } + + } + private boolean isGcc() { if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) { @@ -1270,6 +1300,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { private Address createSpecialVtable(Address vtableAddress) throws CancelledException, InvalidInputException { + // if vtable is in external block don't try to create it because the full table isn't there + // but is external + if (program.getMemory().getBlock(vtableAddress).getName().equals("EXTERNAL")) { + return vtableAddress; + } + Symbol vtableSymbol = symbolTable.getPrimarySymbol(vtableAddress); api.clearListing(vtableAddress); @@ -1817,9 +1853,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager); CharDataType characterDT = new CharDataType(); - DataType pointer = dataTypeManager.getPointer(null); + + PointerTypedef classTypeInfoPtr = + new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset); + DataType charPointer = dataTypeManager.getPointer(characterDT); - classTypeInfoStructure.add(pointer, "classTypeinfoPtr", null); + classTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null); classTypeInfoStructure.add(charPointer, "typeinfoName", null); classTypeInfoStructure.setPackingEnabled(true); @@ -1834,10 +1873,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { classDataTypesCategoryPath, SI_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager); CharDataType characterDT = new CharDataType(); - DataType pointer = dataTypeManager.getPointer(null); + + PointerTypedef classTypeInfoPtr = + new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset); + DataType charPointer = dataTypeManager.getPointer(characterDT); - siClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null); + siClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null); siClassTypeInfoStructure.add(charPointer, "typeinfoName", null); DataType pointerToClassTypeInfoStruct = dataTypeManager.getPointer(classTypeInfoStructure); @@ -1898,10 +1940,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { CharDataType characterDT = new CharDataType(); UnsignedIntegerDataType unsignedIntDT = new UnsignedIntegerDataType(); - DataType pointer = dataTypeManager.getPointer(null); + PointerTypedef classTypeInfoPtr = + new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset); + DataType charPointer = dataTypeManager.getPointer(characterDT); - vmiClassTypeInfoStructure.add(pointer, "classTypeinfoPtr", null); + vmiClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null); vmiClassTypeInfoStructure.add(charPointer, "typeinfoName", null); vmiClassTypeInfoStructure.add(unsignedIntDT, "flags", null); vmiClassTypeInfoStructure.add(unsignedIntDT, "numBaseClasses", null); @@ -2905,7 +2949,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer { Map orderToParentMap = classToParentOrderMap.get(recoveredClass); - if (orderToParentMap.isEmpty()) { + if (orderToParentMap == null || orderToParentMap.isEmpty()) { throw new Exception( "Vmi class " + recoveredClass.getClassNamespace().getName(true) + " should have a parent in the classToParentOrderMap but doesn't");