mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-10 14:21:00 +08:00
GP-6526 - MicrosoftDemangler - fix logic and tests for argument tags
This commit is contained in:
@@ -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.
|
||||
@@ -227,6 +227,14 @@ public class MDDataType extends MDType {
|
||||
}
|
||||
// super.insert(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this type as though it is an template or function argument
|
||||
* @param the builder to which the insertion is made
|
||||
*/
|
||||
public void insertAsArg(StringBuilder builder) {
|
||||
insert(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
+5
-1
@@ -65,12 +65,16 @@ public class MDComplexType extends MDDataType {
|
||||
super.insert(builder);
|
||||
}
|
||||
|
||||
public void insertWithoutComplexTag(StringBuilder builder) {
|
||||
@Override
|
||||
public void insertAsArg(StringBuilder builder) {
|
||||
// TODO: look at what needs to be done to get rid of this?
|
||||
if ((builder.length() != 0) && (builder.charAt(0) != ' ')) {
|
||||
dmang.insertString(builder, " ");
|
||||
}
|
||||
qualifiedName.insert(builder);
|
||||
if (dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
||||
super.insert(builder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class MDArrayBasicType extends MDModifierType {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void insertReferredType(StringBuilder builder) {
|
||||
protected void insertReferredType(StringBuilder builder, boolean isArg) {
|
||||
StringBuilder arrayBuilder = new StringBuilder();
|
||||
arrayBuilder.append("[]");
|
||||
MDType dt = this.refType;
|
||||
|
||||
+21
-6
@@ -204,12 +204,27 @@ public abstract class MDModifierType extends MDDataType {
|
||||
dmang.cleanOutput(builder); // 20170714
|
||||
}
|
||||
|
||||
protected void insertReferredType(StringBuilder builder) {
|
||||
refType.insert(builder);
|
||||
protected void insertReferredType(StringBuilder builder, boolean asArg) {
|
||||
// LATER: Investigate weather we can change refType definition from MDType to MDDataType
|
||||
if (refType instanceof MDDataType mdt && asArg) {
|
||||
mdt.insertAsArg(builder);
|
||||
}
|
||||
else {
|
||||
refType.insert(builder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(StringBuilder builder) {
|
||||
insertInternal(builder, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAsArg(StringBuilder builder) {
|
||||
insertInternal(builder, true);
|
||||
}
|
||||
|
||||
private void insertInternal(StringBuilder builder, boolean asArg) {
|
||||
// Added 20170412 to try have available to get MSFT affect on this
|
||||
// "invalid" condition.
|
||||
// if (cvMod.isBasedPtrBased()) {
|
||||
@@ -274,12 +289,12 @@ public abstract class MDModifierType extends MDDataType {
|
||||
// builder.insertString(" "); //20160701
|
||||
if (refType instanceof MDArrayReferencedType) {
|
||||
// 20170714 refType.insert(builder);
|
||||
insertReferredType(builder);// 20170714
|
||||
insertReferredType(builder, asArg);// 20170714
|
||||
}
|
||||
else if (cvMod.isPinPointer()) {
|
||||
StringBuilder refBuilder = new StringBuilder();
|
||||
// 20170714 refType.insert(refBuilder);
|
||||
insertReferredType(refBuilder);// 20170714
|
||||
insertReferredType(refBuilder, asArg);// 20170714
|
||||
dmang.appendString(refBuilder, " ");
|
||||
if (!(cvMod.isQuestionType() ||
|
||||
(cvMod.isPointerType() && (refType instanceof MDVoidDataType)))) {
|
||||
@@ -296,7 +311,7 @@ public abstract class MDModifierType extends MDDataType {
|
||||
else if (cvMod.isCLIArray()) {
|
||||
StringBuilder refBuilder = new StringBuilder();
|
||||
// 20170714 refType.insert(refBuilder);
|
||||
insertReferredType(refBuilder);// 20170714
|
||||
insertReferredType(refBuilder, asArg);// 20170714
|
||||
if (!(refType instanceof MDVoidDataType)) {
|
||||
cvMod.insertManagedPropertiesPrefix(refBuilder);
|
||||
// cvMod.insertManagedProperties(refBuilder);
|
||||
@@ -319,7 +334,7 @@ public abstract class MDModifierType extends MDDataType {
|
||||
// }
|
||||
// //Could be function (function pointer or function) or data.
|
||||
// 20170714 refType.insert(builder);
|
||||
insertReferredType(builder);// 20170714
|
||||
insertReferredType(builder, asArg);// 20170714
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -119,13 +119,7 @@ public class MDArgumentsList extends MDParsableItem {
|
||||
}
|
||||
firstArgDone = true;
|
||||
StringBuilder argBuilder = new StringBuilder();
|
||||
if (arg instanceof MDComplexType ct &&
|
||||
!dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
||||
ct.insertWithoutComplexTag(argBuilder);
|
||||
}
|
||||
else {
|
||||
arg.insert(argBuilder);
|
||||
}
|
||||
arg.insertAsArg(argBuilder);
|
||||
dmang.appendString(builder, argBuilder.toString().trim());
|
||||
// doing toString() allows the Based5 "bug" to be cleaned per parameter.
|
||||
// possible: dmang.appendString(builder, arg.toString().trim());
|
||||
|
||||
+2
-8
@@ -202,19 +202,13 @@ public class MDTemplateArgumentsList extends MDParsableItem {
|
||||
if (args.size() > 0) {
|
||||
// boolean firstArgDone = false;
|
||||
Iterator<Boolean> delimIter = commaDelimiter.iterator();
|
||||
for (MDType arg : args) {
|
||||
for (MDDataType arg : args) {
|
||||
if (delimIter.next()) {
|
||||
dmang.appendString(builder, ",");
|
||||
}
|
||||
// firstArgDone = true;
|
||||
StringBuilder argBuilder = new StringBuilder();
|
||||
if (arg instanceof MDComplexType ct &&
|
||||
!dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
||||
ct.insertWithoutComplexTag(argBuilder);
|
||||
}
|
||||
else {
|
||||
arg.insert(argBuilder);
|
||||
}
|
||||
arg.insertAsArg(argBuilder);
|
||||
dmang.appendString(builder, argBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
+50
@@ -299,6 +299,56 @@ public class DemangledFunctionTest extends AbstractGhidraHeadlessIntegrationTest
|
||||
assertTrue(demangled instanceof DemangledFunction);
|
||||
assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY));
|
||||
|
||||
String className =
|
||||
"F<E::D::G<E::D::H<bool_(__cdecl*const)(C::B_const&),0>,bool,C::B_const&>_>";
|
||||
String functionName = className + "<E::D::A<bool,C::B_const&>_>";
|
||||
|
||||
Function function = assertFunction(functionName, addr);
|
||||
assertNoBookmarkAt(addr);
|
||||
|
||||
Symbol[] symbols = symbolTable.getSymbols(addr);
|
||||
assertEquals(2, symbols.length);
|
||||
assertEquals(functionName, symbols[0].getName());
|
||||
assertEquals(mangled, symbols[1].getName());
|
||||
|
||||
// Check for the Class 'this' pointer
|
||||
Parameter[] parameters = function.getParameters();
|
||||
assertEquals(2, parameters.length);
|
||||
Parameter p1 = parameters[0];
|
||||
assertEquals("this", p1.getName());
|
||||
assertEquals(className + " *", p1.getDataType().toString());
|
||||
|
||||
Namespace ns = symbols[0].getParentNamespace();
|
||||
assertEquals(className, ns.getName(false));
|
||||
ns = ns.getParentNamespace();
|
||||
assertEquals("E", ns.getName(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionThisPointerWithTags() throws Exception {
|
||||
|
||||
//
|
||||
// Test a function within a class that has a 'this' pointer
|
||||
//
|
||||
|
||||
String mangled =
|
||||
"??$?0V?$A@_NABW4B@C@@@D@E@@@?$F@V?$G@U?$H@Q6A_NABW4B@C@@@Z$0A@@D@E@@_NABW4B@C@@@D@E@@@E@@QAE@ABV?$F@V?$A@_NABW4B@C@@@D@E@@@1@@Z";
|
||||
Address addr = addr("0x0101");
|
||||
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
symbolTable.createLabel(addr, mangled, SourceType.IMPORTED);
|
||||
|
||||
MicrosoftDemangler demangler = new MicrosoftDemangler();
|
||||
MangledContext mangledContext =
|
||||
demangler.createMangledContext(mangled,
|
||||
MicrosoftDemanglerOptions.DEFAULT_UNDERLYING_OUTPUT, program, addr);
|
||||
DemanglerOptions options = mangledContext.getOptions();
|
||||
// TODO: need direct way to change "for function" vs. just address and program; which might mean MicrosoftDemanglerContext
|
||||
//mangledContext.setIsFunction(true);
|
||||
DemangledObject demangled = demangler.demangle(mangledContext);
|
||||
assertTrue(demangled instanceof DemangledFunction);
|
||||
assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY));
|
||||
|
||||
String className =
|
||||
"F<class_E::D::G<struct_E::D::H<bool_(__cdecl*const)(enum_C::B_const&),0>,bool,enum_C::B_const&>_>";
|
||||
String functionName = className + "<class_E::D::A<bool,enum_C::B_const&>_>";
|
||||
|
||||
Reference in New Issue
Block a user