mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-30 11:09:17 +08:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
+27
@@ -1516,6 +1516,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||||
|
|
||||||
if (vbtableAddress != null) {
|
if (vbtableAddress != null) {
|
||||||
|
if (isInvalidVbtable(vbtableAddress)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return vbtableAddress;
|
return vbtableAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1541,6 +1544,9 @@ public class RTTIWindowsClassRecoverer extends RTTIClassRecoverer {
|
|||||||
highFunction, recoveredClass, constructor, vbtableOffset);
|
highFunction, recoveredClass, constructor, vbtableOffset);
|
||||||
|
|
||||||
if (vbtableAddress != null) {
|
if (vbtableAddress != null) {
|
||||||
|
if (isInvalidVbtable(vbtableAddress)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return vbtableAddress;
|
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
|
* 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
|
* @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.data.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.symbol.Namespace;
|
import ghidra.program.model.symbol.Namespace;
|
||||||
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This command will create a TypeDescriptor data type. Since unsized arrays are not properly
|
* 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();
|
Program program = model.getProgram();
|
||||||
String demangledName = model.getDemangledTypeDescriptor();
|
String demangledName = model.getDemangledTypeDescriptor();
|
||||||
|
|
||||||
|
// if cannot demangle then use the mangled name
|
||||||
if (demangledName == null) {
|
if (demangledName == null) {
|
||||||
return false;
|
demangledName = model.getOriginalTypename();
|
||||||
}
|
}
|
||||||
String prefix = demangledName + " ";
|
String prefix = demangledName + " ";
|
||||||
|
|
||||||
@@ -147,9 +149,25 @@ public class CreateTypeDescriptorBackgroundCmd
|
|||||||
// Label
|
// Label
|
||||||
Namespace classNamespace = model.getDescriptorAsNamespace();
|
Namespace classNamespace = model.getDescriptorAsNamespace();
|
||||||
|
|
||||||
if (classNamespace == null) {
|
// if cannot demangle then use the mangled name as the namespace
|
||||||
Msg.error(RttiUtil.class, "Cannot get namespace from model " + model.getAddress());
|
if (classNamespace == null || classNamespace.isGlobal()) {
|
||||||
return false;
|
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
|
// 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.DumbMemBufferImpl;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import ghidra.program.model.symbol.Namespace;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.exception.CancelledException;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -473,6 +471,10 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
|||||||
return hasComplexType() ? demangledDataType.getOriginalDemangled() : null;
|
return hasComplexType() ? demangledDataType.getOriginalDemangled() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOriginalTypename() {
|
||||||
|
return originalTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets just the name of the type descriptor.
|
* 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
|
* @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();
|
Program program = getProgram();
|
||||||
namespace = DemangledObject.createNamespace(program, demangledDataType,
|
namespace = DemangledObject.createNamespace(program, demangledDataType,
|
||||||
program.getGlobalNamespace(), false);
|
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;
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ public class CreateVfTableBackgroundCmd extends AbstractCreateDataBackgroundCmd<
|
|||||||
String demangledTypeDescriptor = rtti0Model.getDemangledTypeDescriptor();
|
String demangledTypeDescriptor = rtti0Model.getDemangledTypeDescriptor();
|
||||||
String prefixString = ((demangledTypeDescriptor != null)
|
String prefixString = ((demangledTypeDescriptor != null)
|
||||||
? (demangledTypeDescriptor + Namespace.DELIMITER)
|
? (demangledTypeDescriptor + Namespace.DELIMITER)
|
||||||
: "");
|
: rtti0Model.getOriginalTypename() + Namespace.DELIMITER);
|
||||||
data.setComment(CommentType.EOL, "terminator for " + prefixString + VF_TABLE_LABEL);
|
data.setComment(CommentType.EOL, "terminator for " + prefixString + VF_TABLE_LABEL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -321,7 +321,11 @@ public class RttiUtil {
|
|||||||
public static String getDescriptorTypeNamespace(TypeDescriptorModel rtti0Model) {
|
public static String getDescriptorTypeNamespace(TypeDescriptorModel rtti0Model) {
|
||||||
String descriptorTypeNamespace = rtti0Model.getDescriptorTypeNamespace(); // Can be null.
|
String descriptorTypeNamespace = rtti0Model.getDescriptorTypeNamespace(); // Can be null.
|
||||||
if (descriptorTypeNamespace == 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;
|
return descriptorTypeNamespace;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user