mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-19 16:40:38 -09:00
GP-6431 updated RTTI analyzer to handle case where class name cannot be demangled. Some improvement to RTTI script vbtable determination of invalid tables.
This commit is contained in:
@@ -22,10 +22,10 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
/**
|
||||
* This command will create a TypeDescriptor data type. Since unsized arrays are not properly
|
||||
@@ -133,8 +133,10 @@ public class CreateTypeDescriptorBackgroundCmd
|
||||
|
||||
Program program = model.getProgram();
|
||||
String demangledName = model.getDemangledTypeDescriptor();
|
||||
|
||||
// if cannot demangle then use the mangled name
|
||||
if (demangledName == null) {
|
||||
return false;
|
||||
demangledName = model.getOriginalTypename();
|
||||
}
|
||||
String prefix = demangledName + " ";
|
||||
|
||||
@@ -147,9 +149,25 @@ public class CreateTypeDescriptorBackgroundCmd
|
||||
// Label
|
||||
Namespace classNamespace = model.getDescriptorAsNamespace();
|
||||
|
||||
if (classNamespace == null) {
|
||||
Msg.error(RttiUtil.class, "Cannot get namespace from model " + model.getAddress());
|
||||
return false;
|
||||
// if cannot demangle then use the mangled name as the namespace
|
||||
if (classNamespace == null || classNamespace.isGlobal()) {
|
||||
Msg.error(RttiUtil.class, "Cannot get demangled namespace from model " +
|
||||
model.getAddress() + " so will use the mangled name for the namespace");
|
||||
try {
|
||||
classNamespace = program.getSymbolTable()
|
||||
.getOrCreateNameSpace(program.getGlobalNamespace(), demangledName,
|
||||
SourceType.IMPORTED);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
// ok if it is duplicate as it was likely created in another rtti handling method
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.error(TypeDescriptorModel.class,
|
||||
"Failed to create mangled namespace: " + e.getMessage());
|
||||
classNamespace = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If PDB had been run, then the namespace here might already have been promoted to
|
||||
|
||||
@@ -28,11 +28,9 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.DumbMemBufferImpl;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
@@ -473,6 +471,10 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
||||
return hasComplexType() ? demangledDataType.getOriginalDemangled() : null;
|
||||
}
|
||||
|
||||
public String getOriginalTypename() {
|
||||
return originalTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets just the name of the type descriptor.
|
||||
* @return the name of the thing referred to by this descriptor, or null if it couldn't
|
||||
@@ -583,6 +585,23 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
||||
Program program = getProgram();
|
||||
namespace = DemangledObject.createNamespace(program, demangledDataType,
|
||||
program.getGlobalNamespace(), false);
|
||||
|
||||
// if for some reason the mangled name can't be demangled, use the mangled name
|
||||
if (namespace.isGlobal()) {
|
||||
try {
|
||||
namespace = program.getSymbolTable()
|
||||
.getOrCreateNameSpace(program.getGlobalNamespace(), originalTypeName,
|
||||
SourceType.IMPORTED);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
// ok if it is duplicate as it was likely created in another rtti handling method
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.error(TypeDescriptorModel.class,
|
||||
"Failed to create namespace: " + e.getMessage());
|
||||
namespace = null;
|
||||
}
|
||||
}
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public class CreateVfTableBackgroundCmd extends AbstractCreateDataBackgroundCmd<
|
||||
String demangledTypeDescriptor = rtti0Model.getDemangledTypeDescriptor();
|
||||
String prefixString = ((demangledTypeDescriptor != null)
|
||||
? (demangledTypeDescriptor + Namespace.DELIMITER)
|
||||
: "");
|
||||
: rtti0Model.getOriginalTypename() + Namespace.DELIMITER);
|
||||
data.setComment(CommentType.EOL, "terminator for " + prefixString + VF_TABLE_LABEL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -313,7 +313,11 @@ public class RttiUtil {
|
||||
public static String getDescriptorTypeNamespace(TypeDescriptorModel rtti0Model) {
|
||||
String descriptorTypeNamespace = rtti0Model.getDescriptorTypeNamespace(); // Can be null.
|
||||
if (descriptorTypeNamespace == null) {
|
||||
descriptorTypeNamespace = ""; // Couldn't get namespace so leave it off.
|
||||
|
||||
descriptorTypeNamespace = rtti0Model.getOriginalTypename();
|
||||
|
||||
Msg.warn(RttiUtil.class, rtti0Model.getAddress().toString() +
|
||||
": Could not demangle TypeDescriptor namespace so using the mangled string as the namespace.");
|
||||
}
|
||||
return descriptorTypeNamespace;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user