GP-3934 Added options to autoVT task and script. Made example options script for headless. Updated Documentation. Updated and added tests.

This commit is contained in:
ghidra007 2023-11-20 22:32:31 +00:00
parent f98258aa74
commit d4d703368b
11 changed files with 1542 additions and 280 deletions

View file

@ -9,6 +9,7 @@ data/version.tracking.theme.properties||GHIDRA||||END|
src/main/docs/VTClasses.png||GHIDRA||reviewed||END|
src/main/docs/VTGuiImpl.png||GHIDRA||reviewed||END|
src/main/help/help/TOC_Source.xml||GHIDRA||reviewed||END|
src/main/help/help/topics/VersionTrackingPlugin/VT_AutoVT.html||GHIDRA||||END|
src/main/help/help/topics/VersionTrackingPlugin/VT_Correlators.html||GHIDRA||||END|
src/main/help/help/topics/VersionTrackingPlugin/VT_Preconditions.html||GHIDRA||||END|
src/main/help/help/topics/VersionTrackingPlugin/VT_Tool.html||GHIDRA||||END|

View file

@ -13,21 +13,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// An example of how to create Version Tracking session, run some correlators to find matching
// data and and then save the session.
//@category Examples.Version Tracking
// A script that runs Auto Version Tracking given the options set in one of the following ways:
// 1. If script is run from the CodeBrowser, the GUI options are set in a pop up dialog by user.
// 2. If script is run in headless mode either the defaults provided by the script are used or the
// user can specify a script to be run that sets the options. See example script
// SetAutoVersionTrackingOptionsScript that can be copied and updated to reflect the users
// desired options.
//
// NOTE: This is an example to show how run this script in headless mode
//
// <ghidra_install>/support/analyzeHeadless.bat/sh c:/MyGhidraProjectFolder
// MyProjectName/OptionalFolderContainingProgram -process Program1.exe -postScript
// MyOptionsSetupScript -postScript AutoVersionTrackingScript.java "/FolderContainingSession"
// "MySessionName" true "/OptionalFolderContainingProgram/Program2.exe"
//
//
// NOTE: The first program will be analyzed for you if it is not already analyzed (and if you
// do not include the -noanalysis option) as it is part of the typical analyzeHeadless run.
// The second program must be analyzed prior to running the script as the headless analyzer
// itself knows nothing about the file other than as a given option name. This is true in
// both GUI and headless mode.
//
// NOTE: The second to last parameter is to identify whether the first listed program
// is the source program or not. True means first program is source program and second
// program is destination program. False means second program is source program and first
// program is destination program. This is important if you want the correct markup to be
// applied from the source to destination program.
//
// NOTE: The options setup script is optional. It is only necessary if users want to change the
// default options. To use it make a copy of the example one and save to a new script. You
// You may need to add the -scriptPath to the headless run so it will find your script.
//
//@category Version Tracking
import ghidra.app.script.GhidraScript;
import ghidra.feature.vt.api.db.VTSessionDB;
import ghidra.feature.vt.api.main.VTSession;
import ghidra.feature.vt.api.util.VTOptions;
import ghidra.feature.vt.gui.actions.AutoVersionTrackingTask;
import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.util.VTOptionDefines;
import ghidra.features.base.values.GhidraValuesMap;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program;
import ghidra.util.MessageType;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskLauncher;
public class AutoVersionTrackingScript extends GhidraScript {
@ -49,47 +79,106 @@ public class AutoVersionTrackingScript extends GhidraScript {
@Override
public void run() throws Exception {
DomainFolder folder =
askProjectFolder("Please choose a folder for your Version Tracking session.");
String name = askString("Please enter a Version Tracking session name", "Session Name");
GhidraValuesMap startupValues = new GhidraValuesMap();
startupValues.defineProjectFolder("Version Tracking Session Folder", "/");
startupValues.defineString("Version Tracking Session Name");
startupValues.defineBoolean("Check if current program is the Source Program", true);
startupValues.defineProgram("Please select the other program");
startupValues.setValidator((valueMap, status) -> {
GhidraValuesMap map = (GhidraValuesMap) valueMap;
if (!valueMap.hasValue("Version Tracking Session Name")) {
status.setStatusText("Session Name must be filled in!", MessageType.ERROR);
return false;
}
try {
if (hasExistingSession(map.getString("Version Tracking Session Name"),
map.getProjectFolder("Version Tracking Session Folder"))) {
status.setStatusText("Session cannot be an existing session!",
MessageType.ERROR);
return false;
}
}
catch (CancelledException e) {
return false;
}
if (!valueMap.hasValue("Please select the other program")) {
status.setStatusText("Must choose second program!", MessageType.ERROR);
return false;
}
return true;
});
startupValues = askValues("Enter Auto Version Tracking Information",
"Changing these options will not change the corresponding tool options",
startupValues);
DomainFolder folder = startupValues.getProjectFolder("Version Tracking Session Folder");
String name = startupValues.getString("Version Tracking Session Name");
boolean isCurrentProgramSourceProg =
startupValues.getBoolean("Check if current program is the Source Program");
Program otherProgram =
startupValues.getProgram("Please select the other program", this, state.getTool());
boolean isCurrentProgramSourceProg = askYesNo("Current Program Source Program?",
"Is the current program your source program?");
if (isCurrentProgramSourceProg) {
sourceProgram = currentProgram;
destinationProgram = askProgram("Please select the destination (new) program");
destinationProgram = otherProgram;
}
else {
destinationProgram = currentProgram;
sourceProgram = askProgram("Please select the source (existing annotated) program");
sourceProgram = otherProgram;
}
if (sourceProgram == null || destinationProgram == null) {
return;
}
boolean autoCreateImpliedMatches = askYesNo("Implied Matches?",
"Would you like the script to figure out implied matches from any matches it creates?");
// Need to end the script transaction or it interferes with vt things that need locks
end(true);
VTSession session =
VTSessionDB.createVTSession(name, sourceProgram, destinationProgram, this);
folder.createFile(name, session, monitor);
ToolOptions options = getOptions();
if (folder.getFile(name) == null) {
folder.createFile(name, session, monitor);
}
boolean originalImpliedMatchSetting =
options.getBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
// create a default options map in case cannot get user input
GhidraValuesMap optionsMap = createDefaultOptions();
options.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, autoCreateImpliedMatches);
// if running script in GUI get options from user and update the vtOptions with them
if(!isRunningHeadless()) {
optionsMap = getOptionsFromUser();
}
// else if running script in headless get possible options set by prescript that saves
// optionsMap in script state variable and update the vtOptions with them
else {
// try to get options map from state if running headless
// if user runs prescript to set up their own options map those options will be used
// See SetAutoVersionTrackingOptionsScript.java as an example
GhidraValuesMap stateOptionsMap =
(GhidraValuesMap) state.getEnvironmentVar("autoVTOptionsMap");
if (optionsMap != null) {
optionsMap = stateOptionsMap;
}
}
ToolOptions vtOptions = setToolOptionsFromOptionsMap(optionsMap);
AutoVersionTrackingTask autoVtTask =
new AutoVersionTrackingTask(session, options, 0.95, 10.0);
new AutoVersionTrackingTask(session, vtOptions);
TaskLauncher.launch(autoVtTask);
@ -98,21 +187,131 @@ public class AutoVersionTrackingScript extends GhidraScript {
// if running headless - must save here or nothing that was done in this script will be
// accessible later.
if (isRunningHeadless()) {
otherProgram.save("Updated with Auto Version Tracking", monitor);
session.save();
}
options.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, originalImpliedMatchSetting);
println(autoVtTask.getStatusMsg());
otherProgram.release(this);
}
/**
* Method to determine if there is an existing VTSession in the given folder with the given name
* @param name the given name
* @param folder the given Ghidra project folder
* @return true if there is an existing VTSession with the given name in the given folder, false
* otherwise
* @throws CancelledException if cancelled
*/
private boolean hasExistingSession(String name, DomainFolder folder) throws CancelledException {
private ToolOptions getOptions() {
ToolOptions vtOptions = new VTOptions("Dummy");
PluginTool tool = state.getTool();
if (tool != null) {
vtOptions = tool.getOptions(VTController.VERSION_TRACKING_OPTIONS_NAME);
DomainFile[] files = folder.getFiles();
for (DomainFile file : files) {
monitor.checkCancelled();
if (file.getName().equals(name)) {
if (file.getContentType().equals("VersionTracking")) {
return true;
}
}
}
return vtOptions;
return false;
}
/**
* Method to create the default GhidraValuesMap AutoVT options
* @return the default GhidraValuesMap AutoVT options
*/
private GhidraValuesMap createDefaultOptions() {
GhidraValuesMap optionsValues = new GhidraValuesMap();
optionsValues.defineBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_SYMBOL_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION_TEXT, true);
optionsValues.defineBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION_TEXT, true);
optionsValues.defineInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION_TEXT, 5);
optionsValues.defineInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION_TEXT, 3);
optionsValues.defineInt(VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT, 10);
optionsValues.defineInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT, 10);
optionsValues.defineBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION_TEXT, true);
optionsValues.defineInt(VTOptionDefines.MIN_VOTES_OPTION_TEXT, 2);
optionsValues.defineInt(VTOptionDefines.MAX_CONFLICTS_OPTION_TEXT, 0);
optionsValues.defineDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION_TEXT, 0.95);
optionsValues.defineDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION_TEXT, 10.0);
return optionsValues;
}
/**
* Method to ask the user for AutoVT options
* @return a GhidraValuesMap containing AutoVT options values
* @throws CancelledException if cancelled
*/
private GhidraValuesMap getOptionsFromUser() throws CancelledException {
GhidraValuesMap optionsValues = createDefaultOptions();
optionsValues = askValues("Enter Auto Version Tracking Options",
"These options will not be saved to your current tool options.",
optionsValues);
return optionsValues;
}
/**
* Set the Auto Version Tracking options given a GhidraValuesMap containing the options values
* @param optionsValues the option values in a GhidraValuesMap
* @return ToolOptions containing the Auto Version Tracking options values
*/
private ToolOptions setToolOptionsFromOptionsMap(GhidraValuesMap optionsValues) {
ToolOptions toolOptions = new VTOptions("Dummy");
toolOptions.setBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION,
optionsValues.getBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_EXACT_SYMBOL_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_EXACT_SYMBOL_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION,
optionsValues.getBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION,
optionsValues.getInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION,
optionsValues.getInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION,
optionsValues.getInt(VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION,
optionsValues.getInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT));
toolOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION,
optionsValues.getDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION_TEXT));
toolOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION,
optionsValues.getDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION_TEXT));
toolOptions.setBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION,
optionsValues.getBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.MIN_VOTES_OPTION,
optionsValues.getInt(VTOptionDefines.MIN_VOTES_OPTION_TEXT));
toolOptions.setInt(VTOptionDefines.MAX_CONFLICTS_OPTION,
optionsValues.getInt(VTOptionDefines.MAX_CONFLICTS_OPTION_TEXT));
return toolOptions;
}
}

