diff --git a/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java b/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java index 75bb5dbd53..d4378ac49b 100644 --- a/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java @@ -184,6 +184,10 @@ public class ResolveX86orX64LinuxSyscallsScript extends GhidraScript { funcName = syscallNumbersToNames.get(offset); } callee = createFunction(callTarget, funcName); + if (callee == null) { + Msg.warn(this, "Unable to create function at "+callTarget); + continue; + } callee.setCallingConvention(callingConvention); //check if the function name is one of the non-returning syscalls diff --git a/Ghidra/Features/DecompilerDependent/certification.manifest b/Ghidra/Features/DecompilerDependent/certification.manifest index 7bada2609a..5e08aeb77e 100644 --- a/Ghidra/Features/DecompilerDependent/certification.manifest +++ b/Ghidra/Features/DecompilerDependent/certification.manifest @@ -8,3 +8,5 @@ src/main/help/help/topics/DecompilerTaint/DecompilerTaint.html||GHIDRA||||END| src/main/help/help/topics/DecompilerTextFinderPlugin/Decompiler_Text_Finder.html||GHIDRA||||END| src/main/help/help/topics/DecompilerTextFinderPlugin/images/DecompilerTextFinderDialog.png||GHIDRA||||END| src/main/help/help/topics/DecompilerTextFinderPlugin/images/DecompilerTextFinderResultsTable.png||GHIDRA||||END| +src/main/resources/images/default-query.png||GHIDRA||||END| +src/main/resources/images/gate-set.png||GHIDRA||||END| diff --git a/Ghidra/Features/DecompilerDependent/data/decompiler.dependent.theme.properties b/Ghidra/Features/DecompilerDependent/data/decompiler.dependent.theme.properties index d750ff76df..b5cba262ee 100644 --- a/Ghidra/Features/DecompilerDependent/data/decompiler.dependent.theme.properties +++ b/Ghidra/Features/DecompilerDependent/data/decompiler.dependent.theme.properties @@ -8,5 +8,7 @@ color.bg.decompiler.highlights.sourcesink = color.palette.darkcyan color.bg.decompiler.highlights.path = color.palette.yellow icon.plugin.decompiler.text.finder.select.functions = icon.make.selection {FunctionScope.gif[size(12,12)][move(6,6)]} +icon.plugin.decompiler.taint.gate.set = gate-set.png +icon.plugin.decompiler.taint.default.query = default-query.png [Dark Defaults] \ No newline at end of file diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/absint/AbstractInterpretationService.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/absint/AbstractInterpretationService.java new file mode 100644 index 0000000000..b4ad16a564 --- /dev/null +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/absint/AbstractInterpretationService.java @@ -0,0 +1,29 @@ +/* ### + * 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.absint; + +import ghidra.framework.plugintool.ServiceInfo; + +/** + * The AbstractInterpretationService provides a general service for generating results from an external engine + */ +@ServiceInfo(description = "supply abstract interpretation") +public interface AbstractInterpretationService { + + public String getActiveQueryName(); + + +} diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/AbstractTaintState.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/AbstractTaintState.java index 5c1a13974e..0ca4c22bc7 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/AbstractTaintState.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/AbstractTaintState.java @@ -33,6 +33,7 @@ import ghidra.program.model.listing.Program; import ghidra.program.model.pcode.HighVariable; import ghidra.program.model.pcode.PcodeException; import ghidra.util.Msg; +import ghidra.util.task.TaskMonitor; import sarif.SarifService; /** @@ -59,10 +60,11 @@ public abstract class AbstractTaintState implements TaintState { protected TaintOptions taintOptions; protected TaintPlugin plugin; protected boolean usesIndex = true; - private boolean cancellation; + protected TaskMonitor monitor = TaskMonitor.DUMMY; private TaskType taskType = TaskType.SET_TAINT; + public AbstractTaintState(TaintPlugin plugin) { this.plugin = plugin; } @@ -83,13 +85,22 @@ public abstract class AbstractTaintState implements TaintState { protected abstract void writeFooter(PrintWriter writer); @Override - public boolean wasCancelled() { - return this.cancellation; + public void setMonitor(TaskMonitor monitor) { + if (monitor != null) { + monitor.setIndeterminate(true); + monitor.setShowProgressValue(false); + } + this.monitor = monitor; } @Override - public void setCancellation(boolean status) { - this.cancellation = status; + public boolean isCancelled() { + return monitor != null && monitor.isCancelled(); + } + + @Override + public void cancel() { + monitor.cancel(); } @Override @@ -320,6 +331,10 @@ public abstract class AbstractTaintState implements TaintState { pb.redirectError(Redirect.INHERIT); Process p = pb.start(); + monitor.addCancelledListener(() -> { + p.destroyForcibly(); + }); + readQueryResultsIntoDataFrame(program, p.getInputStream()); // We wait for the process to finish after starting to read the input stream, @@ -555,4 +570,9 @@ public abstract class AbstractTaintState implements TaintState { return ENGINE_NAME; } + @Override + public String getQueryName() { + return null; + } + } diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintDecompilerMarginProvider.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintDecompilerMarginProvider.java index 98690229b6..d2b55f47cf 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintDecompilerMarginProvider.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintDecompilerMarginProvider.java @@ -57,7 +57,7 @@ public class TaintDecompilerMarginProvider extends JPanel private Icon sourceIcon = new GIcon("icon.plugin.scriptmanager.run"); private Icon sinkIcon = new GIcon("icon.stop"); - private Icon gateIcon = new GIcon("icon.debugger.breakpoint.set"); + private Icon gateIcon = new GIcon("icon.plugin.decompiler.taint.gate.set"); public TaintDecompilerMarginProvider(TaintPlugin plugin) { this.plugin = plugin; diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabelsTableProvider.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabelsTableProvider.java index e4a58b9ec7..e85966553e 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabelsTableProvider.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintLabelsTableProvider.java @@ -160,15 +160,16 @@ public class TaintLabelsTableProvider extends ComponentProviderAdapter { TaintState state = plugin.getTaintState(); - Task queryTask = new Task("Source-Sink Query Task", true, true, true, true) { + Task queryTask = new Task("Source-Sink Query Task", true, false, false, true) { @Override public void run(TaskMonitor monitor) { - state.setCancellation(false); monitor.initialize(program.getFunctionManager().getFunctionCount()); // query index NOT the default query; use table data. boolean successful = state.queryIndex(currentProgram, tool, QueryType.SRCSINK); - state.setCancellation(!successful || monitor.isCancelled()); + if (!successful) { + state.cancel(); + } monitor.clearCancelled(); } }; @@ -180,7 +181,7 @@ public class TaintLabelsTableProvider extends ComponentProviderAdapter { // 1. Query Index. tool.execute(queryTask); - if (!state.wasCancelled()) { + if (!state.isCancelled()) { // 2. Show Table. SarifService sarifService = plugin.getSarifService(); sarifService.getController() @@ -192,8 +193,6 @@ public class TaintLabelsTableProvider extends ComponentProviderAdapter { TaintProvider provider = plugin.getProvider(); provider.setTaint(); plugin.consoleMessage("query complete"); - state.setCancellation(false); - } else { plugin.consoleMessage("Source-Sink query was cancelled."); 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 c5bbccdbae..4e17637a75 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 @@ -265,7 +265,7 @@ public class TaintProvider extends ComponentProviderAdapter implements OptionsCh state.setTaskType(taskType); AddressSet taintAddressSet = state.getTaintAddressSet(); - Msg.info(this, "setTaint(): " + taintAddressSet.toString()); + //Msg.info(this, "setTaint(): " + taintAddressSet.toString()); // sets the selection in the LISTING? // TODO: should we not set select and only highlight in the decompilation. diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintQueryResult.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintQueryResult.java index 22724c9bc7..c487a16c3d 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintQueryResult.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/TaintQueryResult.java @@ -119,6 +119,9 @@ public record TaintQueryResult(String name,String fqname, Address iaddr, Address if (fqname.contains(":"+hvName)) { return hvName; } + if (fqname.contains(":"+ast.getAddress())) { + return hvName; + } } } 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 12a4dd37cb..6cf2f51ad9 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 @@ -35,6 +35,7 @@ import ghidra.program.model.symbol.SymbolTable; import ghidra.util.Msg; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ExtensionPoint; +import ghidra.util.task.TaskMonitor; /** * The interface for the methods that collect desired taint information from the decompiler window and store them @@ -92,6 +93,8 @@ public interface TaintState extends ExtensionPoint { */ public boolean queryIndex(Program program, PluginTool tool, QueryType queryType); + public String getQueryName(); + public TaintLabel toggleMark(MarkType mtype, ClangToken token) throws PcodeException; public Set getTaintLabels(MarkType mtype); @@ -121,9 +124,11 @@ public interface TaintState extends ExtensionPoint { // predicate that indicates there are sources, sinks, or gates. public boolean hasMarks(); - public boolean wasCancelled(); + public void setMonitor(TaskMonitor monitor); - public void setCancellation(boolean status); + public boolean isCancelled(); + + public void cancel(); public void setTaintVarnodeMap(Map> vmap, TaskType delta); 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 52ee73f957..39fe4eb0bc 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 @@ -76,11 +76,9 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc @Override public void run(TaskMonitor monitor) { TaintState state = plugin.getTaintState(); - state.setCancellation(false); - monitor.initialize(program.getFunctionManager().getFunctionCount()); + state.setMonitor(monitor); state.queryIndex(program, tool, queryType); - state.setCancellation(monitor.isCancelled()); - monitor.clearCancelled(); + state.setMonitor(null); } }; @@ -91,11 +89,15 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc tool.execute(defaultQueryTask); TaintState state = plugin.getTaintState(); - if (!state.wasCancelled()) { + if (!defaultQueryTask.isCancelled()) { TaintFormat format = state.getOptions().getTaintOutputForm(); if (!format.equals(TaintFormat.NONE)) { SarifService sarifService = plugin.getSarifService(); sarifService.getController().setDefaultGraphHander(SarifTaintGraphRunHandler.class); + String queryName = state.getQueryName(); + if (queryName != null) { + desc = queryName; + } sarifService.showSarif(desc, state.getData()); } @@ -104,11 +106,9 @@ public abstract class TaintAbstractQueryAction extends TaintAbstractDecompilerAc provider.setTaint(); plugin.consoleMessage("query complete"); - state.setCancellation(false); } else { plugin.consoleMessage("Source-Sink query was cancelled."); - } } } 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 022c364e35..1d181c930e 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 @@ -28,7 +28,7 @@ public class TaintQueryDefaultAction extends TaintAbstractQueryAction { public TaintQueryDefaultAction(TaintPlugin plugin) { super(plugin, "DefaultQuery", "Default Taint Query", "Run default taint query"); - executeTaintQueryIconString = "icon.version.tracking.markup.status.conflict"; + executeTaintQueryIconString = "icon.plugin.decompiler.taint.default.query"; 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 index c33f3b7c51..cb8c7991f2 100644 --- 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 @@ -23,6 +23,7 @@ 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.HelpLocation; import ghidra.util.UndefinedFunction; /** @@ -46,6 +47,7 @@ public class TaintSetSizeAction extends TaintAbstractDecompilerAction { public TaintSetSizeAction(TaintPlugin plugin) { super("Set length"); + setHelpLocation(new HelpLocation(TaintPlugin.HELP_LOCATION, TaintPlugin.HELP_LOCATION)); // Taint Menu -> Source sub item. setPopupMenuData(new MenuData(new String[] { "Taint", "Set length" }, "Decompile")); this.plugin = plugin; diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/sarif/SarifTaintResultHandler.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/sarif/SarifTaintResultHandler.java index ea5e94e8bf..41de9cdaab 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/sarif/SarifTaintResultHandler.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/decompiler/taint/sarif/SarifTaintResultHandler.java @@ -216,6 +216,7 @@ public class SarifTaintResultHandler extends SarifResultHandler { protected void doRun(TaskMonitor monitor) { int[] selected = tableProvider.filterTable.getTable().getSelectedRows(); Map> map = new HashMap<>(); + AddressSet set = new AddressSet(); for (int row : selected) { Map r = tableProvider.getRow(row); String kind = (String) r.get("kind"); @@ -225,12 +226,17 @@ public class SarifTaintResultHandler extends SarifResultHandler { if (kind.equals("variable")) { getTaintedVariable(map, r); } + Address addr = (Address) r.get("Address"); + if (addr != null) { + set.add(addr); + } } PluginTool tool = tableProvider.getController().getPlugin().getTool(); TaintService service = tool.getService(TaintService.class); if (service != null) { service.setVarnodeMap(map, true, taskType); + service.setAddressSet(set, false); } } diff --git a/Ghidra/Features/DecompilerDependent/src/main/resources/images/default-query.png b/Ghidra/Features/DecompilerDependent/src/main/resources/images/default-query.png new file mode 100644 index 0000000000..b789c54462 Binary files /dev/null and b/Ghidra/Features/DecompilerDependent/src/main/resources/images/default-query.png differ diff --git a/Ghidra/Features/DecompilerDependent/src/main/resources/images/gate-set.png b/Ghidra/Features/DecompilerDependent/src/main/resources/images/gate-set.png new file mode 100644 index 0000000000..2d618a99a7 Binary files /dev/null and b/Ghidra/Features/DecompilerDependent/src/main/resources/images/gate-set.png differ diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java b/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java index 0f7cfaf826..cdc2aaac8d 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/SarifController.java @@ -111,6 +111,10 @@ public class SarifController implements ObjectSelectedListener clazz) { defaultGraphHandler = clazz; } diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java b/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java index a9f5c62edb..9192e8a5d3 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/SarifUtils.java @@ -92,6 +92,31 @@ public class SarifUtils { return locations; } + public static JsonArray setLocation(Address addr, String kind, String uri, String name, String fqname, int index) { + JsonArray locations = new JsonArray(); + JsonObject element = new JsonObject(); + locations.add(element); + JsonObject ploc = new JsonObject(); + JsonArray lloc = new JsonArray(); + element.add("physicalLocation", ploc); + element.add("logicalLocations", lloc); + JsonObject artifact = new JsonObject(); + artifact.addProperty("uri", uri); + JsonObject address = new JsonObject(); + ploc.add("artifactLocation", artifact); + ploc.add("address", address); + address.addProperty("absoluteAddress", addr.getOffset()); + if (name != null) { + address.addProperty("name", name); + } + address.addProperty("kind", kind); + address.addProperty("fullyQualifiedName", fqname); + JsonObject ll = new JsonObject(); + lloc.add(ll); + ll.addProperty("index", index); + return locations; + } + @SuppressWarnings("unchecked") public static AddressSet getLocations(Map result, Program program, AddressSet set) throws AddressOverflowException { diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/ExtLogicalLocation.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/ExtLogicalLocation.java new file mode 100644 index 0000000000..f8a43dccf6 --- /dev/null +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/ExtLogicalLocation.java @@ -0,0 +1,49 @@ +/* ### + * 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 sarif.export; + +import ghidra.program.model.data.ISF.IsfObject; +import ghidra.program.model.listing.Function; + +public class ExtLogicalLocation implements IsfObject { + + String name; + String kind; + String decoratedName; + String fullyQualifiedName; + String uri; + + public ExtLogicalLocation(String key, Function function, String location, String op) { + this.name = key; + this.kind = "variable"; + this.decoratedName = op; + this.fullyQualifiedName = location + ":" + name; + this.uri = function.getProgram().getExecutablePath(); + } + + public String getName() { + return name; + } + + public String getDecoratedName() { + return decoratedName; + } + + public String getFullyQualfiedName() { + return fullyQualifiedName; + } + +} diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java index 343e54fdfb..68115caedb 100644 --- a/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/SarifObject.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -67,6 +67,13 @@ public class SarifObject implements IsfObject { } } + public SarifObject(String key, String ruleKey, ExtLogicalLocation lloc, JsonElement tree, Address addr, int index) { + this(key, ruleKey, tree); + if (addr != null) { + locations = SarifUtils.setLocation(addr, "data", lloc.uri, lloc.name, lloc.fullyQualifiedName, index); + } + } + protected void writeLocations(Address min, Address max) { if (SARIF) { locations = SarifUtils.setLocations(min, max); diff --git a/Ghidra/Features/Sarif/src/main/java/sarif/export/WrappedLogicalLocation.java b/Ghidra/Features/Sarif/src/main/java/sarif/export/WrappedLogicalLocation.java new file mode 100644 index 0000000000..731ca3698d --- /dev/null +++ b/Ghidra/Features/Sarif/src/main/java/sarif/export/WrappedLogicalLocation.java @@ -0,0 +1,47 @@ +/* ### + * 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 sarif.export; + +import ghidra.program.model.address.Address; + +public class WrappedLogicalLocation { + + private ExtLogicalLocation lloc; + private Address addr; + private int index; + + public WrappedLogicalLocation(ExtLogicalLocation lloc, Address addr) { + this.lloc = lloc; + this.addr = addr; + } + + public ExtLogicalLocation getLogicalLocation() { + return lloc; + } + + public Address getAddress() { + return addr; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + +}