mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-25 10:29:51 +08:00
Merge remote-tracking branch
'origin/GP-6431_ghidra007_RTTIAnalyzer_handle_nondemangling_classnames--SQUASHED' into patch (Closes #8944)
This commit is contained in:
+27
@@ -1516,6 +1516,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||
|
||||
if (vbtableAddress != null) {
|
||||
if (isInvalidVbtable(vbtableAddress)) {
|
||||
continue;
|
||||
}
|
||||
return vbtableAddress;
|
||||
}
|
||||
}
|
||||
@@ -1541,6 +1544,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||
|
||||
if (vbtableAddress != null) {
|
||||
if (isInvalidVbtable(vbtableAddress)) {
|
||||
continue;
|
||||
}
|
||||
return vbtableAddress;
|
||||
}
|
||||
}
|
||||
@@ -1549,6 +1555,27 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
||||
|
||||
}
|
||||
|
||||
private boolean isInvalidVbtable(Address address) {
|
||||
|
||||
// check to see if already has a non-default symbol that is not vbtable
|
||||
Symbol symbol = program.getSymbolTable().getPrimarySymbol(address);
|
||||
if (symbol.getSource() != SourceType.DEFAULT &&
|
||||
!symbol.getName().contains("vbtable")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check to see if table contains an address reference
|
||||
// if it is an address then is very unlikely this is a vbtable since
|
||||
// it needs offset values and most are either large negatives (FFFFF....) or small offsets
|
||||
// both of which are not valid addresses in a normal PE binary
|
||||
Address referencedAddress = extendedFlatAPI.getPointer(address);
|
||||
if (program.getMemory().contains(referencedAddress)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to find the address of the vbtable referenced at the given offset in the given function
|
||||
* @param fillStructHelper a reusable {@link FillOutStructureHelper} instance to be used
|
||||
|
||||
+24
-6
@@ -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
|
||||
|
||||
+23
-4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+5
-1
@@ -321,7 +321,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