View file

@ -0,0 +1,105 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Example script to set AutoVersionTrackcing options to be used when running AutoVersionTracking
// script in headless mode. Users should copy and rename this script and update the given default
// option values to ones they prefer.
//@category Examples.Version Tracking
import ghidra.app.script.GhidraScript;
import ghidra.feature.vt.gui.util.VTOptionDefines;
import ghidra.features.base.values.GhidraValuesMap;
public class SetAutoVersionTrackingOptionsScript extends GhidraScript {
@Override
public void run() throws Exception {
GhidraValuesMap optionsMap = getOptions();
state.addEnvironmentVar("autoVTOptionsMap", optionsMap);
}
private GhidraValuesMap getOptions() {
GhidraValuesMap optionsValues = new GhidraValuesMap();
// If true, this option will cause the Auto Version Tracker to create implied matches for any
// applied function matches by other correlators
optionsValues.defineBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run the Exact Symbol Correlator
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_SYMBOL_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run the Exact Data Correlator
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run the Exact Function Bytes
// Correlator
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run the Exact Function
// Instruction Correlator and the Exact Function Mnemonics Correlator
optionsValues.defineBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run the Duplicate Function
// Correlator
optionsValues.defineBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION_TEXT, true);
// If true, this option will cause Auto Version Tracker to run either the Data Reference
// Correlator (if only applied Data matches exist), the Function Reference Correlator
// (if only applied Function matches exist), or the Function and Data Reference Correlator
// (if both applied data and function matches exist)
optionsValues.defineBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION_TEXT, true);
// This option defines the minimum data length for the Exact Data Correlator
optionsValues.defineInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION_TEXT, 5);
// This option defines the minimum symbol name lenght for the Exact Symbol Correlator
optionsValues.defineInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION_TEXT, 3);
// This option defines the minimum function length for the Exact Function Bytes Correlator,
// the Exact Function Instruction Correlator, and the Exact Function Mnemonics Correlator
optionsValues.defineInt(VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT, 10);
// This option defines the minimum function length for the Duplicate Function Correlator
// NOTE: This correlator can be slow on programs with large sets of duplicate function
// matches so adjusting the length can potentially speed it up
optionsValues.defineInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT, 10);
// If true, this option will cause Implied Matches to be applied according to the limits set
// for minimum votes and maximum conflicts
optionsValues.defineBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION_TEXT, true);
// This option defines the minimum number of votes needed to cause an implied match to be
// applied
optionsValues.defineInt(VTOptionDefines.MIN_VOTES_OPTION_TEXT, 2);
// This option defines the maximum number of conflicts allowed to cause an implied match to
// be applied
optionsValues.defineInt(VTOptionDefines.MAX_CONFLICTS_OPTION_TEXT, 0);
// This option defines the minimum score needed to apply reference correlator matches
optionsValues.defineDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION_TEXT, 0.95);
// This option defines the minimum confidence level needed to apply reference correlator
// matches. Note: Due to the log10 scaling of the confidence the confidence thresholds
// equal log 10 (10*optionValue) So optionValue 1.0 = threshold 1.0, optionValue 10.0
// = threshold 2.0, optionValue 100 = threshold 3.0
// optionsValues.defineDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION_TEXT, 10.0);
optionsValues.defineDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION_TEXT, 10.0);
return optionsValues;
}
}

View file

@ -0,0 +1,353 @@
<!DOCTYPE doctype PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
<HTML>
<HEAD>
<META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<TITLE>Auto Version Tracking</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
</HEAD>
<BODY lang="EN-US">
<H1><A name="Auto_Version_Tracking"></A>Auto Version Tracking</H1>
<P align="left"></A> The <b>Automatic Version Tracking</b> uses various correlators in a predetermined order
to automatically create matches, accept the most likely matches, and apply markup. The following
correlators are run in this order if the associated <a href="help/topics/VersionTrackingPlugin/VT_AutoVT.html#Auto_Version_Tracking_Options"> options</a> are set: </P>
<BLOCKQUOTE>
<ul>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Symbol_Match">Exact Symbol Name Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Data_Match">Exact Data Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Bytes_Match">Exact Function Bytes Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Instructions_Match">Exact Function Instructions Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Mnemonics_Match">Exact Function Mnemonics Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Duplicate_Function_Instructions_Match">Duplicate Function Instructions Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Data_Ref">Data Reference Correlator</a>, <a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Func_Ref">Function Reference Correlator</a>, <b>OR</b> <a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Comb_Func_Data_Ref">Combined Function and Data Reference Correlator</a></li>
</ul>
<P>If the Create Implied Matches option is set, Implied Matches will be created whenever
the above correlators accept matches.</P>
<P>If the Apply Implied Matches option is set, any created Implied Matches that have
the set minimum number of votes and does not exceed the set maximum number of conflicts
will be applied.</P>
<blockquote>
<P> <IMG src="help/shared/note.yellow.png" border="0"> <b>NOTE: It is unlikely that all matches in the entire program will be made and there is no guarantee that no mistakes will be made. This
action was designed to try to save as much time as possible while also taking a conservative approach to the automation.</b>
</blockquote>
</P>
</BLOCKQUOTE>
<BODY lang="EN-US">
<H2><A name="Auto_Version_Tracking_Options"></A>Auto Version Tracking Options</H2>
<P>
Auto Version Tracking will run each selected correlator and will use the option values found
in the Auto Version Tracking options rather than the options chosen when the correlators are
run individually. To access the options use Edit->Tool Options->Version Tracking->Auto
Version Tracking from the Version Tracking Match Window. </P>
<P> The following options are found when the <b>Edit->Tool Options->Version Tracking->Auto Version
Tracking</b> options folder is selected and will determine which correlators will be run during
Auto Version Tracking.</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Create Implied Matches</b></TD>
<TD>When true, Implied Matches will be created whenever the other correlators
accept matches.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Duplicate Function Correlator</b></TD>
<TD>When true, the Duplicate Function Instructions Correlator will be run
during Auto Version Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Exact Data Correlator</b></TD>
<TD>When true, the Exact Data Correlator will be run during Auto Version
Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Exact Function Bytes Correlator</b></TD>
<TD>When true, the Exact Function Bytes Correlator will be run during Auto
Version Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Exact Function Instruction Correlators</b></TD>
<TD>When true, the Exact Function Instruction Correlator and the Exact
Function Mnemonic Correlator will be run during Auto Version Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Exact Symbol Correlator</b></TD>
<TD>When true, the Exact Symbol Correlator will be run during Auto Version
Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Run Reference Correlators</b></TD>
<TD>When true, the Data Reference Correlator (if previous correlators applied
only data matches), Function Reference Correlator (if previous correlators
applied only function matches), or the Combined Function and Data Reference
Correlator (if previous correlators applied both data and function matches)
will be run during Auto Version Tracking.
</TD>
<TD><tt>True</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following option is found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Data Correlator Options</b>
</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Data Correlator Minimum Length</b></TD>
<TD>This option sets the minimum data length used to find data matches when
running the Exact Data Correlator in Auto Version Tracking.
</TD>
<TD><tt>5</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following option is found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Exact Function Correlators Options</b>
</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Exact Function Correlators Minimum Function Length</b></TD>
<TD>This option sets the minimum function length used to find function
matches when running the Exact Function Instruction Bytes Correlator, the
Exact Function Instruction Correlator, and the Exact Function Mnemonics
Correlator in Auto Version Tracking.
</TD>
<TD><tt>10</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following option is found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Duplicate Function Correlator Options</b>
</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Duplicate Function Correlators Minimum Function Length</b></TD>
<TD>This option sets the minimum function length used to find function
matches when running the Duplicate Function Instruction Correlator in
Auto Version Tracking.
</TD>
<TD><tt>10</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following option is found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Symbol Correlators Options</b>
</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Symbol Correlator Minimum Symbol Length</b></TD>
<TD>This option sets the the minimum symbol name length used to find function
and data matches when running the Exact Symbol Correlator in Auto Version
Tracking.
</TD>
<TD><tt>10</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following options are found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Reference Correlators Options</b> </P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Reference Correlators Minimum Confidence</b></TD>
<TD>This option sets minimum confidence score used to find function matches
using the Data Reference Correlator, the Function Reference Correlator and the
Combined Function and Data Reference Correlator.
</TD>
<TD><tt>10.0</tt></TD>
</TR>
<TR>
<TD nowrap><b>Reference Correlators Minimum Score</b></TD>
<TD>This option sets minimum similarity score used to find function matches
using the Data Reference Correlator, the Function Reference Correlator and the
Combined Function and Data Reference Correlator.
</TD>
<TD><tt>9.5</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<P> The following options are found when selecting
<b>Edit->Tool Options->Auto Version Tracking->Implied Match Correlator Options</b>
</P>
<BR>
<BLOCKQUOTE>
<TABLE align="center" border="1" width="90%">
<TR>
<TH>Name</TH>
<TH>Description</TH>
<TH nowrap>Default Value</TH>
</TR>
<TR>
<TD nowrap><b>Apply Implied Matches</b></TD>
<TD>This option if true, causes Auto Version Tracking to apply Implied Matches
if the minimum vote count is met and the maximum conflict count is not exceeded.
</TD>
<TD><tt>True</tt></TD>
</TR>
<TR>
<TD nowrap><b>Maximum Conflicts Allowed</b></TD>
<TD>This option sets the maximum number of allowed conflicts for an applied
implied match in Auto Version Tracking.
</TD>
<TD><tt>0</tt></TD>
</TR>
<TR>
<TD nowrap><b>Minimum Votes Needed</b></TD>
<TD>This option sets the minimum number of needed votes for an applied
implied match in Auto Version Tracking.
</TD>
<TD><tt>2</tt></TD>
</TR>
</TABLE>
</BLOCKQUOTE><!-- Main content blockquote -->
<P class="providedbyplugin">Provided by: <I>Version Tracking Plugin</I></P>
<P class="relatedtopic">Related Topics:</P>
<UL>
<LI><A href="help/topics/VersionTrackingPlugin/Version_Tracking_Intro.html">Version Tracking
Introduction</A></LI>
<LI><A href="help/topics/VersionTrackingPlugin/VT_Tool.html">Version Tracking Tool</A></LI>
</UL><BR>
<BR>
</BODY>
</HTML>

