mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-256 - Graphing - fixed AST graph exceptions
This commit is contained in:
parent
7764f965be
commit
edc8efdbf6
7 changed files with 51 additions and 31 deletions
|
@ -120,6 +120,10 @@ public abstract class AddressBasedGraphDisplayListener
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String id = getVertexId(address);
|
String id = getVertexId(address);
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return graphDisplay.getGraph().getVertex(id);
|
return graphDisplay.getGraph().getVertex(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +206,9 @@ public abstract class AddressBasedGraphDisplayListener
|
||||||
|
|
||||||
private void handleSymbolAddedOrRenamed(Address address, Symbol symbol) {
|
private void handleSymbolAddedOrRenamed(Address address, Symbol symbol) {
|
||||||
AttributedVertex vertex = getVertex(address);
|
AttributedVertex vertex = getVertex(address);
|
||||||
|
if (vertex == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
graphDisplay.updateVertexName(vertex, symbol.getName());
|
graphDisplay.updateVertexName(vertex, symbol.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.test;
|
package ghidra.test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ToyProgramBuilder extends ProgramBuilder {
|
public class ToyProgramBuilder extends ProgramBuilder {
|
||||||
|
|
||||||
private static final String TOY_LANGUAGE_ID_BE = "Toy:BE:32:builder";
|
private static final String TOY_LANGUAGE_ID_BE = "Toy:BE:32:builder";
|
||||||
|
@ -106,7 +106,7 @@ public class ToyProgramBuilder extends ProgramBuilder {
|
||||||
/**
|
/**
|
||||||
* Get address in default ram space
|
* Get address in default ram space
|
||||||
* @param offset address offset
|
* @param offset address offset
|
||||||
* @return address
|
* @return the address
|
||||||
*/
|
*/
|
||||||
public Address getAddress(long offset) {
|
public Address getAddress(long offset) {
|
||||||
return defaultSpace.getAddress(offset);
|
return defaultSpace.getAddress(offset);
|
||||||
|
|
|
@ -123,13 +123,7 @@ public class ASTGraphTask extends Task {
|
||||||
graphType == GraphType.DATA_FLOW_GRAPH ? "AST Data Flow" : "AST Control Flow";
|
graphType == GraphType.DATA_FLOW_GRAPH ? "AST Data Flow" : "AST Control Flow";
|
||||||
description = description + " for " + hfunction.getFunction().getName();
|
description = description + " for " + hfunction.getFunction().getName();
|
||||||
display.setGraph(graph, description, false, monitor);
|
display.setGraph(graph, description, false, monitor);
|
||||||
// set the graph location
|
setGraphLocation(display, displayListener);
|
||||||
if (location != null) {
|
|
||||||
AttributedVertex vertex = displayListener.getVertex(location);
|
|
||||||
// update graph location, but don't have it send out event
|
|
||||||
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (GraphException e) {
|
catch (GraphException e) {
|
||||||
Msg.showError(this, null, "Graph Error", e.getMessage());
|
Msg.showError(this, null, "Graph Error", e.getMessage());
|
||||||
|
@ -140,6 +134,20 @@ public class ASTGraphTask extends Task {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setGraphLocation(GraphDisplay display, ASTGraphDisplayListener displayListener) {
|
||||||
|
if (location == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedVertex vertex = displayListener.getVertex(location);
|
||||||
|
if (vertex == null) {
|
||||||
|
return; // location not in graph
|
||||||
|
}
|
||||||
|
|
||||||
|
// update graph location, but don't have it send out event
|
||||||
|
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
protected void createDataFlowGraph(AttributedGraph graph, TaskMonitor monitor)
|
protected void createDataFlowGraph(AttributedGraph graph, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
Iterator<PcodeOpAST> opIter = hfunction.getPcodeOps();
|
Iterator<PcodeOpAST> opIter = hfunction.getPcodeOps();
|
||||||
|
|
|
@ -770,7 +770,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the {@link AttributedGraph} for visualization
|
* set the {@link AttributedGraph} for visualization
|
||||||
* @param attributedGraph the {@link AttributedGraph} to visualize
|
* @param attributedGraph the {@link AttributedGraph} to visualize
|
||||||
|
@ -784,7 +783,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||||
configureViewerPreferredSize();
|
configureViewerPreferredSize();
|
||||||
|
|
||||||
Swing.runNow(() -> {
|
Swing.runNow(() -> {
|
||||||
// set the graph but defer the layoutalgorithm setting
|
// set the graph but defer the layout algorithm setting
|
||||||
viewer.getVisualizationModel().setGraph(graph, false);
|
viewer.getVisualizationModel().setGraph(graph, false);
|
||||||
configureFilters();
|
configureFilters();
|
||||||
LayoutAlgorithm<AttributedVertex> initialLayoutAlgorithm =
|
LayoutAlgorithm<AttributedVertex> initialLayoutAlgorithm =
|
||||||
|
@ -795,8 +794,8 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a vertex is a root. For our purpose, a root either has no incomming edges
|
* Determines if a vertex is a root. For our purpose, a root either has no incoming edges
|
||||||
* or has at least one outgoing "favored" edge and no incomming "favored" edge
|
* or has at least one outgoing "favored" edge and no incoming "favored" edge
|
||||||
* @param vertex the vertex to test if it is a root
|
* @param vertex the vertex to test if it is a root
|
||||||
* @return true if the vertex is a root
|
* @return true if the vertex is a root
|
||||||
*/
|
*/
|
||||||
|
@ -1208,7 +1207,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the hide selected action states to determine what vertices are shown:
|
* Use the hide selected action states to determine what vertices are shown:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class BlockGraphTask extends Task {
|
||||||
private CodeBlockModel blockModel;
|
private CodeBlockModel blockModel;
|
||||||
private AddressSetView selection;
|
private AddressSetView selection;
|
||||||
private ProgramLocation location;
|
private ProgramLocation location;
|
||||||
private GraphDisplayProvider graphService;
|
private GraphDisplayProvider graphProvider;
|
||||||
private boolean reuseGraph;
|
private boolean reuseGraph;
|
||||||
private boolean appendGraph;
|
private boolean appendGraph;
|
||||||
private PluginTool tool;
|
private PluginTool tool;
|
||||||
|
@ -116,7 +116,7 @@ public class BlockGraphTask extends Task {
|
||||||
public BlockGraphTask(String actionName, boolean graphEntryPointNexus, boolean showCode,
|
public BlockGraphTask(String actionName, boolean graphEntryPointNexus, boolean showCode,
|
||||||
boolean reuseGraph, boolean appendGraph, PluginTool tool, ProgramSelection selection,
|
boolean reuseGraph, boolean appendGraph, PluginTool tool, ProgramSelection selection,
|
||||||
ProgramLocation location, CodeBlockModel blockModel,
|
ProgramLocation location, CodeBlockModel blockModel,
|
||||||
GraphDisplayProvider graphService) {
|
GraphDisplayProvider graphProvider) {
|
||||||
|
|
||||||
super("Graph Program", true, false, true);
|
super("Graph Program", true, false, true);
|
||||||
this.actionName = actionName;
|
this.actionName = actionName;
|
||||||
|
@ -127,7 +127,7 @@ public class BlockGraphTask extends Task {
|
||||||
this.appendGraph = appendGraph;
|
this.appendGraph = appendGraph;
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
this.blockModel = blockModel;
|
this.blockModel = blockModel;
|
||||||
this.graphService = graphService;
|
this.graphProvider = graphProvider;
|
||||||
this.colorizingService = tool.getService(ColorizingService.class);
|
this.colorizingService = tool.getService(ColorizingService.class);
|
||||||
this.selection = selection;
|
this.selection = selection;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
|
@ -142,7 +142,7 @@ public class BlockGraphTask extends Task {
|
||||||
AttributedGraph graph = createGraph();
|
AttributedGraph graph = createGraph();
|
||||||
monitor.setMessage("Generating Graph...");
|
monitor.setMessage("Generating Graph...");
|
||||||
try {
|
try {
|
||||||
GraphDisplay display = graphService.getGraphDisplay(reuseGraph, monitor);
|
GraphDisplay display = graphProvider.getGraphDisplay(reuseGraph, monitor);
|
||||||
BlockModelGraphDisplayListener listener =
|
BlockModelGraphDisplayListener listener =
|
||||||
new BlockModelGraphDisplayListener(tool, blockModel, display);
|
new BlockModelGraphDisplayListener(tool, blockModel, display);
|
||||||
display.setGraphDisplayListener(listener);
|
display.setGraphDisplayListener(listener);
|
||||||
|
|
|
@ -30,6 +30,10 @@ import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.test.*;
|
import ghidra.test.*;
|
||||||
|
|
||||||
public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest {
|
public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
protected static final String CALLER_FUNCTION_ADDRESS = "01002200";
|
||||||
|
protected static final String SIMPLE_FUNCTION_ADDRESS = "01002239";
|
||||||
|
|
||||||
protected PluginTool tool;
|
protected PluginTool tool;
|
||||||
protected ProgramDB program;
|
protected ProgramDB program;
|
||||||
protected TestEnv env;
|
protected TestEnv env;
|
||||||
|
@ -37,10 +41,6 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
private ToyProgramBuilder builder;
|
private ToyProgramBuilder builder;
|
||||||
protected CodeBrowserPlugin codeBrowser;
|
protected CodeBrowserPlugin codeBrowser;
|
||||||
|
|
||||||
protected Address addr(long addr) {
|
|
||||||
return builder.getAddress(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
tool = env.getTool();
|
tool = env.getTool();
|
||||||
|
|
||||||
initializeTool();
|
initializeTool();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -80,14 +79,15 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
builder = new ToyProgramBuilder("sample", true);
|
builder = new ToyProgramBuilder("sample", true);
|
||||||
builder.createMemory("caller", "0x01002200", 8);
|
builder.createMemory("caller", "0x01002200", 8);
|
||||||
builder.createMemory("simple", "0x01002239", 8);
|
builder.createMemory("simple", "0x01002239", 8);
|
||||||
|
builder.createMemory("not_graphed", "0x01002300", 8);
|
||||||
|
|
||||||
buildCallerFunction(builder);
|
buildCallerFunction();
|
||||||
buildSimpleFunction(builder);
|
buildSimpleFunction();
|
||||||
|
|
||||||
program = builder.getProgram();
|
program = builder.getProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildCallerFunction(ToyProgramBuilder builder) throws MemoryAccessException {
|
private void buildCallerFunction() throws MemoryAccessException {
|
||||||
// just a function that calls another
|
// just a function that calls another
|
||||||
builder.addBytesNOP("0x01002200", 1);
|
builder.addBytesNOP("0x01002200", 1);
|
||||||
builder.addBytesCall("0x01002201", "0x01002239");// jump to C
|
builder.addBytesCall("0x01002201", "0x01002239");// jump to C
|
||||||
|
@ -98,7 +98,7 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
builder.createLabel("0x01002200", "entry");// function label
|
builder.createLabel("0x01002200", "entry");// function label
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildSimpleFunction(ToyProgramBuilder builder) throws MemoryAccessException {
|
private void buildSimpleFunction() throws MemoryAccessException {
|
||||||
// just a function to render in the graph so that we can clear out settings/cache
|
// just a function to render in the graph so that we can clear out settings/cache
|
||||||
// 01002239
|
// 01002239
|
||||||
|
|
||||||
|
@ -128,4 +128,12 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
builder.createLabel("0x01002239", "simple");// function label
|
builder.createLabel("0x01002239", "simple");// function label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Address addr(long addr) {
|
||||||
|
return builder.getAddress(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Address addr(String addressString) {
|
||||||
|
return builder.addr(addressString);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertTrue(selectedVertices.contains(b));
|
assertTrue(selectedVertices.contains(b));
|
||||||
|
|
||||||
// now try and select a second vertex
|
// now try and select a second vertex
|
||||||
context = new VertexGraphActionContext(graphComponentProvider, graph, null, null,d);
|
context = new VertexGraphActionContext(graphComponentProvider, graph, null, null, d);
|
||||||
performAction(action, context, true);
|
performAction(action, context, true);
|
||||||
selectedVertices = display.getSelectedVertices();
|
selectedVertices = display.getSelectedVertices();
|
||||||
assertEquals(2, selectedVertices.size());
|
assertEquals(2, selectedVertices.size());
|
||||||
|
@ -197,7 +197,6 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertTrue(selectedVerticeIds.contains(c));
|
assertTrue(selectedVerticeIds.contains(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGrowSelectionIn() {
|
public void testGrowSelectionIn() {
|
||||||
select(d);
|
select(d);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue