Merge remote-tracking branch 'origin/GP-12_emteere_demangleSymbolApplicaton'

This commit is contained in:
ghidra1 2020-07-23 09:26:29 -04:00
commit d9cc6b1b83
2 changed files with 62 additions and 32 deletions

View file

@ -142,7 +142,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
// Someone has already added arguments or return to the function signature
if (symbol.getSymbolType() == SymbolType.FUNCTION) {
Function function = (Function) symbol.getObject();
if (function.getSignatureSource() != SourceType.DEFAULT) {
if (function.getSignatureSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
return true;
}
}
@ -176,8 +176,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
* @param log the error log
* @return the demangled object; null if unsuccessful
*/
protected DemangledObject demangle(String mangled, DemanglerOptions options,
MessageLog log) {
protected DemangledObject demangle(String mangled, DemanglerOptions options, MessageLog log) {
DemangledObject demangled = null;
try {
@ -232,9 +231,8 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
failMessage += errorMessage;
}
log.appendMsg(getName(),
"Failed to apply mangled symbol at " + address + "; name: " +
demangled.getMangledString() + failMessage);
log.appendMsg(getName(), "Failed to apply mangled symbol at " + address + "; name: " +
demangled.getMangledString() + failMessage);
}
protected String cleanSymbol(Address address, String name) {

View file

@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import ghidra.app.cmd.disassemble.DisassembleCommand;
import ghidra.app.cmd.function.*;
import ghidra.app.util.NamespaceUtils;
import ghidra.program.database.data.DataTypeUtilities;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.*;
@ -359,8 +360,8 @@ public class DemangledFunction extends DemangledObject {
//if existing function signature is user defined - add demangled label only
boolean makePrimary = (function.getSignatureSource() != SourceType.USER_DEFINED);
Symbol demangledSymbol = applyDemangledName(function.getEntryPoint(), makePrimary,
false, program);
Symbol demangledSymbol =
applyDemangledName(function.getEntryPoint(), makePrimary, false, program);
if (demangledSymbol == null) {
return false;
}
@ -379,7 +380,7 @@ public class DemangledFunction extends DemangledObject {
signature.setVarArgs(true);
}
if (!function.isExternal() && isParameterMismatch(function, signature)) {
bookmarkParameterMismatch(program, function.getEntryPoint(), args);
bookmarkParameterMismatch(program, function.getEntryPoint());
return true;
}
@ -412,26 +413,15 @@ public class DemangledFunction extends DemangledObject {
return false;
}
private void bookmarkParameterMismatch(Program program, Address address,
List<ParameterDefinitionImpl> args) {
private void bookmarkParameterMismatch(Program program, Address address) {
if (parameters.isEmpty()) {
return;
}
int pointerSize = program.getDefaultPointerSize();
BookmarkManager bookmarkManager = program.getBookmarkManager();
for (int i = 0; i < args.size(); i++) {
if (args.get(i).getLength() > pointerSize) {
bookmarkManager.setBookmark(address, BookmarkType.ANALYSIS, "Demangler",
"Couldn't apply demangled signature - probably due to datatype that is too " +
"large to fit in a parameter");
}
}
bookmarkManager.setBookmark(address, BookmarkType.ANALYSIS, "Demangler",
"Couldn't apply demangled signature - bad parameter number match (" + args.size() +
") in a function in a namespace");
"Couldn't apply demangled signature - mismatch with existing signature");
}
static void maybeCreateUndefined(Program program, Address address) {
@ -543,14 +533,14 @@ public class DemangledFunction extends DemangledObject {
}
private boolean isParameterMismatch(Function func, FunctionSignature signature) {
int existingParameterCount = func.getParameterCount();
// If this function is not in a namespace, we don't care if the parameters mismatch,
// just apply them.
if (namespace == null || namespace.getName().startsWith("__")) {
// Default source types can be overridden
if (func.getSignatureSource() == SourceType.DEFAULT) {
return false;
}
int existingParameterCount = func.getParameterCount();
// If we don't know the parameters, and have already decided on This calling
// convention. is not a problem.
String callingConventionName = func.getCallingConventionName();
@ -558,8 +548,14 @@ public class DemangledFunction extends DemangledObject {
return false;
}
// Default source types can be overridden
if (func.getSignatureSource() == SourceType.DEFAULT) {
// are the data types already on the signature better than analysis provided ones
if (isDefinedFunctionDataTypes(func)) {
return true;
}
// If this function is not in a namespace, we don't care if the parameters mismatch,
// just apply them.
if (namespace == null || namespace.getName().startsWith("__")) {
return false;
}
@ -602,6 +598,43 @@ public class DemangledFunction extends DemangledObject {
return false;
}
/**
* check if the return/param data types were defined by better than analysis (user, import)
*
* @param func the function to check
* @return true if the parameters are not undefined, or are of a higher source type.
*/
protected boolean isDefinedFunctionDataTypes(Function func) {
Parameter[] funcParams = func.getParameters();
for (Parameter parameter : funcParams) {
if (parameter.isAutoParameter()) {
// automatic parameter, is OK.
continue;
}
// check for default type of data type
DataType dt = parameter.getDataType();
dt = DataTypeUtilities.getBaseDataType(dt);
if (dt == null || Undefined.isUndefined(dt)) {
continue;
}
// if the parameters source is higher than
if (parameter.getSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
return true;
}
}
// if already a return type and this one has a return type
DataType returnDT = func.getReturnType();
returnDT = DataTypeUtilities.getBaseDataType(returnDT);
if (!(returnDT == null || Undefined.isUndefined(returnDT)) &&
this.getReturnType() != null) {
return true;
}
return false;
}
/**
* Overloaded operators with more than 1 parameter are global
* and therefore not contained inside a class.
@ -726,11 +759,10 @@ public class DemangledFunction extends DemangledObject {
Structure structure = (Structure) existingType;
if (structure == null) {
structure = DemangledDataType.createPlaceHolderStructure(className,
classNamespace);
structure = DemangledDataType.createPlaceHolderStructure(className, classNamespace);
}
structure = (Structure) dataTypeManager.resolve(structure,
DataTypeConflictHandler.DEFAULT_HANDLER);
structure =
(Structure) dataTypeManager.resolve(structure, DataTypeConflictHandler.DEFAULT_HANDLER);
return structure;
}