View file

@ -113,43 +113,26 @@
<IMG src="images/start-here_16.png" border="0"> action will launch the
<a href="help/topics/VersionTrackingPlugin/VT_Wizard.html">Version Tracking Wizard</a> to
guide you through the process of create a new
<a href="help/topics/VersionTrackingPlugin/Version_Tracking_Intro.html#Session">version tracking session</a>.
<a href="help/topics/VersionTrackingPlugin/Version_Tracking_Intro.html#Session">version
tracking session</a>.
</P>
<P align="left"><A name="Add_To_Session"></A>The <b>Add to Session</b>
<IMG src="images/Plus.png" border="0"> action will launch the
<a href="help/topics/VersionTrackingPlugin/VT_Wizard.html">Version Tracking Wizard</a> to
guide you through the process of create adding new
<a href="help/topics/VersionTrackingPlugin/VT_Correlators.html">Program Correlator</a> results to
<a href="help/topics/VersionTrackingPlugin/VT_Correlators.html">Program Correlator</a>
results to
an existing
<a href="help/topics/VersionTrackingPlugin/Version_Tracking_Intro.html#Session">version tracking session</a>.
<a href="help/topics/VersionTrackingPlugin/Version_Tracking_Intro.html#Session">version
tracking session</a>.
</P>
<P align="left"><A name="Automatic_Version_Tracking"></A> The <b>Automatic Version Tracking</b>
<IMG src="images/wizard.png" border="0"> action uses various correlators in a predetermined order
to automatically create matches, accept the most likely matches, and apply markup all with one button press. The following
correlators are run in this order:
<ul>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Symbol_Match">Exact Symbol Name Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Data_Match">Exact Data Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Bytes_Match">Exact Function Bytes Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Instructions_Match">Exact Function Instructions Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Exact_Function_Mnemonics_Match">Exact Function Mnemonics Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Duplicate_Function_Instructions_Match">Duplicate Function Instructions Correlator</a></li>
<li><a href="help/topics/VersionTrackingPlugin/VT_Correlators.html#Comb_Func_Data_Ref">Combined Function and Data Reference Correlator</a></li>
</ul>
<blockquote>
<P> <IMG src="help/shared/note.yellow.png" border="0"> <b>NOTE: It is unlikely that all matches in the entire program will be made and there is no guarantee that no mistakes will be made. This
action was designed to try to save as much time as possible while also taking a conservative approach to the automation.</b>
</blockquote>
<P align="left"><A name="Automatic_Version_Tracking"></A> The <b>Automatic Version
Tracking</b> <IMG src="images/wizard.png" border="0"> action will launch
<a href="help/topics/VersionTrackingPlugin/VT_AutoVT.html">Auto Version Tracking</a> to
try and automatically create and accept the most likely matches </a>.
</P>
<P align="left"><A name="Open_Session"></A>The <b>Open Session...</b>
action will launch a session chooser dialog that allows you to pick a previously
created session. This action is available only from the <b>File</b> menu.
</P>
</BLOCKQUOTE>
@ -174,9 +157,9 @@
Version Tracking Wizard</a> so that you can create a new version tracking
session.
</LI>
<LI><b>Auto Version Track</b> - Runs various correlators in a predetermined order
and automatically creates matches, accepts the most likely matches, and applies markup
all with one button press. </LI>
<LI><b>Auto Version Track</b> - Runs
<a href="help/topics/VersionTrackingPlugin/VT_AutoVT.html">Auto Version Tracking</a> to
try and automatically create and accept the most likely matches </a>. </li>
<LI><B>Open Session</B> - Shows a chooser dialog that allows
you to open an <b>existing</b> version tracking session.
</LI>

View file

