();
File queryFile = null;
taintOptions = plugin.getOptions();
@@ -229,37 +243,39 @@ public abstract class AbstractTaintState implements TaintState {
// Make sure we can access and execute the engine binary.
Path engine = Path.of(taintOptions.getTaintEnginePath());
- File engine_file = engine.toFile();
+ File engineFile = engine.toFile();
- if (!engine_file.exists() || !engine_file.canExecute()) {
+ if (!engineFile.exists()) {
plugin.consoleMessage("The " + getName() + " binary (" +
- engine_file.getCanonicalPath() + ") cannot be found or executed.");
- engine_file = getFilePath(taintOptions.getTaintEnginePath(),
+ engineFile.getCanonicalPath() + ") cannot be found or executed.");
+ engineFile = getFilePath(taintOptions.getTaintEnginePath(),
"Select the " + getName() + " binary");
- if (engine_file == null) {
+ if (engineFile == null) {
plugin.consoleMessage(
"No " + getName() + " engine has been specified; exiting query function.");
return false;
}
}
- plugin.consoleMessage("Using " + getName() + " binary: " + engine_file.toString());
+ plugin.consoleMessage("Using " + getName() + " binary: " + engineFile.toString());
- Path index_directory = Path.of(taintOptions.getTaintOutputDirectory());
+ Path indexDirectory = Path.of(taintOptions.getTaintOutputDirectory());
Path indexDBPath = Path.of(taintOptions.getTaintOutputDirectory(),
taintOptions.getTaintIndexDBName(program.getName()));
-
File indexDBFile = indexDBPath.toFile();
- plugin.consoleMessage("Attempting to use index: " + indexDBFile.toString());
-
- if (!indexDBFile.exists()) {
- plugin.consoleMessage("The index database for the binary named: " +
- program.getName() + " does not exist; create it first.");
- return false;
+
+ if (usesIndex) {
+ plugin.consoleMessage("Attempting to use index: " + indexDBFile.toString());
+
+ if (!indexDBFile.exists()) {
+ plugin.consoleMessage("The index database for the binary named: " +
+ program.getName() + " does not exist; create it first.");
+ return false;
+ }
+
+ plugin.consoleMessage("Using index database: " + indexDBFile);
}
- plugin.consoleMessage("Using index database: " + indexDBFile);
-
switch (queryType) {
case SRCSINK:
// Generate a datalog query file based on the selected source, sink, etc. data.
@@ -281,7 +297,7 @@ public abstract class AbstractTaintState implements TaintState {
plugin.consoleMessage("Unknown query type.");
}
- buildQuery(param_list, engine, indexDBFile, index_directory.toString());
+ buildQuery(paramList, engine, indexDBFile, indexDirectory.toString());
if (queryType.equals(QueryType.SRCSINK) || queryType.equals(QueryType.CUSTOM)) {
// The datalog that specifies the query.
@@ -295,12 +311,12 @@ public abstract class AbstractTaintState implements TaintState {
return false;
}
}
- param_list.add(queryFile.getAbsolutePath());
+ paramList.add(queryFile.getAbsolutePath());
}
- Msg.info(this, "Query Param List: " + param_list.toString());
+ Msg.info(this, "Query Param List: " + paramList.toString());
try {
- ProcessBuilder pb = new ProcessBuilder(param_list);
+ ProcessBuilder pb = new ProcessBuilder(paramList);
pb.directory(new File(taintOptions.getTaintOutputDirectory()));
pb.redirectError(Redirect.INHERIT);
Process p = pb.start();
@@ -327,9 +343,10 @@ public abstract class AbstractTaintState implements TaintState {
}
/**
+ * @param prog current program if needed
* @param is the input stream (SARIF json) from the process builder that runs the engine
*/
- private void readQueryResultsIntoDataFrame(Program program, InputStream is) {
+ protected void readQueryResultsIntoDataFrame(Program prog, InputStream is) {
StringBuilder sb = new StringBuilder();
String line = null;
@@ -534,6 +551,7 @@ public abstract class AbstractTaintState implements TaintState {
return plugin.getOptions();
}
+ @Override
public String getName() {
return ENGINE_NAME;
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabel.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabel.java
index c7c8bd90a3..33edbb23a3 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabel.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabel.java
@@ -28,6 +28,7 @@ public class TaintLabel {
private String fname;
private HighFunction hfun;
private HighVariable hvar;
+ private Varnode vnode;
private boolean active;
private String label;
private boolean isGlobal = false;
@@ -36,8 +37,10 @@ public class TaintLabel {
// TODO: This is not a good identifier since it could change during re work!
private Address addr;
private ClangLine clangLine;
+ private int size = 0;
public TaintLabel(MarkType mtype, ClangToken token) throws PcodeException {
+
HighVariable highVar = token.getHighVariable();
if (highVar == null) {
hfun = token.getClangFunction().getHighFunction();
@@ -50,25 +53,31 @@ public class TaintLabel {
}
}
- Varnode exactSpot = token.getVarnode();
- if (exactSpot != null) { // The user pointed at a particular usage, not just the vardecl
- HighVariable high = exactSpot.getHigh();
+ this.vnode = token.getVarnode();
+ if (vnode != null) { // The user pointed at a particular usage, not just the vardecl
+ HighVariable high = vnode.getHigh();
if (high instanceof HighLocal) {
- highVar = hfun.splitOutMergeGroup(high, exactSpot);
+ highVar = hfun.splitOutMergeGroup(high, vnode);
}
}
String fn = token instanceof ClangFuncNameToken ftoken ? ftoken.getText()
: hfun.getFunction().getName();
PcodeOp pcodeOp = token.getPcodeOp();
- Address target = pcodeOp == null ? null : pcodeOp.getSeqnum().getTarget();
-
+ Address target = pcodeOp == null ? hfun.getFunction().getEntryPoint() : pcodeOp.getSeqnum().getTarget();
+ if (vnode == null && pcodeOp != null) {
+ vnode = pcodeOp.getOutput();
+ }
+
this.mtype = mtype;
this.token = token;
this.fname = fn;
this.hvar = highVar;
this.active = true;
this.addr = target;
+ if (hvar != null) {
+ size = hvar.getSize();
+ }
this.clangLine = token.getLineParent();
// Initial label is one of SOURCE, SINK, or GATE
@@ -145,6 +154,14 @@ public class TaintLabel {
public void activate() {
active = true;
}
+
+ public int getSize() {
+ return size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
public void toggle() {
active = !active;
@@ -213,5 +230,12 @@ public class TaintLabel {
}
return true;
}
+
+ public Address getVarnodeAddress() {
+ if (vnode != null) {
+ return vnode.getAddress();
+ }
+ return null;
+ }
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintOptions.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintOptions.java
index 1f32ddf8b6..d249163c0b 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintOptions.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintOptions.java
@@ -45,6 +45,7 @@ public class TaintOptions {
/* The default name of the index database file. */
public final static String OP_KEY_TAINT_DB = "Taint.Query.Index";
+ public final static String OP_KEY_TAINT_QUERY_ENGINE = "Taint.Query Engine";
public final static String OP_KEY_TAINT_QUERY_DIRECTION = "Taint.Force Direction";
public final static String OP_KEY_TAINT_QUERY_OUTPUT_FORM = "Taint.Output Format";
/* Color used in the decompiler to highlight taint. */
@@ -68,13 +69,14 @@ public class TaintOptions {
new GColor("color.bg.listing.highlighter.default");
private final static Highlighter TAINT_HIGHLIGHT_STYLE_DEFAULT = Highlighter.DEFAULT;
- private String taintEngine;
+ private String taintEnginePath;
private String taintFactsDir;
private String taintOutputDir;
private String taintQuery;
private String taintDB;
+ private String taintQueryEngine;
private TaintDirection taintQueryDirection;
private TaintFormat taintQueryOutputForm;
@@ -106,7 +108,7 @@ public class TaintOptions {
public TaintOptions(TaintProvider provider) {
taintProvider = provider;
- taintEngine = DEFAULT_TAINT_ENGINE_PATH;
+ taintEnginePath = DEFAULT_TAINT_ENGINE_PATH;
taintFactsDir = DEFAULT_TAINT_FACTS_DIR;
taintOutputDir = DEFAULT_TAINT_OUTPUT_DIR;
taintQuery = DEFAULT_TAINT_QUERY;
@@ -129,7 +131,11 @@ public class TaintOptions {
opt.registerOption(OP_KEY_TAINT_QUERY_OUTPUT_FORM, TaintFormat.ALL,
new HelpLocation(HelpTopics.DECOMPILER, "Taint Output Type"),
- "The type of Source-Sink query output (e.g., sarif, summary, text");
+ "The type of Source-Sink query output (e.g., sarif, summary, text)");
+
+ opt.registerOption(OP_KEY_TAINT_QUERY_ENGINE, "",
+ new HelpLocation(HelpTopics.DECOMPILER, "Taint Query Engine"),
+ "The query engine (e.g., angr, ctadl)");
opt.registerOption(OP_KEY_TAINT_ENGINE_PATH, DEFAULT_TAINT_ENGINE_PATH,
new HelpLocation(HelpTopics.DECOMPILER, "Taint Engine Directory"),
@@ -176,7 +182,17 @@ public class TaintOptions {
*/
public void grabFromToolAndProgram(Plugin ownerPlugin, ToolOptions opt, Program program) {
- taintEngine = opt.getString(OP_KEY_TAINT_ENGINE_PATH, "");
+ String engine = opt.getString(OP_KEY_TAINT_QUERY_ENGINE, "");
+ if (!engine.equals(taintQueryEngine)) {
+ TaintPlugin plugin = (TaintPlugin) ownerPlugin;
+ TaintState state = TaintState.newInstance(plugin, engine);
+ if (state != null) {
+ plugin.setTaintState(state);
+ taintQueryEngine = engine;
+ }
+ }
+
+ taintEnginePath = opt.getString(OP_KEY_TAINT_ENGINE_PATH, "");
taintFactsDir = opt.getString(OP_KEY_TAINT_FACTS_DIR, "");
taintQuery = opt.getString(OP_KEY_TAINT_QUERY, "");
// taintQueryResultsFile = opt.getString(OP_KEY_TAINT_QUERY_RESULTS, "");
@@ -196,8 +212,12 @@ public class TaintOptions {
return taintQueryOutputForm;
}
+ public String getTaintEngineType() {
+ return taintQueryEngine;
+ }
+
public String getTaintEnginePath() {
- return taintEngine;
+ return taintEnginePath;
}
public String getTaintFactsDirectory() {
@@ -244,6 +264,11 @@ public class TaintOptions {
return taintUseAllAccess;
}
+ public void setTaintQueryEngine(String engine) {
+ this.taintQueryEngine = engine;
+ taintProvider.setOption(OP_KEY_TAINT_QUERY_ENGINE, engine);
+ }
+
public void setTaintOutputForm(TaintFormat form) {
this.taintQueryOutputForm = form;
taintProvider.setOption(OP_KEY_TAINT_QUERY_OUTPUT_FORM, form.getOptionString());
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintPlugin.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintPlugin.java
index 00e7ba157e..4dc83df83d 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintPlugin.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintPlugin.java
@@ -111,8 +111,11 @@ public class TaintPlugin extends ProgramPlugin implements TaintService {
}
public static enum TaintFormat {
- ALL("all", "sarif+all"), GRAPHS("graphs", "sarif+graphs"),
- INSTS("insts", "sarif+instructions"), PATHS("paths", "sarif");
+ ALL("all", "sarif+all"),
+ GRAPHS("graphs", "sarif+graphs"),
+ INSTS("insts", "sarif+instructions"),
+ PATHS("paths", "sarif"),
+ NONE("none", "none");
private String label;
private String optionString;
@@ -175,7 +178,6 @@ public class TaintPlugin extends ProgramPlugin implements TaintService {
public TaintPlugin(PluginTool tool) {
super(tool);
- state = TaintState.newInstance(this);
taintProvider = new TaintProvider(this);
taintDecompMarginProvider = new TaintDecompilerMarginProvider(this);
createActions();
@@ -353,9 +355,11 @@ public class TaintPlugin extends ProgramPlugin implements TaintService {
GhidraState ghidraState = new GhidraState(tool, null, currentProgram,
currentLocation, currentHighlight, currentHighlight);
GhidraScript exportScript = state.getExportScript(consoleService, false);
- RunPCodeExportScriptTask export_task =
- new RunPCodeExportScriptTask(tool, exportScript, ghidraState, consoleService);
- tool.execute(export_task);
+ if (exportScript != null) {
+ RunPCodeExportScriptTask export_task =
+ new RunPCodeExportScriptTask(tool, exportScript, ghidraState, consoleService);
+ tool.execute(export_task);
+ }
}
@Override
@@ -433,6 +437,10 @@ public class TaintPlugin extends ProgramPlugin implements TaintService {
return state;
}
+ public void setTaintState(TaintState state) {
+ this.state = state;
+ }
+
public TaintProvider getProvider() {
return taintProvider;
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintProvider.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintProvider.java
index 34b605fdbe..c5bbccdbae 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintProvider.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintProvider.java
@@ -61,8 +61,6 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
private DecompilerProvider decompilerProvider;
private Navigatable navigatable;
- private TaintState state;
-
private DecompilerHighlighter highlighter;
private TaintCTokenHighlighterPalette highlightPalette;
@@ -84,7 +82,6 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
super(plugin.getTool(), "TaintProvider", plugin.getName(), DecompilerActionContext.class);
this.plugin = plugin;
this.taintOptions = new TaintOptions(this);
- this.state = plugin.getTaintState();
this.cachedHighlightsByToken = new HashMap<>();
this.cachedHighlightByAddress = new HashMap<>();
this.highlightPalette = new TaintCTokenHighlighterPalette(256);
@@ -108,34 +105,37 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
// These actions are only available in the drop-down window
- TaintSourceAction taintSourceAction = new TaintSourceAction(plugin, state);
+ TaintSourceAction taintSourceAction = new TaintSourceAction(plugin);
setGroupInfo(taintSourceAction, variableGroup, subGroupPosition++);
TaintSourceBySymbolAction taintSourceBySymbolAction =
- new TaintSourceBySymbolAction(plugin, state);
+ new TaintSourceBySymbolAction(plugin);
setGroupInfo(taintSourceBySymbolAction, variableGroup, subGroupPosition++);
- TaintSinkAction taintSinkAction = new TaintSinkAction(plugin, state);
+ TaintSinkAction taintSinkAction = new TaintSinkAction(plugin);
setGroupInfo(taintSinkAction, variableGroup, subGroupPosition++);
TaintSinkBySymbolAction taintSinkBySymbolAction =
- new TaintSinkBySymbolAction(plugin, state);
+ new TaintSinkBySymbolAction(plugin);
setGroupInfo(taintSinkBySymbolAction, variableGroup, subGroupPosition++);
- TaintGateAction taintGateAction = new TaintGateAction(plugin, state);
+ TaintGateAction taintGateAction = new TaintGateAction(plugin);
setGroupInfo(taintGateAction, variableGroup, subGroupPosition++);
- TaintClearAction taintClearAction = new TaintClearAction(plugin, state);
+ TaintClearAction taintClearAction = new TaintClearAction(plugin);
setGroupInfo(taintClearAction, variableGroup, subGroupPosition++);
- // These actions have an icon and a drop-down menu option in the decompiler window.
- TaintQueryAction taintQueryAction = new TaintQueryAction(plugin, state);
- TaintQueryDefaultAction taintQueryDefaultAction =
- new TaintQueryDefaultAction(plugin, state);
- TaintQueryCustomAction taintQueryCustomAction = new TaintQueryCustomAction(plugin, state);
- TaintLoadAction taintLoadAction = new TaintLoadAction(plugin, state);
+ TaintSetSizeAction taintSizeAction = new TaintSetSizeAction(plugin);
+ setGroupInfo(taintSizeAction, variableGroup, subGroupPosition++);
- TaintSliceTreeAction taintSliceTreeAction = new TaintSliceTreeAction(plugin, state);
+ // These actions have an icon and a drop-down menu option in the decompiler window.
+ TaintQueryAction taintQueryAction = new TaintQueryAction(plugin);
+ TaintQueryDefaultAction taintQueryDefaultAction =
+ new TaintQueryDefaultAction(plugin);
+ TaintQueryCustomAction taintQueryCustomAction = new TaintQueryCustomAction(plugin);
+ TaintLoadAction taintLoadAction = new TaintLoadAction(plugin);
+
+ TaintSliceTreeAction taintSliceTreeAction = new TaintSliceTreeAction(plugin);
DockingAction taintLabelTableAction = new DockingAction("TaintShowLabels", TaintPlugin.HELP_LOCATION) {
@@ -153,7 +153,8 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
@Override
public boolean isEnabledForContext(ActionContext context) {
- return state.hasMarks();
+ TaintState state = plugin.getTaintState();
+ return state == null ? false : state.hasMarks();
}
};
@@ -175,6 +176,7 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
provider.addLocalAction(taintQueryCustomAction);
provider.addLocalAction(taintLoadAction);
provider.addLocalAction(taintClearAction);
+ provider.addLocalAction(taintSizeAction);
}
/**
@@ -253,6 +255,10 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
* @param taskType subtract previous result
*/
public void setTaint(TaskType taskType) {
+ TaintState state = plugin.getTaintState();
+ if (state == null) {
+ return;
+ }
if (navigatable == null) {
navigatable = tool.getService(CodeViewerService.class).getNavigatable();
}
@@ -284,6 +290,11 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
}
public boolean matchOn(ClangToken token) {
+
+ TaintState state = plugin.getTaintState();
+ if (state == null) {
+ return false;
+ }
if (token instanceof ClangBreak ||
token instanceof ClangTypeToken ||
@@ -372,7 +383,7 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh
Msg.info(this,
"TaintProvider: clearTaint() - state clearTaint() and highligher apply highlights.");
matchCount = 0;
- state.clearTaint();
+ plugin.getTaintState().clearTaint();
highlighter.clearHighlights();
cachedHighlightByAddress.clear();
cachedHighlightsByToken.clear();
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintState.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintState.java
index 3c1b256f76..dc1c3332bb 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintState.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintState.java
@@ -16,12 +16,12 @@
package ghidra.app.plugin.core.decompiler.taint;
import java.io.File;
+import java.lang.reflect.Constructor;
import java.util.*;
import com.contrastsecurity.sarif.SarifSchema210;
import ghidra.app.decompiler.*;
-import ghidra.app.plugin.core.decompiler.taint.ctadl.TaintStateCTADL;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.ConsoleService;
import ghidra.framework.plugintool.PluginTool;
@@ -31,12 +31,18 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolTable;
+import ghidra.util.Msg;
+import ghidra.util.classfinder.ClassSearcher;
+import ghidra.util.classfinder.ExtensionPoint;
/**
* The interface for the methods that collect desired taint information from the decompiler window and store them
* for construction of queries and indexing.
+ *
+ * NOTE: ALL TaintState CLASSES MUST END IN "TaintState". If not,
+ * the ClassSearcher will not find them.
*/
-public interface TaintState {
+public interface TaintState extends ExtensionPoint {
public enum MarkType {
SOURCE, SINK, GATE
@@ -50,10 +56,31 @@ public interface TaintState {
SET_TAINT, SET_DELTA, APPLY_DELTA
}
- public static TaintState newInstance(TaintPlugin plugin) {
- return new TaintStateCTADL(plugin);
+ public static TaintState newInstance(TaintPlugin plugin, String type) {
+ List> list = ClassSearcher.getClasses(TaintState.class)
+ .stream()
+ .toList();
+ Class>[] constructorArgumentTypes = {TaintPlugin.class};
+ Object[] args = new Object[1];
+ args[0] = plugin;
+ for (Class extends TaintState> clazz : list) {
+ if (clazz.getName().toLowerCase().contains(type)) {
+ try {
+ Constructor> constructor = clazz.getConstructor(constructorArgumentTypes);
+ Object obj = constructor.newInstance(plugin);
+ return TaintState.class.cast(obj);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Unable to instantiate TaintState");
+ }
+ }
+ }
+ Msg.error(plugin, "No match for engine = "+type);
+ return null;
}
+ public String getName();
+
/**
* Perform a Source-Sink query on the index database.
*
@@ -108,6 +135,10 @@ public interface TaintState {
public GhidraScript getExportScript(ConsoleService console, boolean perFunction);
+ public void setTaskType(TaskType taskType);
+
+ public TaintLabel getLabelForToken(MarkType type, ClangToken token);
+
public static String hvarName(ClangToken token) {
HighVariable hv = token.getHighVariable();
HighFunction hf =
@@ -159,6 +190,4 @@ public interface TaintState {
return false;
}
- public void setTaskType(TaskType taskType);
-
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintAbstractQueryAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintAbstractQueryAction.java
index ef6d284040..52ee73f957 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintAbstractQueryAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintAbstractQueryAction.java
@@ -20,6 +20,7 @@ import javax.swing.Icon;
import docking.action.MenuData;
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.*;
+import ghidra.app.plugin.core.decompiler.taint.TaintPlugin.TaintFormat;
import ghidra.app.plugin.core.decompiler.taint.TaintState.QueryType;
import ghidra.app.plugin.core.decompiler.taint.sarif.SarifTaintGraphRunHandler;
import ghidra.framework.plugintool.PluginTool;
@@ -37,7 +38,6 @@ import sarif.SarifService;
public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAction {
protected TaintPlugin plugin;
- protected TaintState state;
protected String desc;
protected String title;
@@ -45,14 +45,13 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc
protected Icon executeTaintQueryIcon;
protected QueryType queryType;
- public TaintAbstractQueryAction(TaintPlugin plugin, TaintState state, String desc, String title, String cmd) {
+ public TaintAbstractQueryAction(TaintPlugin plugin, String desc, String title, String cmd) {
super(cmd);
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "Taint"+desc));
setMenuBarData(new MenuData(new String[] { "Source-Sink", getName() }));
this.plugin = plugin;
- this.state = state;
this.desc = desc;
this.title = title;
}
@@ -62,6 +61,9 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc
*/
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
return true;
}
@@ -73,6 +75,7 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc
Task defaultQueryTask = new Task(title, true, true, true, true) {
@Override
public void run(TaskMonitor monitor) {
+ TaintState state = plugin.getTaintState();
state.setCancellation(false);
monitor.initialize(program.getFunctionManager().getFunctionCount());
state.queryIndex(program, tool, queryType);
@@ -87,10 +90,14 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc
// We still get a progress bar and option to cancel.
tool.execute(defaultQueryTask);
+ TaintState state = plugin.getTaintState();
if (!state.wasCancelled()) {
- SarifService sarifService = plugin.getSarifService();
- sarifService.getController().setDefaultGraphHander(SarifTaintGraphRunHandler.class);
- sarifService.showSarif(desc, state.getData());
+ TaintFormat format = state.getOptions().getTaintOutputForm();
+ if (!format.equals(TaintFormat.NONE)) {
+ SarifService sarifService = plugin.getSarifService();
+ sarifService.getController().setDefaultGraphHander(SarifTaintGraphRunHandler.class);
+ sarifService.showSarif(desc, state.getData());
+ }
plugin.consoleMessage("executing query...");
TaintProvider provider = plugin.getProvider();
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintClearAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintClearAction.java
index 1342792aaa..ce17896d1d 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintClearAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintClearAction.java
@@ -23,7 +23,6 @@ import docking.action.MenuData;
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
-import ghidra.app.util.HelpTopics;
import ghidra.util.HelpLocation;
/**
@@ -34,25 +33,26 @@ import ghidra.util.HelpLocation;
public class TaintClearAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
- private TaintState state;
- public TaintClearAction(TaintPlugin plugin, TaintState state) {
+ public TaintClearAction(TaintPlugin plugin) {
super("Clear Markers");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintClear"));
setPopupMenuData(new MenuData(new String[] { "Taint", "Clear" }, "Decompile"));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
this.plugin = plugin;
- this.state = state;
}
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
return true;
}
@Override
protected void decompilerActionPerformed(DecompilerActionContext context) {
- state.clearMarkers();
+ plugin.getTaintState().clearMarkers();
plugin.clearIcons();
plugin.clearTaint();
plugin.consoleMessage("taint cleared");
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintGateAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintGateAction.java
index 7e413ac8d9..c55497d576 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintGateAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintGateAction.java
@@ -25,7 +25,6 @@ import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -43,7 +42,7 @@ public class TaintGateAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
private MarkType mtype;
- public TaintGateAction(TaintPlugin plugin, TaintState state) {
+ public TaintGateAction(TaintPlugin plugin) {
super("Mark Gate");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintGate"));
setPopupMenuData(new MenuData(new String[] { "Taint", "Gate" }, "Decompile"));
@@ -58,6 +57,10 @@ public class TaintGateAction extends TaintAbstractDecompilerAction {
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
Function function = context.getFunction();
if (function == null || function instanceof UndefinedFunction) {
return false;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintLoadAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintLoadAction.java
index 10c5d4a641..09f6d85d29 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintLoadAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintLoadAction.java
@@ -27,7 +27,6 @@ import generic.theme.GIcon;
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
-import ghidra.app.util.HelpTopics;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;
@@ -47,12 +46,11 @@ import ghidra.util.HelpLocation;
public class TaintLoadAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
- private TaintState state;
private static String loadSarifFileIconString = "icon.fsbrowser.file.extension.obj";
private static Icon loadSarifFileIcon = new GIcon(loadSarifFileIconString);
- public TaintLoadAction(TaintPlugin plugin, TaintState state) {
+ public TaintLoadAction(TaintPlugin plugin) {
super("Load SARIF file");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintLoadSarif"));
@@ -60,7 +58,6 @@ public class TaintLoadAction extends TaintAbstractDecompilerAction {
setToolBarData(new ToolBarData(loadSarifFileIcon));
this.plugin = plugin;
- this.state = state;
}
@Override
@@ -78,6 +75,7 @@ public class TaintLoadAction extends TaintAbstractDecompilerAction {
// Pop a file dialog to select the SARIF file.
// need to pop-up a file chooser dialog.
+ TaintState state = plugin.getTaintState();
GhidraFileChooser file_chooser = new GhidraFileChooser(tool.getToolFrame());
file_chooser.setCurrentDirectory(new File(state.getOptions().getTaintEnginePath()));
file_chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryAction.java
index 2ada4ef297..9ae43d9801 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryAction.java
@@ -27,8 +27,8 @@ import ghidra.app.plugin.core.decompiler.taint.TaintState.QueryType;
public class TaintQueryAction extends TaintAbstractQueryAction {
- public TaintQueryAction(TaintPlugin plugin, TaintState state) {
- super(plugin, state, "Query", "Source-Sink Taint Query", "Run taint query");
+ public TaintQueryAction(TaintPlugin plugin) {
+ super(plugin, "Query", "Source-Sink Taint Query", "Run taint query");
executeTaintQueryIconString = "icon.graph.default.display.program.graph";
executeTaintQueryIcon = new GIcon(executeTaintQueryIconString);
queryType = QueryType.SRCSINK;
@@ -39,7 +39,8 @@ public class TaintQueryAction extends TaintAbstractQueryAction {
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
- return state.isValid();
+ TaintState state = plugin.getTaintState();
+ return state == null ? false : state.isValid();
}
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryCustomAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryCustomAction.java
index eac8d0b915..ba4c2a31e6 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryCustomAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryCustomAction.java
@@ -25,8 +25,8 @@ import ghidra.app.plugin.core.decompiler.taint.TaintState.QueryType;
public class TaintQueryCustomAction extends TaintAbstractQueryAction {
- public TaintQueryCustomAction(TaintPlugin plugin, TaintState state) {
- super(plugin, state, "CustomQuery", "Custom Taint Query", "Run custom taint query");
+ public TaintQueryCustomAction(TaintPlugin plugin) {
+ super(plugin, "CustomQuery", "Custom Taint Query", "Run custom taint query");
queryType = QueryType.CUSTOM;
setKeyBindingData(new KeyBindingData(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryDefaultAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryDefaultAction.java
index 27fa19078c..2760b841e9 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryDefaultAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintQueryDefaultAction.java
@@ -27,8 +27,8 @@ import ghidra.app.plugin.core.decompiler.taint.TaintState.QueryType;
public class TaintQueryDefaultAction extends TaintAbstractQueryAction {
- public TaintQueryDefaultAction(TaintPlugin plugin, TaintState state) {
- super(plugin, state, "DefaultQuery", "Default Taint Query", "Run default taint query");
+ public TaintQueryDefaultAction(TaintPlugin plugin) {
+ super(plugin, "DefaultQuery", "Default Taint Query", "Run default taint query");
executeTaintQueryIconString = "icon.version.tracking.markup.status.conflict";
executeTaintQueryIcon = new GIcon(executeTaintQueryIconString);
queryType = QueryType.DEFAULT;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSetSizeAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSetSizeAction.java
new file mode 100644
index 0000000000..c33f3b7c51
--- /dev/null
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSetSizeAction.java
@@ -0,0 +1,97 @@
+/* ###
+ * 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.
+ */
+package ghidra.app.plugin.core.decompiler.taint.actions;
+
+import docking.action.MenuData;
+import docking.widgets.dialogs.InputDialog;
+import ghidra.app.decompiler.*;
+import ghidra.app.plugin.core.decompile.DecompilerActionContext;
+import ghidra.app.plugin.core.decompiler.taint.TaintLabel;
+import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
+import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
+import ghidra.program.model.listing.Function;
+import ghidra.util.UndefinedFunction;
+
+/**
+ * Triggered by right-click on a token in the decompiler window.
+ *
+ * Action triggered from a specific token in the decompiler window to mark a variable as a
+ * source or sink and generate the requisite query. Legal tokens to select include:
+ *
-
+ * An input parameter,
+ *
-
+ * A stack variable,
+ *
-
+ * A variable associated with a register, or
+ *
-
+ * A "dynamic" variable.
+ *
+ */
+public class TaintSetSizeAction extends TaintAbstractDecompilerAction {
+
+ private TaintPlugin plugin;
+
+ public TaintSetSizeAction(TaintPlugin plugin) {
+ super("Set length");
+ // Taint Menu -> Source sub item.
+ setPopupMenuData(new MenuData(new String[] { "Taint", "Set length" }, "Decompile"));
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
+ Function function = context.getFunction();
+ if (function == null || function instanceof UndefinedFunction) {
+ return false;
+ }
+
+ ClangToken tokenAtCursor = context.getTokenAtCursor();
+ if (tokenAtCursor == null) {
+ return false;
+ }
+ if (tokenAtCursor instanceof ClangFieldToken) {
+ return true;
+ }
+ if (tokenAtCursor.Parent() instanceof ClangReturnType) {
+ return false;
+ }
+ if (tokenAtCursor instanceof ClangFuncNameToken) {
+ return true;
+ }
+ if (!tokenAtCursor.isVariableRef()) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void decompilerActionPerformed(DecompilerActionContext context) {
+ TaintLabel label = plugin.getTaintState().getLabelForToken(MarkType.SOURCE, context.getTokenAtCursor());
+ if (label != null) {
+ InputDialog dialog = new InputDialog("Update length", "Length", Integer.toHexString(label.getSize()));
+ plugin.getTool().showDialog(dialog);
+ if (dialog.isCanceled()) {
+ return;
+ }
+ String val = dialog.getValue();
+ label.setSize(Integer.parseInt(val, 16));
+ }
+ }
+}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkAction.java
index 9bf5cf30fd..d4836f4d16 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkAction.java
@@ -25,7 +25,6 @@ import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -40,7 +39,7 @@ public class TaintSinkAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
private MarkType mtype;
- public TaintSinkAction(TaintPlugin plugin, TaintState state) {
+ public TaintSinkAction(TaintPlugin plugin) {
super("Mark Sink");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintSink"));
setPopupMenuData(new MenuData(new String[] { "Taint", "Sink" }, "Decompile"));
@@ -59,6 +58,10 @@ public class TaintSinkAction extends TaintAbstractDecompilerAction {
*/
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
Function function = context.getFunction();
if (function == null || function instanceof UndefinedFunction) {
return false;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkBySymbolAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkBySymbolAction.java
index fcd539987a..d743631b8a 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkBySymbolAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSinkBySymbolAction.java
@@ -21,7 +21,6 @@ import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -36,7 +35,7 @@ public class TaintSinkBySymbolAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
private MarkType mtype;
- public TaintSinkBySymbolAction(TaintPlugin plugin, TaintState state) {
+ public TaintSinkBySymbolAction(TaintPlugin plugin) {
super("Mark Sink (Symbol)");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintSinkSymbol"));
setPopupMenuData(new MenuData(new String[] { "Taint", "Sink (Symbol)" }, "Decompile"));
@@ -54,6 +53,10 @@ public class TaintSinkBySymbolAction extends TaintAbstractDecompilerAction {
*/
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
Function function = context.getFunction();
if (function == null || function instanceof UndefinedFunction) {
return false;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSliceTreeAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSliceTreeAction.java
index c7c632472e..b54aba5e53 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSliceTreeAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSliceTreeAction.java
@@ -20,7 +20,6 @@ import ghidra.app.decompiler.ClangToken;
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.HighVariable;
import ghidra.util.HelpLocation;
@@ -45,7 +44,7 @@ public class TaintSliceTreeAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
- public TaintSliceTreeAction(TaintPlugin plugin, TaintState state) {
+ public TaintSliceTreeAction(TaintPlugin plugin) {
super("Show Slice Tree");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintSliceTree"));
setPopupMenuData(new MenuData(new String[] { "Taint", "Slice Tree" }, "Decompile"));
@@ -56,6 +55,10 @@ public class TaintSliceTreeAction extends TaintAbstractDecompilerAction {
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
return true;
}
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceAction.java
index 55dd7a3471..792a61edb5 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceAction.java
@@ -24,7 +24,6 @@ import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -49,7 +48,7 @@ public class TaintSourceAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
private MarkType mtype;
- public TaintSourceAction(TaintPlugin plugin, TaintState state) {
+ public TaintSourceAction(TaintPlugin plugin) {
super("Mark Source");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintSource"));
// Taint Menu -> Source sub item.
@@ -66,6 +65,10 @@ public class TaintSourceAction extends TaintAbstractDecompilerAction {
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
Function function = context.getFunction();
if (function == null || function instanceof UndefinedFunction) {
return false;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceBySymbolAction.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceBySymbolAction.java
index 8072edb417..29a1c353ce 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceBySymbolAction.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/actions/TaintSourceBySymbolAction.java
@@ -21,7 +21,6 @@ import ghidra.app.plugin.core.decompile.DecompilerActionContext;
import ghidra.app.plugin.core.decompiler.taint.TaintPlugin;
import ghidra.app.plugin.core.decompiler.taint.TaintState;
import ghidra.app.plugin.core.decompiler.taint.TaintState.MarkType;
-import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -46,7 +45,7 @@ public class TaintSourceBySymbolAction extends TaintAbstractDecompilerAction {
private TaintPlugin plugin;
private MarkType mtype;
- public TaintSourceBySymbolAction(TaintPlugin plugin, TaintState state) {
+ public TaintSourceBySymbolAction(TaintPlugin plugin) {
super("Mark Source (Symbol)");
setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, "TaintSourceSymbol"));
// Taint Menu -> Source sub item.
@@ -61,6 +60,10 @@ public class TaintSourceBySymbolAction extends TaintAbstractDecompilerAction {
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
+ if (plugin.getTaintState() == null) {
+ return false;
+ }
+
Function function = context.getFunction();
if (function == null || function instanceof UndefinedFunction) {
return false;
diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/TaintStateCTADL.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/CTADLTaintState.java
similarity index 94%
rename from Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/TaintStateCTADL.java
rename to Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/CTADLTaintState.java
index 7781c41dc8..fe65000da6 100644
--- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/TaintStateCTADL.java
+++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/ctadl/CTADLTaintState.java
@@ -35,9 +35,9 @@ import ghidra.program.model.pcode.HighVariable;
* Container for all the decompiler elements the users "selects" via the menu.
* This data is used to build queries.
*/
-public class TaintStateCTADL extends AbstractTaintState {
+public class CTADLTaintState extends AbstractTaintState {
- public TaintStateCTADL(TaintPlugin plugin) {
+ public CTADLTaintState(TaintPlugin plugin) {
super(plugin);
ENGINE_NAME = "ctadl";
}
@@ -106,6 +106,12 @@ public class TaintStateCTADL extends AbstractTaintState {
return perFunction ? "ExportPCodeForSingleFunction.java" : "ExportPCodeForCTADL.java";
}
+
+ @Override
+ protected void writeHeader(PrintWriter writer) {
+ writer.println("#include \"pcode/taintquery.dl\"");
+ }
+
/*
* NOTE: This is the only method used now for Sources and Sinks.
*/
@@ -178,6 +184,7 @@ public class TaintStateCTADL extends AbstractTaintState {
Boolean allAccess = taintOptions.getTaintUseAllAccess();
String method = "TaintSanitizeAll";
Address addr = mark.getAddress();
+ // TODO: verify setting entryPoint as addr doesn't break things
if (mark.getFunctionName() == null) {
return;
@@ -199,4 +206,9 @@ public class TaintStateCTADL extends AbstractTaintState {
writer.println("\tVertex(vn, p).");
}
+ @Override
+ protected void writeFooter(PrintWriter writer) {
+ // Nothing to do here
+ }
+
}