GP-6515 - MicrosoftDemangler - fix warnings and tests; change default UDT tags; change source of defaults of options panels

This commit is contained in:
ghizard
2026-02-27 13:40:48 -05:00
parent 872d4d2c92
commit 8a8245f8b9
9 changed files with 67 additions and 85 deletions
@@ -20,6 +20,7 @@ import ghidra.app.util.datatype.microsoft.DataValidationOptions;
import ghidra.app.util.datatype.microsoft.MSDataTypeUtils;
import ghidra.app.util.demangler.*;
import ghidra.app.util.demangler.microsoft.MicrosoftDemangler;
import ghidra.app.util.demangler.microsoft.MicrosoftMangledContext;
import ghidra.docking.settings.SettingsImpl;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
@@ -594,7 +595,7 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
SourceType.IMPORTED);
}
catch (DuplicateNameException e) {
// ok if it is duplicate as it was likely created in another rtti handling method
// ok if it is duplicate as it was likely created in another rtti handling method
}
catch (InvalidInputException e) {
Msg.error(TypeDescriptorModel.class,
@@ -624,7 +625,7 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
Address address) {
MicrosoftDemangler demangler = new MicrosoftDemangler();
try {
MangledContext mangledContext =
MicrosoftMangledContext mangledContext =
demangler.createMangledContext(mangledString, null, program, address);
DemangledDataType demangledType = demangler.demangleType(mangledContext);
if (isPermittedType(demangledType)) {
@@ -16,7 +16,8 @@
package ghidra.app.plugin.core.analysis;
import ghidra.app.util.demangler.*;
import ghidra.app.util.demangler.microsoft.*;
import ghidra.app.util.demangler.microsoft.MicrosoftDemangler;
import ghidra.app.util.demangler.microsoft.MicrosoftDemanglerOptions;
import ghidra.app.util.demangler.microsoft.options.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.OptionType;
@@ -34,40 +35,16 @@ public class MicrosoftDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
"After a function is created, this analyzer will attempt to demangle " +
"the name and apply datatypes to parameters.";
public static final String OPTION_NAME_APPLY_SIGNATURE = "Apply Function Signatures";
private static final String OPTION_DESCRIPTION_APPLY_SIGNATURE =
"Apply any recovered function signature, in addition to the function name";
public static final String OPTION_NAME_APPLY_CALLING_CONVENTION =
"Apply Function Calling Conventions";
private static final String OPTION_DESCRIPTION_APPLY_CALLING_CONVENTION =
"Apply any recovered function signature calling convention";
private static final String OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS =
"Demangle Only Known Mangled Symbols";
private static final String OPTION_DESCRIPTION_USE_KNOWN_PATTERNS =
"Only demangle symbols that follow known compiler mangling patterns. " +
"Leaving this option off may cause non-mangled symbols to get demangled.";
public static final String OPTION_NAME_MS_C_INTERPRETATION =
"C-Style Symbol Interpretation";
private static final String OPTION_DESCRIPTION_MS_C_INTERPRETATION =
"When ambiguous, treat C-Style mangled symbol as: function, variable," +
" or function if a function exists";
private boolean applyFunctionSignature = true;
private boolean applyCallingConvention = true;
private boolean demangleOnlyKnownPatterns = false;
private MsCInterpretation interpretation = MsCInterpretation.FUNCTION_IF_EXISTS;
private static final String APPLY_OPTIONS_LABEL = "msdApplyOptions";
public static final String APPLY_OPTIONS_LABEL = "msdApplyOptions";
private static final String OUTPUT_OPTIONS_LABEL = "msdOutputOptions";
private MsdApplyOption applyOption;
private MsdOutputOption outputOption;
private MicrosoftDemanglerOptions msOptions;
public MicrosoftDemanglerAnalyzer() {
super(NAME, DESCRIPTION);
msOptions = new MicrosoftDemanglerOptions();
demangler = new MicrosoftDemangler();
setDefaultEnablement(true);
}
@@ -82,14 +59,18 @@ public class MicrosoftDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
HelpLocation help = new HelpLocation("AutoAnalysisPlugin", "Demangler_Analyzer");
options.registerOption(APPLY_OPTIONS_LABEL, OptionType.CUSTOM_TYPE,
new MsdApplyOption(), help, "Configures how demangling is applied",
new MsdApplyOption(msOptions.demangleOnlyKnownPatterns(), msOptions.applySignature(),
msOptions.applyCallingConvention(), msOptions.getInterpretation()),
help, "Configures how demangling is applied",
() -> new MsdApplyOptionsEditor());
applyOption =
(MsdApplyOption) options.getCustomOption(APPLY_OPTIONS_LABEL, null);
options.registerOption(OUTPUT_OPTIONS_LABEL, OptionType.CUSTOM_TYPE,
new MsdOutputOption(), help, "Controls demangled output",
() -> new MsdOutputOptionsEditor());
new MsdOutputOption(msOptions.getUseEncodedAnonymousNamespace(),
msOptions.getApplyUdtArgumentTypeTag()),
help, "Controls demangled output", () -> new MsdOutputOptionsEditor());
outputOption = (MsdOutputOption) options.getCustomOption(OUTPUT_OPTIONS_LABEL, null);
}
@@ -98,19 +79,18 @@ public class MicrosoftDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
applyOption = (MsdApplyOption) options.getCustomOption(APPLY_OPTIONS_LABEL, applyOption);
outputOption =
(MsdOutputOption) options.getCustomOption(OUTPUT_OPTIONS_LABEL, outputOption);
msOptions.setApplySignature(applyOption.applySignature());
msOptions.setApplyCallingConvention(applyOption.applyCallingConvention());
msOptions.setDemangleOnlyKnownPatterns(applyOption.demangleOnlyKnownPatterns());
msOptions.setInterpretation(applyOption.getInterpretation());
msOptions.setUseEncodedAnonymousNamespace(outputOption.getUseEncodedAnonymousNamespace());
msOptions.setApplyUdtArgumentTypeTag(outputOption.getApplyUdtArgumentTypeTag());
msOptions.setErrorOnRemainingChars(true);
}
@Override
protected DemanglerOptions getOptions() {
MicrosoftDemanglerOptions options = new MicrosoftDemanglerOptions();
options.setApplySignature(applyOption.applySignature());
options.setApplyCallingConvention(applyOption.applyCallingConvention());
options.setDemangleOnlyKnownPatterns(applyOption.demangleOnlyKnownPatterns());
options.setInterpretation(applyOption.getInterpretation());
options.setUseEncodedAnonymousNamespace(outputOption.getUseEncodedAnonymousNamespace());
options.setApplyUdtArgumentTypeTag(outputOption.getApplyUdtArgumentTypeTag());
options.setErrorOnRemainingChars(true);
return options;
return msOptions;
}
@Override
@@ -69,7 +69,7 @@ public class MicrosoftDemanglerOptions extends DemanglerOptions {
errorOnRemainingChars = true;
interpretation = MsCInterpretation.FUNCTION_IF_EXISTS;
useEncodedAnonymousNamespace = true;
applyUdtArgumentTypeTag = true;
applyUdtArgumentTypeTag = false;
}
/**
@@ -38,20 +38,20 @@ public class MsdApplyOption extends DemanglerOptions implements CustomOption {
private static final String APPLY_CALLING_CONVENTION = "applyFunctionCallingConventions";
private static final String MS_C_INTERPRETATION = "C-StyleSymbolInterpretation";
private static boolean DEFAULT_DEMANGLE_USE_KNOWN_PATTERNS = false;
private static boolean DEFAULT_APPLY_SIGNATURE = true;
private static boolean DEFAULT_APPLY_CALLING_CONVENTION = true;
private static MsCInterpretation DEFAULT_MS_C_INTERPRETATION =
MsCInterpretation.FUNCTION_IF_EXISTS;
private MsCInterpretation interpretation;
public MsdApplyOption() {
// required for persistence, but also using for overriding initializations of parent
setDemangleOnlyKnownPatterns(DEFAULT_DEMANGLE_USE_KNOWN_PATTERNS);
setApplySignature(DEFAULT_APPLY_SIGNATURE);
setApplyCallingConvention(DEFAULT_APPLY_CALLING_CONVENTION);
interpretation = DEFAULT_MS_C_INTERPRETATION;
// required for persistence, but must set some initial values even though they will
// get overridden by writeState.
this(false, false, false, MsCInterpretation.FUNCTION_IF_EXISTS);
}
public MsdApplyOption(boolean demangleOnlyKnownPatternsArg, boolean applySignatureArg,
boolean applyCallingConventionArg, MsCInterpretation interpretationArg) {
setDemangleOnlyKnownPatterns(demangleOnlyKnownPatternsArg);
setApplySignature(applySignatureArg);
setApplyCallingConvention(applyCallingConventionArg);
interpretation = interpretationArg;
}
/**
@@ -194,11 +194,9 @@ public class MsdApplyOptionsEditor extends PropertyEditorSupport
}
private MsdApplyOption cloneNamespaceValues() {
MsdApplyOption newOptions = new MsdApplyOption();
newOptions.setApplySignature(signatureCb.isSelected());
newOptions.setApplyCallingConvention(callingConventionCb.isSelected());
newOptions.setDemangleOnlyKnownPatterns(knownPatternsCb.isSelected());
newOptions.setInterpretation((MsCInterpretation) interpretationComboBox.getSelectedItem());
MsdApplyOption newOptions = new MsdApplyOption(knownPatternsCb.isSelected(),
signatureCb.isSelected(), callingConventionCb.isSelected(),
(MsCInterpretation) interpretationComboBox.getSelectedItem());
return newOptions;
}
@@ -18,6 +18,7 @@ package ghidra.app.util.demangler.microsoft.options;
import java.util.Objects;
import ghidra.app.plugin.core.analysis.MicrosoftDemanglerAnalyzer;
import ghidra.app.util.demangler.microsoft.MicrosoftDemanglerOptions;
import ghidra.framework.options.CustomOption;
import ghidra.framework.options.GProperties;
@@ -33,14 +34,18 @@ public class MsdOutputOption implements CustomOption {
private static final String USE_ENCODED_ANONYMOUS_NAMESPACE = "useEncodedAnonymousNamespace";
private static final String APPLY_TEMPLATE_ARG_TAGS = "applyTagsTemplateArgumentTags";
private static boolean DEFAULT_USE_ENCODED_ANONYMOUS_NAMESPACE = true;
private static boolean DEFAULT_APPLY_TEMPLATE_ARG_TAGS = true;
private boolean useEncodedAnonymousNamespace = DEFAULT_USE_ENCODED_ANONYMOUS_NAMESPACE;
private boolean applyUdtArgumentTypeTag = DEFAULT_APPLY_TEMPLATE_ARG_TAGS;
private boolean useEncodedAnonymousNamespace;
private boolean applyUdtArgumentTypeTag;
public MsdOutputOption() {
// required for persistence
// required for persistence, but must set some initial values even though they will
// get overridden by writeState.
this(false, false);
}
public MsdOutputOption(boolean useEncodedAnonymousNamespace, boolean applyUdtArgumentTypeTag) {
this.useEncodedAnonymousNamespace = useEncodedAnonymousNamespace;
this.applyUdtArgumentTypeTag = applyUdtArgumentTypeTag;
}
/**
@@ -135,9 +135,8 @@ public class MsdOutputOptionsEditor extends PropertyEditorSupport implements Cus
}
private MsdOutputOption cloneNamespaceValues() {
MsdOutputOption newOption = new MsdOutputOption();
newOption.setUseEncodedAnonymousNamespace(useEncodedAnonNsCb.isSelected());
newOption.setApplyUdtArgumentTypeTag(useUdtTagsCb.isSelected());
MsdOutputOption newOption =
new MsdOutputOption(useEncodedAnonNsCb.isSelected(), useUdtTagsCb.isSelected());
return newOption;
}
@@ -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.
@@ -21,6 +21,7 @@ import org.junit.Before;
import org.junit.Test;
import ghidra.app.cmd.label.AddLabelCmd;
import ghidra.app.util.demangler.microsoft.options.MsdApplyOption;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.Options;
import ghidra.program.database.ProgramBuilder;
@@ -70,7 +71,7 @@ public class MicrosoftDemanglerAnalyzerTest extends AbstractGhidraHeadedIntegrat
Address addr = addr("0x110");
createSymbol(addr, mangled);
setOption(MicrosoftDemanglerAnalyzer.OPTION_NAME_APPLY_SIGNATURE, true);
setApplySignatureOption(true);
analyze();
@@ -88,7 +89,7 @@ public class MicrosoftDemanglerAnalyzerTest extends AbstractGhidraHeadedIntegrat
Address addr = addr("0x110");
createSymbol(addr, mangled);
setOption(MicrosoftDemanglerAnalyzer.OPTION_NAME_APPLY_SIGNATURE, false);
setApplySignatureOption(false);
analyze();
@@ -129,22 +130,21 @@ public class MicrosoftDemanglerAnalyzerTest extends AbstractGhidraHeadedIntegrat
tx(program, () -> analyzer.added(program, program.getMemory(), TaskMonitor.DUMMY, log));
}
private void setOption(String optionName, boolean doUse) {
private void setApplySignatureOption(boolean doUse) {
String fullOptionName = analyzer.getName() + Options.DELIMITER_STRING + optionName;
Options options = program.getOptions("Analyzers");
// Analyzers . Demangler Microsoft . msdApplyOptions . applyFunctionSignatures
for (String name : options.getOptionNames()) {
if (name.equals(fullOptionName)) {
tx(program, () -> options.setBoolean(optionName, doUse));
Options analyzerOptions = program.getOptions(
"Analyzers" + Options.DELIMITER_STRING + MicrosoftDemanglerAnalyzer.NAME);
// we must call this manually, since we are not using a tool
analyzer.optionsChanged(options, program);
return;
}
}
MsdApplyOption applyOption =
(MsdApplyOption) analyzerOptions
.getCustomOption(MicrosoftDemanglerAnalyzer.APPLY_OPTIONS_LABEL, null);
fail("Could not find option '" + optionName + "'");
tx(program, () -> {
applyOption.setApplySignature(doUse);
});
analyzer.optionsChanged(analyzerOptions, program);
}
private void registerOptions() {
@@ -164,7 +164,6 @@ public abstract class AbstractComplexTypeApplier extends MsDataTypeApplier {
// type. We did not dig into where it got steered wrong, but presumed it was because of
// what we stated above.
context.getOptions().setUseEncodedAnonymousNamespace(false);
context.getOptions().setApplyUdtArgumentTypeTag(false);
try {
mdemangler.demangleType(context);
MDDataType mdDataType = mdemangler.getMdType();