mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00

GP-3443: clean-up & comment GP-3443: more help edits; fix for QueryResult error GP-3443: actions refactor GP-3443: record fix + html fixes GP-3443: misc GP-3443: fixes for help GP-3443: more post-review GP-3443: refactor on queries + other stuff GP-3443: test improvement GP-3443: post-review more easy GP-3443: post-review easy fixes GP-3443: imports GP-3443: formatting fixes GP-3443: better test GP-3443: more test improvemnts GP-3443: fix for fields, more test stuff GP-3443: prelims for testing GP-3443: more work on edge cases GP-3443: fix for locals fixed GP-3443: fix for locals GP-3443: by symbol fix GP-3443: by symbol fix GP-3443: minor ergonomics GP-3443: simpler query GP-3443: fix for structs GP-3443: fix for clear GP-3443: thunks working GP-3443: more deps GP-3443: dependencies fix GP-3443: gates GP-3443: imports organized GP-3443: oops GP-3443: oops GP-3443: pretty substantial refactor GP-3443: marks now location-specific GP-3443: better clear GP-3443: fairly major logic change GP-3443: (better) functioning plugin GP-3443: better docs GP-3443: script GP-3443: script GP-3443: bueno GP-3443: manual rebase
168 lines
5.2 KiB
Java
168 lines
5.2 KiB
Java
/* ###
|
|
* 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.view;
|
|
|
|
import java.awt.BorderLayout;
|
|
import java.util.*;
|
|
|
|
import javax.swing.JComponent;
|
|
import javax.swing.JPanel;
|
|
|
|
import docking.ComponentProvider;
|
|
import docking.action.DockingAction;
|
|
import ghidra.app.services.GoToService;
|
|
import ghidra.framework.plugintool.Plugin;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.listing.Program;
|
|
import ghidra.service.graph.AttributedVertex;
|
|
import ghidra.util.table.GhidraFilterTable;
|
|
import ghidra.util.table.GhidraTable;
|
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
|
import sarif.SarifController;
|
|
import sarif.handlers.SarifResultHandler;
|
|
import sarif.model.*;
|
|
import sarif.model.SarifResultsTableModelFactory.SarifResultsTableModel;
|
|
|
|
/**
|
|
* Show the SARIF result as a table and build possible actions on the table
|
|
*
|
|
*/
|
|
public class SarifResultsTableProvider extends ComponentProvider {
|
|
|
|
private JComponent component;
|
|
public SarifResultsTableModel model;
|
|
public GhidraFilterTable<Map<String, Object>> filterTable;
|
|
public Program program;
|
|
private Plugin plugin;
|
|
private SarifController controller;
|
|
|
|
public SarifResultsTableProvider(String description, Plugin plugin, SarifController controller,
|
|
SarifDataFrame df) {
|
|
super(plugin.getTool(), controller.getProgram().getName(), plugin.getName());
|
|
this.plugin = plugin;
|
|
this.controller = controller;
|
|
this.program = controller.getProgram();
|
|
SarifResultsTableModelFactory factory = new SarifResultsTableModelFactory(df.getColumns());
|
|
this.model = factory.createModel(description, plugin.getTool(), program, df);
|
|
this.component = buildPanel();
|
|
filterTable.getTable()
|
|
.getSelectionModel()
|
|
.addListSelectionListener(e -> plugin.getTool().contextChanged(this));
|
|
this.createActions();
|
|
this.setTransient();
|
|
}
|
|
|
|
private JComponent buildPanel() {
|
|
JPanel panel = new JPanel(new BorderLayout());
|
|
filterTable = new GhidraFilterTable<>(this.model);
|
|
GhidraTable table = filterTable.getTable();
|
|
|
|
GoToService goToService = this.getTool().getService(GoToService.class);
|
|
table.installNavigation(plugin.getTool(), goToService.getDefaultNavigatable());
|
|
table.setNavigateOnSelectionEnabled(true);
|
|
panel.add(filterTable);
|
|
return panel;
|
|
}
|
|
|
|
public void dispose() {
|
|
filterTable.dispose();
|
|
closeComponent();
|
|
}
|
|
|
|
@Override
|
|
public void closeComponent() {
|
|
super.closeComponent();
|
|
getController().removeProvider(this);
|
|
}
|
|
|
|
@Override
|
|
public JComponent getComponent() {
|
|
return component;
|
|
}
|
|
|
|
/**
|
|
* Columns are added to the table based on if they are required by the SARIF
|
|
* format or are a taxonomy that the SARIF file defines We "support" certain
|
|
* taxonomies here by if the names match adding additional context actions that
|
|
* can be performed
|
|
*/
|
|
public void createActions() {
|
|
DockingAction selectionAction =
|
|
new MakeProgramSelectionAction(this.plugin, filterTable.getTable());
|
|
this.addLocalAction(selectionAction);
|
|
Set<SarifResultHandler> resultHandlers = controller.getSarifResultHandlers();
|
|
List<SarifColumnKey> columns = model.getDataFrame().getColumns();
|
|
List<String> keyNames = new ArrayList<>();
|
|
for (SarifColumnKey key : columns) {
|
|
keyNames.add(key.getName());
|
|
}
|
|
for (SarifResultHandler handler : resultHandlers) {
|
|
if (keyNames.contains(handler.getKey())) {
|
|
if (handler.getActionName() != null) {
|
|
this.addLocalAction(handler.createAction(this));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getIndex(String key) {
|
|
List<SarifColumnKey> columns = model.getDataFrame().getColumns();
|
|
for (SarifColumnKey c : columns) {
|
|
if (c.getName().equals(key)) {
|
|
columns.indexOf(c);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public Object getValue(int x, int y) {
|
|
return model.getColumnValueForRow(model.getRowObject(x), y);
|
|
}
|
|
|
|
public Map<String, Object> getRow(int x) {
|
|
return model.getRowObject(x);
|
|
}
|
|
|
|
public SarifController getController() {
|
|
return controller;
|
|
}
|
|
|
|
public SarifDataFrame getDataFrame() {
|
|
return model.getDataFrame();
|
|
}
|
|
|
|
public void setSelection(Set<AttributedVertex> vertices) {
|
|
for (AttributedVertex vertex : vertices) {
|
|
Map<String, String> attributes = vertex.getAttributes();
|
|
if (attributes.containsKey("Address")) {
|
|
String addrStr = attributes.get("Address");
|
|
String name = attributes.get("name");
|
|
for (int i = 0; i < model.getRowCount(); i++) {
|
|
Address address = model.getAddress(i);
|
|
if (address != null && address.toString(true).equals(addrStr)) {
|
|
Map<String, Object> rowObject = model.getRowObject(i);
|
|
String objName = (String) rowObject.get("name");
|
|
if (name.equals(objName)) {
|
|
filterTable.getTable().selectRow(i);
|
|
filterTable.getTable().scrollToSelectedRow();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|