@ -18,7 +18,9 @@ package ghidra.feature.vt.gui.actions;
import javax.swing.Icon;
import docking.ActionContext;
import docking.action.*;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.action.ToolBarData;
import docking.tool.ToolConstants;
import generic.theme.GIcon;
import ghidra.feature.vt.api.main.VTSession;
@ -27,7 +29,9 @@ import ghidra.feature.vt.gui.plugin.VTPlugin;
import ghidra.framework.options.ToolOptions;
import ghidra.util.HTMLUtilities;
import ghidra.util.HelpLocation;
import ghidra.util.task.*;
import ghidra.util.task.Task;
import ghidra.util.task.TaskLauncher;
import ghidra.util.task.TaskListener;
/**
* This action runs the {@link AutoVersionTrackingTask}
@ -62,15 +66,8 @@ public class AutoVersionTrackingAction extends DockingAction {
VTSession session = controller.getSession();
ToolOptions options = controller.getOptions();
// In the future we might want to make these user options so the user can change them.
// We don't want to make this change until the confidence option in the reference
// correlators is changed to make more sense to the user - currently the confidence has
// to be entered as the value before the log 10 is computed but the table shows log 10 value.
//
// The current passed values for score and confidence (.95 and 10.0)
// get you accepted matches with similarity scores >= .95 and
// confidence (log 10) scores 2.0 and up
AutoVersionTrackingTask task = new AutoVersionTrackingTask(session, options, 0.95, 10.0);
AutoVersionTrackingTask task = new AutoVersionTrackingTask(session, options);
task.addTaskListener(new TaskListener() {
@Override
@ -92,4 +89,6 @@ public class AutoVersionTrackingAction extends DockingAction {
TaskLauncher.launch(task);
}
}

View file

@ -71,8 +71,9 @@ import ghidra.util.task.TaskMonitor;
import ghidra.util.task.WrappingTaskMonitor;
/**
* This command runs all of the <b>exact</b> {@link VTProgramCorrelator}s that return
* unique matches (i.e., only one of each match is found in each program):
* If their options are set, this command runs all of the
* <b>exact</b> {@link VTProgramCorrelator}s that return unique matches (i.e., only one of each
* match is found in each program) for each correlator selected in the autoVT options to run:
* <ol>
* <li> Exact Symbol Name correlator </li>
* <li> Exact Data correlator </li>
@ -81,19 +82,28 @@ import ghidra.util.task.WrappingTaskMonitor;
* <li> Exact Function Mnemonic correlator </li>
* </ol>
*
* <P> After running each correlator all matches are accepted since they are exact/unique matches
* and all markup from the source program functions is applied to the matching destination program
* functions.
* <P> After running each of the above correlators all matches are accepted since they are
* exact/unique matches and all markup from the source program functions is applied to the matching
* destination program functions.
*
* <P> Next, this command runs the Duplicate Function Instruction correlator to find any non-unique
* functions with exact instruction bytes then compares their operands to determine and accept
* correct matches with markup.
* <P> Next, if the autoVT option for this correlator is selected, the command runs the
* Duplicate Function Instruction correlator to find any non-unique
* functions with exact instruction bytes. It then compares their operands to try and determine
* unique matches within matching sets and if found will accept correct matches and apply markup.
*
* <P> The command then gets a little more speculative by running the Combined Function and Data
* Reference correlator, which uses match information from the previous correlators to find more
* matches.
* <P> If chosen, the command then gets a little more speculative by running the Data Reference
* Correlator, the Function Reference Correlator, and/or the Combined Function and Data Reference
* Correlator, which use accepted match information from the previous correlators to find more
* matches. Only the matches with minimum score/confidence values, as chosen in the autoVT options,
* will be accepted.
*
* <P> As more techniques get developed, more automation will be added to this command.
* <P> If the user chooses to create implied matches then whenever matches are accepted, matches
* that can be implied by those matches as new matches will be created. If the user chooses to
* accept applied matches, then they will be applied if the chosen minimum vote count is met and if
* the chosen maximum conflict count is not exceeded.
*
* All options can be set in the Version Tracking Match Window's Edit -> Tool Options in
* Version Tracking/Auto Version Tracking option folder.
*
*/
public class AutoVersionTrackingTask extends Task {
@ -106,9 +116,7 @@ public class AutoVersionTrackingTask extends Task {
private Program destinationProgram;
private AddressSetView sourceAddressSet;
private AddressSetView destinationAddressSet;
private double minCombinedReferenceCorrelatorScore;
private double minCombinedReferenceCorrelatorConfidence;
private ToolOptions applyOptions;
private ToolOptions toolOptions;
private String statusMsg = null;
private static int NUM_CORRELATORS = 8;
@ -118,24 +126,20 @@ public class AutoVersionTrackingTask extends Task {
* @param session The Version Tracking session containing the source, destination, correlator
* and match information needed for this command.
* @param options the options used when applying matches
* @param toolOptions the options used when applying matches
* @param minCombinedReferenceCorrelatorScore The minimum score used to limit matches created by
* the Combined Reference Correlator.
* @param minCombinedReferenceCorrelatorConfidence The minimum confidence used to limit matches
* created by the Combined Reference Correlator.
*/
public AutoVersionTrackingTask(VTSession session, ToolOptions options,
double minCombinedReferenceCorrelatorScore,
double minCombinedReferenceCorrelatorConfidence) {
public AutoVersionTrackingTask(VTSession session, ToolOptions toolOptions) {
super(NAME, true, true, true);
this.session = session;
this.matchInfoFactory = new MatchInfoFactory();
this.addressCorrelator = new AddressCorrelatorManager(() -> session);
this.sourceProgram = session.getSourceProgram();
this.destinationProgram = session.getDestinationProgram();
this.minCombinedReferenceCorrelatorScore = minCombinedReferenceCorrelatorScore;
this.minCombinedReferenceCorrelatorConfidence = minCombinedReferenceCorrelatorConfidence;
this.applyOptions = options;
this.toolOptions = toolOptions;
}
@Override
@ -173,11 +177,12 @@ public class AutoVersionTrackingTask extends Task {
int count = 0;
monitor.doInitialize(NUM_CORRELATORS);
// save user option and use to determine whether to handle implied matches at all later
boolean autoCreateImpliedMatches =
applyOptions.getBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
// save user's Version Tracking (not AutoVT) Create implied match option
// Turn off auto implied matches and handle later if user had that option set
boolean originalImpliedMatchOption =
toolOptions.getBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
// Turn off auto implied matches and handle later if user had that Auto VT option set
// This is because when run from the VT GUI action implied matches are created automatically
// by the VT controller when the option is set but they are not created when called from a
// script since there is no VT controller in that case. If allowed to happen in
@ -185,50 +190,85 @@ public class AutoVersionTrackingTask extends Task {
// votes will be wrong. This Task doesn't know if called from GUI or script so this is
// klunky but will make sure they are only processed once and will make sure the user option
// is put back the way the user had it.
applyOptions.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
toolOptions.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
// Use default options for all of the "exact" correlators; passed in options for the others
VTOptions options;
// Start with each correlator's default options and overwrite with appropriate
// corresponding AutoVT options
VTOptions vtOptions;
String prefix = "%s correlation (%d of " + NUM_CORRELATORS + ") - ";
// Run the correlators in the following order:
// Do this one first because we don't want it to find ones that get markup applied by later
// correlators
VTProgramCorrelatorFactory factory = new SymbolNameProgramCorrelatorFactory();
options = factory.createDefaultOptions();
boolean runExactSymbolCorrelator =
toolOptions.getBoolean(VTOptionDefines.RUN_EXACT_SYMBOL_OPTION, true);
if (runExactSymbolCorrelator) {
VTProgramCorrelatorFactory factory = new SymbolNameProgramCorrelatorFactory();
String prefix = "%s correlation (%d of " + NUM_CORRELATORS + ") - ";
monitor.setPrefix(String.format(prefix, "Symbol Name", ++count));
hasApplyErrors = correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
vtOptions = factory.createDefaultOptions();
int symbolMin = toolOptions.getInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION, 3);
vtOptions.setInt(SymbolNameProgramCorrelatorFactory.MIN_SYMBOL_NAME_LENGTH, symbolMin);
factory = new ExactDataMatchProgramCorrelatorFactory();
options = factory.createDefaultOptions();
monitor.setPrefix(String.format(prefix, "Symbol Name", ++count));
hasApplyErrors = correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
boolean runExactDataCorrelator =
toolOptions.getBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION, true);
if (runExactDataCorrelator) {
VTProgramCorrelatorFactory factory = new ExactDataMatchProgramCorrelatorFactory();
monitor.setPrefix(String.format(prefix, "Exact Data", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
vtOptions = factory.createDefaultOptions();
int dataMin = toolOptions.getInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION, 5);
vtOptions.setInt(ExactDataMatchProgramCorrelatorFactory.DATA_MINIMUM_SIZE, dataMin);
factory = new ExactMatchBytesProgramCorrelatorFactory();
options = factory.createDefaultOptions();
monitor.setPrefix(String.format(prefix, "Exact Data", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
monitor.setPrefix(String.format(prefix, "Exact Bytes", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
int minFunctionLen =
toolOptions.getInt(VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION, 10);
factory = new ExactMatchInstructionsProgramCorrelatorFactory();
options = factory.createDefaultOptions();
boolean runExactFunctionBytesCorrelator =
toolOptions.getBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION, true);
if (runExactFunctionBytesCorrelator) {
VTProgramCorrelatorFactory factory = new ExactMatchBytesProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
monitor.setPrefix(String.format(prefix, "Exact Instructions", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
vtOptions.setInt(ExactMatchBytesProgramCorrelatorFactory.FUNCTION_MINIMUM_SIZE,
minFunctionLen);
factory = new ExactMatchMnemonicsProgramCorrelatorFactory();
options = factory.createDefaultOptions();
monitor.setPrefix(String.format(prefix, "Exact Bytes", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
boolean runExactFunctionInstCorrelator =
toolOptions.getBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION, true);
if (runExactFunctionInstCorrelator) {
VTProgramCorrelatorFactory factory =
new ExactMatchInstructionsProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
vtOptions.setInt(ExactMatchInstructionsProgramCorrelatorFactory.FUNCTION_MINIMUM_SIZE,
minFunctionLen);
monitor.setPrefix(String.format(prefix, "Exact Instructions", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
factory = new ExactMatchMnemonicsProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
vtOptions.setInt(ExactMatchMnemonicsProgramCorrelatorFactory.FUNCTION_MINIMUM_SIZE,
minFunctionLen);
monitor.setPrefix(String.format(prefix, "Exact Mnemonic", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
monitor.setPrefix(String.format(prefix, "Exact Mnemonic", ++count));
hasApplyErrors |= correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
// This is the first of the "speculative" post-correlator match algorithm. The correlator
// returns all duplicate function instruction matches so there will always be more
@ -237,12 +277,30 @@ public class AutoVersionTrackingTask extends Task {
// Given that each function must contains the same instructions to even become a match,
// and the compare function mechanism has been very well tested, the mechanism for
// finding the correct match is very accurate.
factory = new DuplicateFunctionMatchProgramCorrelatorFactory();
options = factory.createDefaultOptions();
boolean runDupeFunctionCorrelator =
toolOptions.getBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION, true);
monitor.setPrefix(String.format(prefix, "Duplicate Function", ++count));
hasApplyErrors |= correlateAndPossiblyApplyDuplicateFunctions(factory, options, monitor);
monitor.doIncrementProgress();
if (runDupeFunctionCorrelator) {
VTProgramCorrelatorFactory factory =
new DuplicateFunctionMatchProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
// if Auto VT min function length for dupe matches is different than current
// exact instruction match setting temporarily change it for auto VT run
int dupFunctionMinLen =
toolOptions.getInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION, 10);
vtOptions.setInt(
ExactMatchInstructionsProgramCorrelatorFactory.FUNCTION_MINIMUM_SIZE,
dupFunctionMinLen);
monitor.setPrefix(String.format(prefix, "Duplicate Function", ++count));
hasApplyErrors |=
correlateAndPossiblyApplyDuplicateFunctions(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
// The rest are mores speculative matching algorithms because they depend on our
// choosing the correct score/confidence pair to determine very probable matches. These
@ -251,65 +309,93 @@ public class AutoVersionTrackingTask extends Task {
// Get the names of the confidence and similarity score thresholds that
// are used by all of the "reference" correlators
String confidenceOption = VTAbstractReferenceProgramCorrelatorFactory.CONFIDENCE_THRESHOLD;
String scoreOption = VTAbstractReferenceProgramCorrelatorFactory.SIMILARITY_THRESHOLD;
boolean runRefCorrelators =
toolOptions.getBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION, true);
if (runRefCorrelators) {
// Get the number of data and function matches
int numDataMatches = getNumberOfDataMatches(monitor);
int numFunctionMatches = getNumberOfFunctionMatches(monitor);
double minScore = toolOptions.getDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.95);
double minConf = toolOptions.getDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
// Run the DataReferenceCorrelator if there are accepted data matches but no accepted
// function matches
if (numDataMatches > 0 && numFunctionMatches == 0) {
factory = new DataReferenceProgramCorrelatorFactory();
options = factory.createDefaultOptions();
options.setDouble(confidenceOption, minCombinedReferenceCorrelatorConfidence);
options.setDouble(scoreOption, minCombinedReferenceCorrelatorScore);
monitor.setPrefix(String.format(prefix, "Data Reference", ++count));
hasApplyErrors = hasApplyErrors | correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
// Get the number of data and function matches
int numDataMatches = getNumberOfDataMatches(monitor);
int numFunctionMatches = getNumberOfFunctionMatches(monitor);
// Get the number of data and function matches again if this correlator ran
numDataMatches = getNumberOfDataMatches(monitor);
numFunctionMatches = getNumberOfFunctionMatches(monitor);
// Run the DataReferenceCorrelator if there are accepted data matches but no accepted
// function matches
if (numDataMatches > 0 && numFunctionMatches == 0) {
VTProgramCorrelatorFactory factory = new DataReferenceProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.CONFIDENCE_THRESHOLD, minConf);
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.SIMILARITY_THRESHOLD, minScore);
monitor.setPrefix(String.format(prefix, "Data Reference", ++count));
hasApplyErrors =
hasApplyErrors | correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
// Get the number of data and function matches again if this correlator ran
numDataMatches = getNumberOfDataMatches(monitor);
numFunctionMatches = getNumberOfFunctionMatches(monitor);
}
// Run the FunctionReferenceCorrelator if there are accepted function matches but no
// accepted data matches
if (numDataMatches > 0 && numFunctionMatches == 0) {
VTProgramCorrelatorFactory factory =
new FunctionReferenceProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.CONFIDENCE_THRESHOLD, minConf);
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.SIMILARITY_THRESHOLD, minScore);
factory = new FunctionReferenceProgramCorrelatorFactory();
monitor.setPrefix(String.format(prefix, "Function Reference", ++count));
hasApplyErrors =
hasApplyErrors | correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
// Get the number of data and function matches again if this correlator ran
numDataMatches = getNumberOfDataMatches(monitor);
numFunctionMatches = getNumberOfFunctionMatches(monitor);
}
// Run the CombinedDataAndFunctionReferenceCorrelator if there are both accepted function
// matches but and data matches
if (numDataMatches > 0 && numFunctionMatches > 0) {
VTProgramCorrelatorFactory factory =
new CombinedFunctionAndDataReferenceProgramCorrelatorFactory();
vtOptions = factory.createDefaultOptions();
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.CONFIDENCE_THRESHOLD, minConf);
vtOptions.setDouble(
VTAbstractReferenceProgramCorrelatorFactory.SIMILARITY_THRESHOLD, minScore);
monitor.setPrefix(String.format(prefix, "Function and Data", ++count));
hasApplyErrors =
hasApplyErrors | correlateAndPossiblyApply(factory, vtOptions, monitor);
monitor.doIncrementProgress();
}
}
// Run the FunctionReferenceCorrelator if there are accepted function matches but no
// accepted data matches
if (numDataMatches > 0 && numFunctionMatches == 0) {
factory = new FunctionReferenceProgramCorrelatorFactory();
options = factory.createDefaultOptions();
options.setDouble(confidenceOption, minCombinedReferenceCorrelatorConfidence);
options.setDouble(scoreOption, minCombinedReferenceCorrelatorScore);
factory = new FunctionReferenceProgramCorrelatorFactory();
// Use the AutoVT create implied match option to decide whether to create implied matches
// when running AutoVT
boolean autoCreateImpliedMatches =
toolOptions.getBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION, false);
monitor.setPrefix(String.format(prefix, "Function Reference", ++count));
hasApplyErrors = hasApplyErrors | correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
// Get the number of data and function matches again if this correlator ran
numDataMatches = getNumberOfDataMatches(monitor);
numFunctionMatches = getNumberOfFunctionMatches(monitor);
}
// Run the CombinedDataAndFunctionReferenceCorrelator if there are both accepted function
// matches but and data matches
if (numDataMatches > 0 && numFunctionMatches > 0) {
factory = new CombinedFunctionAndDataReferenceProgramCorrelatorFactory();
options = factory.createDefaultOptions();
options.setDouble(confidenceOption, minCombinedReferenceCorrelatorConfidence);
options.setDouble(scoreOption, minCombinedReferenceCorrelatorScore);
monitor.setPrefix(String.format(prefix, "Function and Data", ++count));
hasApplyErrors = hasApplyErrors | correlateAndPossiblyApply(factory, options, monitor);
monitor.doIncrementProgress();
}
// if user had implied match option chosen then figure out implied matches now
// TODO: add option for applying good matches and num votes/conflicts
// if implied matches are to be created, determine whether user wants them auto-applied
// and determine the min votes and max conflicts option limits to use
if (autoCreateImpliedMatches) {
hasApplyErrors = hasApplyErrors | createImpliedMatches(true, monitor);
boolean applyImpliedMatches =
toolOptions.getBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION, true);
int minVotes = toolOptions.getInt(VTOptionDefines.MIN_VOTES_OPTION, 2);
int maxConflicts = toolOptions.getInt(VTOptionDefines.MAX_CONFLICTS_OPTION, 2);
hasApplyErrors = hasApplyErrors |
createImpliedMatches(applyImpliedMatches, minVotes, maxConflicts, monitor);
}
String applyMarkupStatus = " with no apply markup errors.";
@ -319,12 +405,9 @@ public class AutoVersionTrackingTask extends Task {
}
statusMsg = NAME + " completed successfully" + applyMarkupStatus;
// reset auto implied match option to user choice
// TODO: make separate AutoVT implied match option
applyOptions.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH,
autoCreateImpliedMatches);
// reset the Version Tracking auto implied match option to user choice
toolOptions.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH,
originalImpliedMatchOption);
}
@ -333,20 +416,21 @@ public class AutoVersionTrackingTask extends Task {
* @param applyGoodMatches if true, create applied matches for "good" implied matches based on
* votes/conflict information. For all the applied implied matches, rerun the creation of
* applied matches until no new ones found.
* @param applyGoodMatches if true, apply matches if minVotes met and maxConflicts not exceeded
* for particular match, if false, don't apply any matches
* @param minVotes minimum votes needed to apply a match
* @param maxConflicts maximum conflicts allowed to apply a match
* @param monitor the task monitor
* @return true if there are any apply errors, false otherwise
* @throws CancelledException if cancelled
*/
private boolean createImpliedMatches(boolean applyGoodMatches, TaskMonitor monitor)
private boolean createImpliedMatches(boolean applyGoodMatches, int minVotes, int maxConflicts,
TaskMonitor monitor)
throws CancelledException {
Set<VTAssociation> processedSrcDestPairs = new HashSet<>();
List<VTMatchSet> matchSets = session.getMatchSets();
//TODO: make these options
int minVoteCountNeeded = 2;
int maxConflictsAllowed = 0;
monitor.setMessage("Creating Implied Matches...");
monitor.initialize(matchSets.size());
@ -371,8 +455,8 @@ public class AutoVersionTrackingTask extends Task {
VTMatchSet impliedMatchSet = session.getImpliedMatchSet();
Set<VTMatch> goodImpliedMatches =
findGoodImpliedMatches(impliedMatchSet.getMatches(), minVoteCountNeeded,
maxConflictsAllowed, monitor);
findGoodImpliedMatches(impliedMatchSet.getMatches(), minVotes,
maxConflicts, monitor);
while (goodImpliedMatches.size() > 0) {
@ -387,7 +471,7 @@ public class AutoVersionTrackingTask extends Task {
// possibly find more "good" implied matches from any new implied matches found
impliedMatchSet = session.getImpliedMatchSet();
goodImpliedMatches = findGoodImpliedMatches(impliedMatchSet.getMatches(),
minVoteCountNeeded, maxConflictsAllowed, monitor);
minVotes, maxConflicts, monitor);
}
return hasApplyErrors;
@ -612,7 +696,7 @@ public class AutoVersionTrackingTask extends Task {
}
ApplyMarkupItemTask markupTask =
new ApplyMarkupItemTask(session, markupItems, applyOptions);
new ApplyMarkupItemTask(session, markupItems, toolOptions);
markupTask.run(monitor);
boolean currentMatchHasErrors = markupTask.hasErrors();
@ -789,7 +873,6 @@ public class AutoVersionTrackingTask extends Task {
// from the initial set of related associations get all the other ones that have related
// associations with all the source/destinations of the newly found associations
for (VTAssociation association : relatedAssociations) {
monitor.checkCancelled();
@ -1242,6 +1325,12 @@ public class AutoVersionTrackingTask extends Task {
return offsetToOperandsMap;
}
/**
* Method to create offset/operand mapping for each function in match set
* if more than one identical offset/operand mapping in src or dest piles then remove
* if no operands remove
*
*/
private Map<Integer, Object> createOperandsMap(Instruction inst) {
Map<Integer, Object> map = new HashMap<>();
@ -1275,14 +1364,6 @@ public class AutoVersionTrackingTask extends Task {
return map;
}
/**
* Method to create offset/operand mapping for each function in match set
* if more than one identical offset/operand mapping in src or dest piles then remove
* if no operands remove
*
*/
/**
* Try to accept the given match and if can accept the match try to apply its markup
* @param match The match to try and accept and apply markup to
@ -1316,7 +1397,7 @@ public class AutoVersionTrackingTask extends Task {
if (markupItems != null && markupItems.size() != 0) {
ApplyMarkupItemTask markupTask =
new ApplyMarkupItemTask(session, markupItems, applyOptions);
new ApplyMarkupItemTask(session, markupItems, toolOptions);
markupTask.run(monitor);
boolean currentMatchHasErrors = markupTask.hasErrors();
if (currentMatchHasErrors) {

View file

@ -15,34 +15,153 @@
*/
package ghidra.feature.vt.gui.provider.matchtable;
import static ghidra.feature.vt.gui.actions.TableSelectionTrackingState.*;
import static ghidra.feature.vt.gui.plugin.VTPlugin.*;
import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
import static ghidra.feature.vt.gui.actions.TableSelectionTrackingState.MAINTAIN_SELECTED_ROW_INDEX;
import static ghidra.feature.vt.gui.actions.TableSelectionTrackingState.MAINTAIN_SELECTED_ROW_VALUE;
import static ghidra.feature.vt.gui.actions.TableSelectionTrackingState.NO_SELECTION_TRACKING;
import static ghidra.feature.vt.gui.plugin.VTPlugin.FILTERED_ICON;
import static ghidra.feature.vt.gui.plugin.VTPlugin.UNFILTERED_ICON;
import static ghidra.feature.vt.gui.util.VTOptionDefines.ACCEPT_MATCH_OPTIONS_NAME;
import static ghidra.feature.vt.gui.util.VTOptionDefines.APPLY_DATA_NAME_ON_ACCEPT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.APPLY_FUNCTION_NAME_ON_ACCEPT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.APPLY_MARKUP_OPTIONS_NAME;
import static ghidra.feature.vt.gui.util.VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH;
import static ghidra.feature.vt.gui.util.VTOptionDefines.AUTO_VT_OPTIONS_NAME;
import static ghidra.feature.vt.gui.util.VTOptionDefines.CALLING_CONVENTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.CALL_FIXUP;
import static ghidra.feature.vt.gui.util.VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DATA_MATCH_DATA_TYPE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_CALLING_CONVENTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_CALL_FIXUP;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_DATA_MATCH_DATA_TYPE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_EOL_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_FUNCTION_NAME;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_FUNCTION_RETURN_TYPE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_HIGHEST_NAME_PRIORITY;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_IGNORE_EXCLUDED_MARKUP_ITEMS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_IGNORE_INCOMPLETE_MARKUP_ITEMS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_INLINE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_LABELS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_NO_RETURN;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_DATA_TYPES;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_NAMES;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PLATE_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_POST_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PRE_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_REPEATABLE_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_VAR_ARGS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DISPLAY_APPLY_MARKUP_OPTIONS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.END_OF_LINE_COMMENT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.FUNCTION_CORRELATOR_MIN_LEN_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.FUNCTION_NAME;
import static ghidra.feature.vt.gui.util.VTOptionDefines.FUNCTION_RETURN_TYPE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.FUNCTION_SIGNATURE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.HIGHEST_NAME_PRIORITY;
import static ghidra.feature.vt.gui.util.VTOptionDefines.IGNORE_EXCLUDED_MARKUP_ITEMS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.IGNORE_INCOMPLETE_MARKUP_ITEMS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.INLINE;
import static ghidra.feature.vt.gui.util.VTOptionDefines.LABELS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.MAX_CONFLICTS_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.MIN_VOTES_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.NO_RETURN;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_COMMENTS;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_DATA_TYPES;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_NAMES;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PLATE_COMMENT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.POST_COMMENT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.PRE_COMMENT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.REPEATABLE_COMMENT;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_DUPE_FUNCTION_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_EXACT_DATA_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_EXACT_FUNCTION_INST_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_EXACT_SYMBOL_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.RUN_REF_CORRELATORS_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION;
import static ghidra.feature.vt.gui.util.VTOptionDefines.VAR_ARGS;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.Adjustable;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.*;
import docking.widgets.table.*;
import docking.ActionContext;
import docking.DockingWindowManager;
import docking.WindowPosition;
import docking.widgets.table.AbstractSortedTableModel;
import docking.widgets.table.GTable;
import docking.widgets.table.RowObjectSelectionManager;
import docking.widgets.table.RowObjectTableModel;
import docking.widgets.table.SelectionManager;
import docking.widgets.table.threaded.ThreadedTableModel;
import ghidra.feature.vt.api.impl.VTChangeManager;
import ghidra.feature.vt.api.impl.VersionTrackingChangeRecord;
import ghidra.feature.vt.api.main.*;
import ghidra.feature.vt.gui.actions.*;
import ghidra.feature.vt.api.main.VTMarkupItem;
import ghidra.feature.vt.api.main.VTMatch;
import ghidra.feature.vt.api.main.VTSession;
import ghidra.feature.vt.gui.actions.AcceptMatchAction;
import ghidra.feature.vt.gui.actions.ApplyBlockedMatchAction;
import ghidra.feature.vt.gui.actions.ApplyMatchAction;
import ghidra.feature.vt.gui.actions.ChooseMatchTagAction;
import ghidra.feature.vt.gui.actions.ClearMatchAction;
import ghidra.feature.vt.gui.actions.CreateSelectionAction;
import ghidra.feature.vt.gui.actions.EditAllTagsAction;
import ghidra.feature.vt.gui.actions.MatchTableSelectionAction;
import ghidra.feature.vt.gui.actions.RejectMatchAction;
import ghidra.feature.vt.gui.actions.RemoveMatchAction;
import ghidra.feature.vt.gui.actions.RemoveMatchTagAction;
import ghidra.feature.vt.gui.actions.TableSelectionTrackingState;
import ghidra.feature.vt.gui.editors.MatchTagCellEditor;
import ghidra.feature.vt.gui.filters.*;
import ghidra.feature.vt.gui.filters.AncillaryFilterDialogComponentProvider;
import ghidra.feature.vt.gui.filters.Filter;
import ghidra.feature.vt.gui.filters.Filter.FilterEditingStatus;
import ghidra.feature.vt.gui.plugin.*;
import ghidra.feature.vt.gui.util.*;
import ghidra.feature.vt.gui.util.AbstractVTMatchTableModel.*;
import ghidra.framework.model.*;
import ghidra.feature.vt.gui.filters.FilterDialogModel;
import ghidra.feature.vt.gui.filters.FilterStatusListener;
import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.plugin.VTControllerListener;
import ghidra.feature.vt.gui.plugin.VTPlugin;
import ghidra.feature.vt.gui.plugin.VersionTrackingPluginPackage;
import ghidra.feature.vt.gui.util.AbstractVTMatchTableModel.DestinationLabelTableColumn;
import ghidra.feature.vt.gui.util.AbstractVTMatchTableModel.SourceLabelTableColumn;
import ghidra.feature.vt.gui.util.AbstractVTMatchTableModel.StatusTableColumn;
import ghidra.feature.vt.gui.util.AbstractVTMatchTableModel.TagTableColumn;
import ghidra.feature.vt.gui.util.AllTextFilter;
import ghidra.feature.vt.gui.util.FilterIconFlashTimer;
import ghidra.feature.vt.gui.util.MatchInfo;
import ghidra.feature.vt.gui.util.MatchStatusRenderer;
import ghidra.feature.vt.gui.util.VTSymbolRenderer;
import ghidra.framework.model.DomainObject;
import ghidra.framework.model.DomainObjectChangeRecord;
import ghidra.framework.model.DomainObjectChangedEvent;
import ghidra.framework.options.Options;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.ComponentProviderAdapter;
@ -708,11 +827,74 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
.setOptionsHelpLocation(
new HelpLocation("VersionTracking", "Apply Markup Options"));
// Auto VT options
// put checkboxes to determine which correlators to run during auto VT
vtOptions.registerOption(CREATE_IMPLIED_MATCHES_OPTION, true, null,
"Create Implied Matches when AutoVT correlators apply function matches.");
vtOptions.registerOption(RUN_EXACT_DATA_OPTION, true, null, "Run the Exact Data Correlator");
vtOptions.registerOption(RUN_EXACT_SYMBOL_OPTION, true, null, "Run the Exact Symbol Correlator");
vtOptions.registerOption(RUN_EXACT_FUNCTION_BYTES_OPTION, true, null,
"Run the Exact Function Bytes Correlator");
vtOptions.registerOption(RUN_EXACT_FUNCTION_INST_OPTION, true, null,
"Run the Exact Function Instruction Bytes and Mnemonics Correlators");
vtOptions.registerOption(RUN_DUPE_FUNCTION_OPTION, true, null,
"Run the Duplicate Function Instruction Correlator");
vtOptions.registerOption(RUN_REF_CORRELATORS_OPTION, true, null, "Run the Reference Correlators");
// create sub options for each auto VT correlator
vtOptions.registerOption(APPLY_IMPLIED_MATCHES_OPTION, true, null,
"Apply implied matches if minimum vote count is met and maximum conflict count is not exceeded.");
vtOptions.registerOption(MIN_VOTES_OPTION, 2, null,
"The minimum number of votes needed to apply an implied match.");
vtOptions.registerOption(MAX_CONFLICTS_OPTION, 0, null,
"The maximum number of conflicts allowed to apply an implied match.");
vtOptions.registerOption(SYMBOL_CORRELATOR_MIN_LEN_OPTION, 3, null,
"Minimum Symbol Name Length of Auto Version Tracking Symbol Correlator");
vtOptions.getOptions(SYMBOL_CORRELATOR_MIN_LEN_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
vtOptions.registerOption(DATA_CORRELATOR_MIN_LEN_OPTION, 5, null,
"Minimum Data Length of Auto Version Tracking Data Correlator");
vtOptions.getOptions(DATA_CORRELATOR_MIN_LEN_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
vtOptions.registerOption(FUNCTION_CORRELATOR_MIN_LEN_OPTION, 10, null,
"Minimum Function Length of Auto Version Tracking Duplicate Function Correlator");
vtOptions.getOptions(FUNCTION_CORRELATOR_MIN_LEN_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
vtOptions.registerOption(DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION, 10, null,
"Minimum Function Length of Auto Version Tracking Duplicate Function Correlator");
vtOptions.getOptions(DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
vtOptions.registerOption(REF_CORRELATOR_MIN_SCORE_OPTION, 0.95, null,
"Minimum Score of all Auto Version Tracking Reference Function Correlators (Data, Function, and Combined Function and Data)");
vtOptions.getOptions(REF_CORRELATOR_MIN_SCORE_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
vtOptions.registerOption(REF_CORRELATOR_MIN_CONF_OPTION, 10.0, null,
"Minimum Confidence of all Auto Version Tracking Reference Function Correlator (Data, Function, and Combined Function and Data)");
vtOptions.getOptions(REF_CORRELATOR_MIN_CONF_OPTION)
.setOptionsHelpLocation(
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options"));
HelpLocation applyOptionsHelpLocation =
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Version_Tracking_Apply_Options");
HelpLocation applyMatchOptionsHelpLocation =
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Match_Apply_Options");
HelpLocation autoVTHelpLocation =
new HelpLocation(VTPlugin.HELP_TOPIC_NAME, "Auto_Version_Tracking_Options");
vtOptions.setOptionsHelpLocation(applyOptionsHelpLocation);
vtOptions.getOptions(ACCEPT_MATCH_OPTIONS_NAME)
@ -720,6 +902,9 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
.setOptionsHelpLocation(applyMatchOptionsHelpLocation);
vtOptions.setOptionsHelpLocation(autoVTHelpLocation);
vtOptions.getOptions(AUTO_VT_OPTIONS_NAME).setOptionsHelpLocation(autoVTHelpLocation);
}
//==================================================================================================

View file

@ -15,7 +15,16 @@
*/
package ghidra.feature.vt.gui.util;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.*;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CallingConventionChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CommentChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.FunctionNameChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.FunctionSignatureChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.HighestSourcePriorityChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.LabelChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.ParameterDataTypeChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.ReplaceChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.ReplaceDataChoices;
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.SourcePriorityChoices;
import ghidra.framework.options.Options;
public class VTOptionDefines {
@ -30,7 +39,6 @@ public class VTOptionDefines {
".Automatically Apply Data Label on Accept";
// Apply Options
public static final String APPLY_MARKUP_OPTIONS_NAME = "Apply Markup Options";
public static boolean DEFAULT_OPTION_FOR_IGNORE_INCOMPLETE_MARKUP_ITEMS = false;
public static boolean DEFAULT_OPTION_FOR_IGNORE_EXCLUDED_MARKUP_ITEMS = false;
@ -108,4 +116,101 @@ public class VTOptionDefines {
public final static String DISPLAY_APPLY_MARKUP_OPTIONS = APPLY_MARKUP_OPTIONS_NAME +
Options.DELIMITER + "Display Apply Markup Options";
// Auto VT Options
public static final String AUTO_VT_OPTIONS_NAME = "Auto Version Tracking Options";
public static final String AUTO_VT_SYMBOL_CORRELATOR = "Symbol Correlator Options";
public static final String AUTO_VT_DATA_CORRELATOR = "Data Correlator Options";
public static final String AUTO_VT_EXACT_FUNCTION_CORRELATORS =
"Exact Function Correlators Options";
public static final String AUTO_VT_DUPLICATE_FUNCTION_CORRELATOR =
"Duplicate Function Correlator Options";
public static final String AUTO_VT_REFERENCE_CORRELATORS =
"Reference Correlators Options";
public static final String AUTO_VT_IMPLIED_MATCH_CORRELATOR =
"Implied Match Correlator Options";
public static final String CREATE_IMPLIED_MATCHES_OPTION_TEXT = "Create Implied Matches";
public static final String CREATE_IMPLIED_MATCHES_OPTION = AUTO_VT_OPTIONS_NAME +
"." + CREATE_IMPLIED_MATCHES_OPTION_TEXT;
public static final String RUN_EXACT_DATA_OPTION_TEXT = "Run Exact Data Correlator";
public static final String RUN_EXACT_DATA_OPTION = AUTO_VT_OPTIONS_NAME +
"." + RUN_EXACT_DATA_OPTION_TEXT;
public static final String RUN_EXACT_SYMBOL_OPTION_TEXT = "Run Exact Symbol Correlator";
public static final String RUN_EXACT_SYMBOL_OPTION = AUTO_VT_OPTIONS_NAME +
"." + RUN_EXACT_SYMBOL_OPTION_TEXT;
public static final String RUN_EXACT_FUNCTION_BYTES_OPTION_TEXT =
"Run Exact Function Bytes Correlator";
public static final String RUN_EXACT_FUNCTION_BYTES_OPTION = AUTO_VT_OPTIONS_NAME +
"." + "Run Exact Function Bytes Correlator";
public static final String RUN_EXACT_FUNCTION_INST_OPTION_TEXT =
"Run Exact Function Instructions Correlators";
public static final String RUN_EXACT_FUNCTION_INST_OPTION = AUTO_VT_OPTIONS_NAME +
"." + RUN_EXACT_FUNCTION_INST_OPTION_TEXT;
public static final String RUN_DUPE_FUNCTION_OPTION_TEXT = "Run Duplicate Function Correlator";
public static final String RUN_DUPE_FUNCTION_OPTION = AUTO_VT_OPTIONS_NAME +
"." + RUN_DUPE_FUNCTION_OPTION_TEXT;
public static final String RUN_REF_CORRELATORS_OPTION_TEXT = "Run the Reference Correlators";
public static final String RUN_REF_CORRELATORS_OPTION = AUTO_VT_OPTIONS_NAME +
"." + RUN_REF_CORRELATORS_OPTION_TEXT;
public static final String APPLY_IMPLIED_MATCHES_OPTION_TEXT = "Apply Implied Matches";
public static final String APPLY_IMPLIED_MATCHES_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_IMPLIED_MATCH_CORRELATOR +
"." + APPLY_IMPLIED_MATCHES_OPTION_TEXT;
public static final String MIN_VOTES_OPTION_TEXT = "Minimum Votes Needed";
public static final String MIN_VOTES_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_IMPLIED_MATCH_CORRELATOR +
"." + MIN_VOTES_OPTION_TEXT;
public static final String MAX_CONFLICTS_OPTION_TEXT = "Maximum Conflicts Allowed";
public static final String MAX_CONFLICTS_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_IMPLIED_MATCH_CORRELATOR +
"." + MAX_CONFLICTS_OPTION_TEXT;
public static final String SYMBOL_CORRELATOR_MIN_LEN_OPTION_TEXT =
"Symbol Correlator Minimum Symbol Length";
public static final String SYMBOL_CORRELATOR_MIN_LEN_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_SYMBOL_CORRELATOR +
"." + SYMBOL_CORRELATOR_MIN_LEN_OPTION_TEXT;
public static final String DATA_CORRELATOR_MIN_LEN_OPTION_TEXT =
"Data Correlator Minimum Data Length";
public static final String DATA_CORRELATOR_MIN_LEN_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_DATA_CORRELATOR +
"." + "Data Correlator Minimum Data Length";
public static final String FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT =
"Exact Function Correlators Minimum Function Length";
public static final String FUNCTION_CORRELATOR_MIN_LEN_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_EXACT_FUNCTION_CORRELATORS +
"." + FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT;
public static final String DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT =
"Duplicate Function Correlator Minimum Function Length";
public static final String DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_DUPLICATE_FUNCTION_CORRELATOR +
"." + DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION_TEXT;;
public static final String REF_CORRELATOR_MIN_SCORE_OPTION_TEXT =
"Reference Correlators Minimum Score";
public static final String REF_CORRELATOR_MIN_SCORE_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_REFERENCE_CORRELATORS +
"." + REF_CORRELATOR_MIN_SCORE_OPTION_TEXT;
public static final String REF_CORRELATOR_MIN_CONF_OPTION_TEXT =
"Reference Correlators Minimum Confidence";
public static final String REF_CORRELATOR_MIN_CONF_OPTION =
AUTO_VT_OPTIONS_NAME + "." + AUTO_VT_REFERENCE_CORRELATORS +
"." + REF_CORRELATOR_MIN_CONF_OPTION_TEXT;
}

View file

@ -18,8 +18,8 @@ package ghidra.feature.vt.api;
import static ghidra.feature.vt.db.VTTestUtils.addr;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
@ -42,6 +42,7 @@ import ghidra.feature.vt.api.main.VTProgramCorrelator;
import ghidra.feature.vt.api.main.VTScore;
import ghidra.feature.vt.api.main.VTSession;
import ghidra.feature.vt.api.util.VTAssociationStatusException;
import ghidra.feature.vt.api.util.VTOptions;
import ghidra.feature.vt.db.VTTestUtils;
import ghidra.feature.vt.gui.VTTestEnv;
import ghidra.feature.vt.gui.actions.AutoVersionTrackingTask;
@ -49,18 +50,21 @@ import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.util.VTOptionDefines;
import ghidra.framework.options.Options;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.CodeUnitIterator;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.util.Msg;
import ghidra.util.exception.InvalidInputException;
@ -72,7 +76,6 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
private static final String TEST_DESTINATION_PROGRAM_NAME = "VersionTracking/WallaceVersion2";
private VTTestEnv env;
private VTController controller;
private ProgramDB sourceProgram;
private ProgramDB destinationProgram;
private VTSessionDB session;
@ -102,11 +105,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
runAutoVTCommand(0.999999999, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// verify that the default options are what we expect
// if this assert fails then the follow-on tests will probably fail
@ -162,12 +169,16 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// Score 0.5 and conf threshold 1.0 allow similarity scores of higher than 0.5 for combined
// reference correlator and 1.0 and higher for the log 10 confidence score
runAutoVTCommand(0.5, 1.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.5);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 1.0);
runAutoVTCommand(vtOptions);
// verify that the default options are what we expect
// if this assert fails then the follow-on tests will probably fail
@ -213,8 +224,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// This test is testing to make sure that previously blocked matches do not become
// accepted matches after running Auto VT
@ -235,7 +245,12 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
assertEquals(status2, VTAssociationStatus.ACCEPTED);
// run auto VT which would normally accept the match we blocked
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Now test that the match we blocked is still blocked to verify that auto VT
// does not accept blocked matches
@ -245,6 +260,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
VTAssociationStatus.BLOCKED);
}
private ToolOptions getVTToolOptions(PluginTool tool) {
ToolOptions vtOptions = new VTOptions("Dummy");
if (tool != null) {
vtOptions = tool.getOptions(VTController.VERSION_TRACKING_OPTIONS_NAME);
}
return vtOptions;
}
@Test
public void testDuplicateMatches_DifferentRegisterOperands_allUnique() throws Exception {
@ -270,11 +294,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// run auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Now test that the correct matches were created based on the duplicate functions we created
String correlator = "Duplicate Function Instructions Match";
@ -316,11 +344,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// run auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Now test that the correct matches were created based on the duplicate functions we created
String correlator = "Duplicate Function Instructions Match";
@ -352,11 +384,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// run auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Test to make sure that they weren't matched by something else first so we can
// be sure that we are testing just the duplicate test case
@ -421,11 +457,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// run auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Test to make sure that they weren't matched by something else first so we can
// be sure that we are testing just duplicate correlator match case
@ -575,11 +615,15 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// run auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Test to make sure that they weren't matched by something else first so we can
// be sure that we are testing just the duplicate test case
@ -611,8 +655,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// Put some markup in the tested source function EOL comments
Listing sourceListing = sourceProgram.getListing();
@ -633,7 +676,12 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
sourceProgram.endTransaction(startTransaction, true);
// run Auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Check that the match we are interested in got accepted
String correlator = "Combined Function and Data Reference Match";
@ -667,8 +715,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// Put some markup in the tested source function EOL comments
Listing sourceListing = sourceProgram.getListing();
@ -689,7 +736,12 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
sourceProgram.endTransaction(startTransaction, true);
// run Auto VT
runAutoVTCommand(1.0, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 1.0);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
runAutoVTCommand(vtOptions);
// Check that the match we are interested in got accepted
String correlator = "Duplicate Function Instructions Match";
@ -748,12 +800,16 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
PluginTool tool = env.showTool();
// Now run the AutoVT command with lower confidence thresholds to allow the match we want to
// test in as a match
runAutoVTCommand(0.5, 1.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.5);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 1.0);
runAutoVTCommand(vtOptions);
// Check that the match we are interested in got accepted
String correlator = "Combined Function and Data Reference Match";
@ -812,13 +868,20 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
ToolOptions options = controller.getOptions();
options.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, true);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
runAutoVTCommand(0.999999999, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION, true);
vtOptions.setBoolean(VTOptionDefines.APPLY_IMPLIED_MATCHES_OPTION, true);
vtOptions.setInt(VTOptionDefines.MIN_VOTES_OPTION, 3);
vtOptions.setInt(VTOptionDefines.MAX_CONFLICTS_OPTION, 0);
runAutoVTCommand(vtOptions);
VTMatchSet impliedMatchSet = session.getImpliedMatchSet();
assertTrue(impliedMatchSet.getMatchCount() > 0);
@ -837,10 +900,9 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
VTAssociation association = match.getAssociation();
int numConflicts = association.getRelatedAssociations().size() - 1;
// TODO: use options once options created
// if not min vote count or has conflicts - make sure not accepted match
if (association.getVoteCount() < 2 || numConflicts > 0) {
if (association.getVoteCount() < 3 || numConflicts > 0) {
assertEquals(VTAssociationStatus.AVAILABLE, matchStatus);
continue;
}
@ -860,17 +922,208 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
session = env.createSession(sourceProgram, destinationProgram);
env.showTool();
controller = env.getVTController();
ToolOptions options = controller.getOptions();
options.setBoolean(VTOptionDefines.AUTO_CREATE_IMPLIED_MATCH, false);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
runAutoVTCommand(0.999999999, 10.0);
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setBoolean(VTOptionDefines.CREATE_IMPLIED_MATCHES_OPTION, false);
runAutoVTCommand(vtOptions);
assertTrue(session.getImpliedMatchSet().getMatchCount() == 0);
}
/*
* This tests auto version tracking with some correlators not set to run
*/
@Test
public void testRunAutoVT_disableSomeCorrelators() throws Exception {
sourceProgram = env.getProgram(TEST_SOURCE_PROGRAM_NAME);
destinationProgram = env.getProgram(TEST_DESTINATION_PROGRAM_NAME);
session = env.createSession(sourceProgram, destinationProgram);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION, false);
vtOptions.setBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION, false);
runAutoVTCommand(vtOptions);
VTMatchSet dataMatchSet = getVTMatchSet(session, "Exact Data Match");
assertNull(dataMatchSet);
VTMatchSet dupMatchSet = getVTMatchSet(session, "Duplicate Function Instructions Match");
assertNull(dupMatchSet);
}
/*
* This tests auto version tracking with higher min dupe function len
*/
@Test
public void testRunAutoVT_changeMinFunctionLength() throws Exception {
sourceProgram = env.getProgram(TEST_SOURCE_PROGRAM_NAME);
destinationProgram = env.getProgram(TEST_DESTINATION_PROGRAM_NAME);
session = env.createSession(sourceProgram, destinationProgram);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setInt(VTOptionDefines.DUPE_FUNCTION_CORRELATOR_MIN_LEN_OPTION, 20);
runAutoVTCommand(vtOptions);
VTMatchSet dupMatchSet = getVTMatchSet(session, "Duplicate Function Instructions Match");
assertNotNull(dupMatchSet);
for (VTMatch match : dupMatchSet.getMatches()) {
VTAssociationStatus matchStatus =
getMatchStatus(session, "Duplicate Function Instructions Match",
match.getSourceAddress(), match.getDestinationAddress());
if (matchStatus == VTAssociationStatus.BLOCKED) {
continue;
}
int sourceLength = match.getSourceLength();
int destinationLength = match.getDestinationLength();
if (matchStatus == VTAssociationStatus.AVAILABLE) {
assertTrue(sourceLength < 20);
assertTrue(destinationLength < 20);
continue;
}
if (matchStatus == VTAssociationStatus.ACCEPTED) {
assertTrue(sourceLength >= 20);
assertTrue(destinationLength >= 20);
}
}
}
/*
* This tests auto version tracking with higher min symbol len
*/
@Test
public void testRunAutoVT_changeMinSymbolLength() throws Exception {
sourceProgram = env.getProgram(TEST_SOURCE_PROGRAM_NAME);
destinationProgram = env.getProgram(TEST_DESTINATION_PROGRAM_NAME);
session = env.createSession(sourceProgram, destinationProgram);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setBoolean(VTOptionDefines.RUN_EXACT_DATA_OPTION, false);
vtOptions.setBoolean(VTOptionDefines.RUN_DUPE_FUNCTION_OPTION, false);
vtOptions.setBoolean(VTOptionDefines.RUN_EXACT_FUNCTION_BYTES_OPTION, false);
vtOptions.setBoolean(VTOptionDefines.RUN_REF_CORRELATORS_OPTION, false);
vtOptions.setInt(VTOptionDefines.SYMBOL_CORRELATOR_MIN_LEN_OPTION, 7);
runAutoVTCommand(vtOptions);
VTMatchSet matchSet = getVTMatchSet(session, "Exact Symbol Name Match");
assertNotNull(matchSet);
for (VTMatch match : matchSet.getMatches()) {
VTAssociationStatus matchStatus = getMatchStatus(session, "Exact Symbol Name Match",
match.getSourceAddress(), match.getDestinationAddress());
if (matchStatus == VTAssociationStatus.BLOCKED) {
continue;
}
Address sourceAddress = match.getSourceAddress();
Symbol primarySymbol = sourceProgram.getSymbolTable().getPrimarySymbol(sourceAddress);
int length = primarySymbol.getName().length();
if (matchStatus == VTAssociationStatus.AVAILABLE) {
assertTrue(length < 7);
continue;
}
if (matchStatus == VTAssociationStatus.ACCEPTED) {
assertTrue(length >= 7);
}
}
}
/*
* This tests auto version tracking with higher min data len
*/
@Test
public void testRunAutoVT_changeMinDataLength() throws Exception {
sourceProgram = env.getProgram(TEST_SOURCE_PROGRAM_NAME);
destinationProgram = env.getProgram(TEST_DESTINATION_PROGRAM_NAME);
session = env.createSession(sourceProgram, destinationProgram);
PluginTool tool = env.showTool();
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
ToolOptions vtOptions = getVTToolOptions(tool);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_SCORE_OPTION, 0.999999999);
vtOptions.setDouble(VTOptionDefines.REF_CORRELATOR_MIN_CONF_OPTION, 10.0);
vtOptions.setInt(VTOptionDefines.DATA_CORRELATOR_MIN_LEN_OPTION, 10);
runAutoVTCommand(vtOptions);
VTMatchSet matchSet = getVTMatchSet(session, "Exact Data Match");
assertNotNull(matchSet);
for (VTMatch match : matchSet.getMatches()) {
VTAssociationStatus matchStatus = getMatchStatus(session, "Exact Data Match",
match.getSourceAddress(), match.getDestinationAddress());
if (matchStatus == VTAssociationStatus.BLOCKED) {
continue;
}
Address sourceAddress = match.getSourceAddress();
Data data = sourceProgram.getListing().getDataAt(sourceAddress);
assertNotNull(data);
int length = data.getLength();
if (matchStatus == VTAssociationStatus.AVAILABLE) {
assertTrue(length < 10);
continue;
}
if (matchStatus == VTAssociationStatus.ACCEPTED) {
assertTrue(length >= 10);
}
}
}
private VTMatch createMatch(Address sourceAddress, Address destinationAddress,
boolean setAccepted) throws VTAssociationStatusException {
VTProgramCorrelator correlator =
@ -916,11 +1169,10 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
assertEquals(expectedAcceptedMatchCount, getNumAcceptedMatches(vtSession, correlatorName));
}
private void runAutoVTCommand(double minReferenceCorrelatorScore,
double minReferenceCorrelatorConfidence) {
private void runAutoVTCommand(ToolOptions options) {
AutoVersionTrackingTask task = new AutoVersionTrackingTask(session, controller.getOptions(),
minReferenceCorrelatorScore, minReferenceCorrelatorConfidence);
AutoVersionTrackingTask task =
new AutoVersionTrackingTask(session, options);
TaskLauncher.launch(task);
waitForSession();
}
@ -940,8 +1192,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
}
}
fail("Unable to find a match set for '" + correlatorName + "'");
return null; /// can't get here
return null;
}
private boolean assertCorrectScoreAndConfidenceValues(VTSession vtSession,