From 11ec93bfdbf8bd73a4c22bf586ce474ef5deeea4 Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Mon, 4 Sep 2023 22:33:43 +0100 Subject: [PATCH] Fix the existing __vtbl_ptr_type instead of creating a new one --- .../symboltable/StabsImporter.java | 55 +++++++++---------- .../emotionengine/symboltable/StdumpAST.java | 5 -- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/main/java/ghidra/emotionengine/symboltable/StabsImporter.java b/src/main/java/ghidra/emotionengine/symboltable/StabsImporter.java index b986452..e350664 100644 --- a/src/main/java/ghidra/emotionengine/symboltable/StabsImporter.java +++ b/src/main/java/ghidra/emotionengine/symboltable/StabsImporter.java @@ -235,9 +235,6 @@ public void importDataTypes(StdumpAST.ImporterState importer) { } } - // Create a type for the vtable pointer. - createVtablePointerType(importer); - // Create all the top-level enums, structs and unions first. for(int i = 0; i < type_count; i++) { StdumpAST.Node node = importer.ast.deduplicatedTypes.get(i); @@ -248,14 +245,28 @@ public void importDataTypes(StdumpAST.ImporterState importer) { importer.types.add(importer.programTypeManager.addDataType(type, null)); } else if(node instanceof StdumpAST.InlineStructOrUnion) { StdumpAST.InlineStructOrUnion structOrUnion = (StdumpAST.InlineStructOrUnion) node; - DataType type = structOrUnion.createEmpty(importer); - importer.types.add(importer.programTypeManager.addDataType(type, null)); + boolean isVtablePointerType = structOrUnion.name.equals("__vtbl_ptr_type"); + if(isVtablePointerType) { + fixVtablePointerType(structOrUnion); + } + DataType createdType = structOrUnion.createEmpty(importer); + DataType addedType = importer.programTypeManager.addDataType(createdType, null); + if(isVtablePointerType) { + importer.vtablePointerType = addedType; + } + importer.types.add(addedType); + } else { importer.types.add(null); } monitor.setProgress(i); } - + + // If __vtbl_ptr_type isn't a struct, we assume it's a pointer. + if(importer.vtablePointerType == null) { + importer.vtablePointerType = PointerDataType.dataType; + } + // Fill in the structs and unions recursively. for(int i = 0; i < type_count; i++) { StdumpAST.Node node = importer.ast.deduplicatedTypes.get(i); @@ -270,33 +281,17 @@ public void importDataTypes(StdumpAST.ImporterState importer) { } } - public void createVtablePointerType(StdumpAST.ImporterState importer) { - Integer typeIndex = importer.typeNameToDeduplicatedTypeIndex.get("__vtbl_ptr_type"); - if(typeIndex == null) { - importer.vtablePointerTypeReportError = true; - importer.vtablePointerType = PointerDataType.dataType; - return; - } - - StdumpAST.Node node = importer.ast.deduplicatedTypes.get(typeIndex); - + public void fixVtablePointerType(StdumpAST.InlineStructOrUnion vtablePointerType) { // For some compiler versions __vtbl_ptr_type is just a function // pointer, for others it's a struct containing some integers and a - // function pointer. In the latter case the stab generated for that type - // is weird, so we recreate it from scratch. - if(node.sizeBits == 64) { - StructureDataType type = new StructureDataType("__vtbl_ptr_type_ccc", 8, importer.programTypeManager); - type.setDescription("Generated by the STABS importer."); - try { - type.replaceAtOffset(0, ShortDataType.dataType, 2, "__delta", null); - type.replaceAtOffset(2, ShortDataType.dataType, 2, "__index", null); - type.replaceAtOffset(4, PointerDataType.dataType, 4, "__pfn", null); - } catch(IllegalArgumentException e) { - importer.log.appendException(e); + // function pointer. In the latter case, the stab provided in the symbol + // table leads to incorrect decompilation of virtual function calls, so + // we need to fix it up here. + for(StdumpAST.Node field : vtablePointerType.fields) { + if(field.name.equals("__delta2")) { + vtablePointerType.fields.remove(field); + break; } - importer.vtablePointerType = importer.programTypeManager.addDataType(type, null); - } else { - importer.vtablePointerType = PointerDataType.dataType; } } diff --git a/src/main/java/ghidra/emotionengine/symboltable/StdumpAST.java b/src/main/java/ghidra/emotionengine/symboltable/StdumpAST.java index b4b693a..dba8d85 100644 --- a/src/main/java/ghidra/emotionengine/symboltable/StdumpAST.java +++ b/src/main/java/ghidra/emotionengine/symboltable/StdumpAST.java @@ -64,7 +64,6 @@ public static class ImporterState { HashMap forwardDeclaredTypes = new HashMap<>(); ArrayList prefixStack = new ArrayList<>(); // Used to name nested structs. DataType vtablePointerType; - boolean vtablePointerTypeReportError = false; // Ghidra objects. TaskMonitor monitor; @@ -422,10 +421,6 @@ public void fillVtable(StructureDataType dest, ImporterState importer) { } catch(IllegalArgumentException e) { importer.log.appendException(e); } - if(importer.vtablePointerTypeReportError) { - importer.log.appendMsg("STABS", "Cannot find type '__vtbl_ptr_type'. Generated C++ vtables may be incorrect."); - importer.vtablePointerTypeReportError = false; - } } } }