mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-5146 fixed rttiUtil issue resulting from previous pdb anon fix. Main fix was to remove incorrect pdb secondary symbols causing rtti script to blow up. Also updated to remove known functions from other class possible const/dest lists. Also updated to remove ticks from pdb rtti instead of just removing the symbols and recreating. This fixed the missing _forParent symbols so also updated script to handle for parent case now that it is getting them.
This commit is contained in:
parent
0411db7e88
commit
8892384b71
3 changed files with 103 additions and 33 deletions
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -120,7 +120,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
// They are either undefined bytes or code that is not in a function.
|
||||
private static final boolean FIXUP_PROGRAM = true;
|
||||
|
||||
// bookmark all constructor/destructor functions figured out by this script
|
||||
// bookmark all constructor/destructor functions recognized by script
|
||||
private static final boolean BOOKMARK_FOUND_FUNCTIONS = true;
|
||||
|
||||
// show a graph of class hierarchies after script is complete
|
||||
|
@ -323,12 +323,9 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
getNumberOfConstructorsOrDestructors(recoveredClasses) +
|
||||
" class member functions to assign.");
|
||||
|
||||
if (!hasDebugSymbols) {
|
||||
|
||||
if (BOOKMARK_FOUND_FUNCTIONS) {
|
||||
bookmarkFunctions(recoveredClasses);
|
||||
println("See Bookmark Manager for a list of functions by type.");
|
||||
}
|
||||
if (BOOKMARK_FOUND_FUNCTIONS) {
|
||||
bookmarkFunctions(recoveredClasses);
|
||||
println("See Bookmark Manager for a list of functions by type.");
|
||||
}
|
||||
|
||||
callOptionalOutputMethods(recoveredClasses, out);
|
||||
|
@ -468,17 +465,18 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
if (status == Status.FAILURE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// if any relocations for special typeinfo class symbols are unsupported then
|
||||
// determine where the symbol is located before determining if it is an issue
|
||||
if(status == Status.UNSUPPORTED) {
|
||||
if (status == Status.UNSUPPORTED) {
|
||||
|
||||
//if relocation symbol is the same as the symbol at the relcation address
|
||||
//then this situation is not an issue - it indicates a copy relocation at the
|
||||
//location of the special typeinfo vtable which is a use case that can be handled
|
||||
Address address = r.getAddress();
|
||||
Symbol symbolAtAddress = currentProgram.getSymbolTable().getSymbol(symbolName, address, currentProgram.getGlobalNamespace());
|
||||
if(symbolAtAddress != null) {
|
||||
Symbol symbolAtAddress = currentProgram.getSymbolTable()
|
||||
.getSymbol(symbolName, address, currentProgram.getGlobalNamespace());
|
||||
if (symbolAtAddress != null) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
|
@ -489,7 +487,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void analyzeProgramChanges(AddressSetView beforeChanges) throws Exception {
|
||||
|
||||
AddressSetView addressSet = currentProgram.getChanges().getAddressSet();
|
||||
|
|
|
@ -2562,7 +2562,11 @@ public class RecoveredClassHelper {
|
|||
Function function = functionIterator.next();
|
||||
Namespace namespace = function.getParentNamespace();
|
||||
if (!namespace.equals(recoveredClass.getClassNamespace())) {
|
||||
continue;
|
||||
Symbol functionSymbol = function.getSymbol();
|
||||
if (functionSymbol.getSource().equals(SourceType.IMPORTED)) {
|
||||
functionIterator.remove(); // remove named functions belonging to other class
|
||||
}
|
||||
continue; // continue in either case to skip functions in other namespaces
|
||||
}
|
||||
String name = function.getName();
|
||||
if (name.equals(recoveredClass.getName())) {
|
||||
|
@ -8465,7 +8469,8 @@ public class RecoveredClassHelper {
|
|||
Symbol symbol = symbols.next();
|
||||
if (symbol.getName().equals("vftable") ||
|
||||
symbol.getName().substring(1).startsWith("vftable") ||
|
||||
symbol.getName().contains("vftable_for_")) {
|
||||
symbol.getName().contains("vftable_for_") ||
|
||||
symbol.getName().contains("vftable{for")) {
|
||||
vftableSymbols.add(symbol);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import ghidra.app.cmd.data.TypeDescriptorModel;
|
|||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.PseudoDisassembler;
|
||||
import ghidra.app.util.datatype.microsoft.MSDataTypeUtils;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
import ghidra.app.util.demangler.DemanglerUtil;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.listing.*;
|
||||
|
@ -73,29 +75,71 @@ public class RttiUtil {
|
|||
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
|
||||
// See if the symbol already exists for the RTTI data.
|
||||
// See if the symbol already exists for the RTTI data
|
||||
Symbol matchingSymbol = symbolTable.getSymbol(rttiSuffix, rttiAddress, classNamespace);
|
||||
if (matchingSymbol != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: This code was originally put here to skip applying labels the pdb put down if the
|
||||
// above check failed but symbols were similar. This check has been removed because of
|
||||
// cases where this check stopped the full namespace path from being created. The code is
|
||||
// here commented out because we might want to use this to do extra checking and possibly
|
||||
// remove the similar symbol instead of leaving it as a secondary symbol.
|
||||
// Don't create it if a similar symbol already exists at the address of the data.
|
||||
// SymbolIterator symbols = symbolTable.getSymbolsAsIterator(rttiAddress);
|
||||
// for (Symbol symbol : symbols) {
|
||||
// String name = symbol.getName();
|
||||
// if (name.contains(rttiSuffix)) {
|
||||
// return false; // Similar symbol already exists.
|
||||
// }
|
||||
// }
|
||||
// check for similar symbol
|
||||
DemangledObject matchingDemangledObject = null;
|
||||
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(rttiAddress);
|
||||
for (Symbol symbol : symbols) {
|
||||
String name = symbol.getName();
|
||||
|
||||
// if mangled get the matching demangled object if there is one and save for after loop
|
||||
// in case symbols are not demangled yet
|
||||
DemangledObject demangledObject = DemanglerUtil.demangle(name);
|
||||
if (demangledObject != null && demangledObject.getName().contains(rttiSuffix)) {
|
||||
matchingDemangledObject = demangledObject;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Similar symbol already exists - more checking/fixing needed
|
||||
if (name.contains(rttiSuffix)) {
|
||||
|
||||
// check for differing namespace to correct pdb in rare cases
|
||||
Namespace currentNamespace = symbol.getParentNamespace();
|
||||
if (!currentNamespace.equals(classNamespace)) {
|
||||
Msg.warn(program, "Removed incorrect pdb symbol: " + symbol.getName(true));
|
||||
symbol.delete();
|
||||
continue;
|
||||
}
|
||||
// if symbol contains the matching string and ticks, remove the ticks
|
||||
if (replaceSymbolWithNoTicks(symbol)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if it gets here then there were no demangled symbols that contained the rttisuffix
|
||||
// indicating that the mangled matching symbol has not been demangled yet and needs to be
|
||||
// demangled
|
||||
if (matchingDemangledObject != null) {
|
||||
|
||||
String name = matchingDemangledObject.getName();
|
||||
if (name.contains(rttiSuffix)) {
|
||||
|
||||
try {
|
||||
Symbol symbol = symbolTable.createLabel(rttiAddress, name, classNamespace,
|
||||
SourceType.IMPORTED);
|
||||
// Set the symbol to be primary so that the demangler
|
||||
// won't demangle again
|
||||
symbol.setPrimary();
|
||||
if (replaceSymbolWithNoTicks(symbol)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
//fall through and make a symbol using the rttiSuffix string even though
|
||||
// it might really be one with extra information
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// if code gets here then no pdb info so have to make the symbol here
|
||||
try {
|
||||
// Ignore imported mangled symbol because demangling would add tick marks into the name.
|
||||
// The name created here is better. Set the symbol to be primary so that the demangler
|
||||
// won't demangle.
|
||||
Symbol symbol = symbolTable.createLabel(rttiAddress, rttiSuffix, classNamespace,
|
||||
SourceType.IMPORTED);
|
||||
symbol.setPrimary();
|
||||
|
@ -108,6 +152,30 @@ public class RttiUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to remove all ' and ` from symbol if it starts with `
|
||||
* @param symbol the symbol
|
||||
* @return true if the symbol has been replaced, false otherwise
|
||||
*/
|
||||
private static boolean replaceSymbolWithNoTicks(Symbol symbol) {
|
||||
|
||||
String name = symbol.getName();
|
||||
if (name.startsWith("`")) {
|
||||
name = name.replace("'", "").replace("`", "");
|
||||
try {
|
||||
symbol.setName(name, symbol.getSource());
|
||||
return true;
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
return false;
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to promote the given namespace to a class namespace
|
||||
* @param program the given program
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue