mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Graphing - (various fixes; see below)
-fixed bug that prevented actions being added to sub graphs -subgraph gets bad tab text -properties documentation -fixed incorrect vertex shape function applied to lightweight renderer -dispose actions on close
This commit is contained in:
parent
4041c3693b
commit
e983784753
10 changed files with 262 additions and 179 deletions
|
@ -362,9 +362,9 @@
|
|||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<H3><A NAME="Rename_Vertex"></A>Rename Vertex</H3>
|
||||
<H3><A NAME="Rename_Symbol"></A>Rename Symbol</H3>
|
||||
<BLOCKQUOTE>
|
||||
<P>Allows the user to rename the symbol represented by the given vertex.
|
||||
<P>Allows the user to rename the symbol in the program represented by the given vertex.
|
||||
</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
|
|
|
@ -18,8 +18,10 @@ package ghidra.graph.program;
|
|||
import java.awt.Color;
|
||||
import java.util.*;
|
||||
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.widgets.EventTrigger;
|
||||
import ghidra.app.plugin.core.colorizer.ColorizingService;
|
||||
import ghidra.app.util.AddEditDialog;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.block.*;
|
||||
|
@ -28,8 +30,7 @@ import ghidra.program.model.symbol.*;
|
|||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.service.graph.*;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.GraphException;
|
||||
import ghidra.util.task.Task;
|
||||
|
@ -145,6 +146,7 @@ public class BlockGraphTask extends Task {
|
|||
GraphDisplay display = graphProvider.getGraphDisplay(reuseGraph, monitor);
|
||||
BlockModelGraphDisplayListener listener =
|
||||
new BlockModelGraphDisplayListener(tool, blockModel, display);
|
||||
addActions(display, v -> listener.getAddress(v));
|
||||
display.setGraphDisplayListener(listener);
|
||||
|
||||
if (showCode) {
|
||||
|
@ -175,6 +177,37 @@ public class BlockGraphTask extends Task {
|
|||
}
|
||||
}
|
||||
|
||||
private void addActions(GraphDisplay display,
|
||||
java.util.function.Function<AttributedVertex, Address> addressFunction) {
|
||||
|
||||
display.addAction(new ActionBuilder("Rename Symbol", "Block Graph")
|
||||
.popupMenuPath("Rename Symbol")
|
||||
.withContext(VertexGraphActionContext.class)
|
||||
.helpLocation(new HelpLocation("ProgramGraphPlugin", "Rename_Symbol"))
|
||||
// only enable action when vertex corresponds to an address
|
||||
.enabledWhen(c -> addressFunction.apply(c.getClickedVertex()) != null)
|
||||
.onAction(c -> updateVertexName(addressFunction, c))
|
||||
.build());
|
||||
}
|
||||
|
||||
private void updateVertexName(
|
||||
java.util.function.Function<AttributedVertex, Address> addressFunction,
|
||||
VertexGraphActionContext context) {
|
||||
|
||||
AttributedVertex vertex = context.getClickedVertex();
|
||||
Address address = addressFunction.apply(vertex);
|
||||
Symbol symbol = program.getSymbolTable().getPrimarySymbol(address);
|
||||
|
||||
if (symbol == null) {
|
||||
AddEditDialog dialog = new AddEditDialog("Create Label", tool);
|
||||
dialog.addLabel(address, program, context.getComponentProvider());
|
||||
}
|
||||
else {
|
||||
AddEditDialog dialog = new AddEditDialog("Edit Label", tool);
|
||||
dialog.editLabel(symbol, program, context.getComponentProvider());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of code lines which will be used per block when
|
||||
* showCode is enabled.
|
||||
|
@ -318,10 +351,8 @@ public class BlockGraphTask extends Task {
|
|||
CodeBlockReference cbRef = refIter.next();
|
||||
|
||||
CodeBlock db = cbRef.getDestinationBlock();
|
||||
|
||||
// must be a reference to a data block
|
||||
if (db == null) {
|
||||
continue;
|
||||
continue; // must be a reference to a data block
|
||||
}
|
||||
|
||||
// don't include destination if it does not overlap selection
|
||||
|
@ -336,7 +367,6 @@ public class BlockGraphTask extends Task {
|
|||
}
|
||||
|
||||
// put the edge in the graph
|
||||
String edgeAddr = cbRef.getReferent().toString();
|
||||
AttributedEdge newEdge = graph.addEdge(fromVertex, toVertex);
|
||||
|
||||
// set it's attributes (really its name)
|
||||
|
|
|
@ -17,16 +17,13 @@ package ghidra.graph.program;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import ghidra.app.plugin.core.graph.AddressBasedGraphDisplayListener;
|
||||
import ghidra.app.util.AddEditDialog;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.block.*;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.service.graph.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -41,18 +38,11 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
|||
GraphDisplay display) {
|
||||
super(tool, blockModel.getProgram(), display);
|
||||
this.blockModel = blockModel;
|
||||
addActions(display);
|
||||
}
|
||||
|
||||
private void addActions(GraphDisplay display) {
|
||||
display.addAction(new ActionBuilder("Rename Vertex", "Block Graph")
|
||||
.popupMenuPath("Rename Vertex")
|
||||
.withContext(VertexGraphActionContext.class)
|
||||
.helpLocation(new HelpLocation("ProgramGraphPlugin", "Rename Vertex"))
|
||||
// only enable action when vertex corresponds to an address
|
||||
.enabledWhen(c -> getAddress(c.getClickedVertex().getId()) != null)
|
||||
.onAction(this::updateVertexName)
|
||||
.build());
|
||||
@Override
|
||||
public Address getAddress(AttributedVertex vertex) {
|
||||
return super.getAddress(vertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,25 +69,7 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
|||
// Identify all blocks which have an entry point within the selection address set
|
||||
Set<AttributedVertex> vertices = new HashSet<>();
|
||||
try {
|
||||
SymbolTable symTable = program.getSymbolTable();
|
||||
CodeBlockIterator cbIter =
|
||||
blockModel.getCodeBlocksContaining(addrSet, TaskMonitor.DUMMY);
|
||||
while (cbIter.hasNext()) {
|
||||
CodeBlock block = cbIter.next();
|
||||
String addrString;
|
||||
Address addr = block.getFirstStartAddress();
|
||||
if (addr.isExternalAddress()) {
|
||||
Symbol s = symTable.getPrimarySymbol(addr);
|
||||
addrString = s.getName(true);
|
||||
}
|
||||
else {
|
||||
addrString = addr.toString();
|
||||
}
|
||||
AttributedVertex vertex = graphDisplay.getGraph().getVertex(addrString);
|
||||
if (vertex != null) {
|
||||
vertices.add(vertex);
|
||||
}
|
||||
}
|
||||
addVerticesForAddresses(addrSet, vertices);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// Will not happen with dummyMonitor
|
||||
|
@ -107,37 +79,39 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
|||
return vertices;
|
||||
}
|
||||
|
||||
private void addVerticesForAddresses(AddressSetView addrSet, Set<AttributedVertex> vertices)
|
||||
throws CancelledException {
|
||||
|
||||
SymbolTable symTable = program.getSymbolTable();
|
||||
CodeBlockIterator it =
|
||||
blockModel.getCodeBlocksContaining(addrSet, TaskMonitor.DUMMY);
|
||||
while (it.hasNext()) {
|
||||
CodeBlock block = it.next();
|
||||
String addrString;
|
||||
Address addr = block.getFirstStartAddress();
|
||||
if (addr.isExternalAddress()) {
|
||||
Symbol s = symTable.getPrimarySymbol(addr);
|
||||
addrString = s.getName(true);
|
||||
}
|
||||
else {
|
||||
addrString = addr.toString();
|
||||
}
|
||||
AttributedVertex vertex = graphDisplay.getGraph().getVertex(addrString);
|
||||
if (vertex != null) {
|
||||
vertices.add(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddressSet getAddresses(Set<AttributedVertex> vertices) {
|
||||
AddressSet addrSet = new AddressSet();
|
||||
|
||||
AddressSet addrSet = new AddressSet();
|
||||
try {
|
||||
// for each address string, translate it into a block
|
||||
// and add it to the address set.
|
||||
for (AttributedVertex vertex : vertices) {
|
||||
Address blockAddr = getAddress(vertex);
|
||||
if (!isValidAddress(blockAddr)) {
|
||||
continue;
|
||||
}
|
||||
CodeBlock blocks[] = null;
|
||||
if (blockModel != null) {
|
||||
CodeBlock block = blockModel.getCodeBlockAt(blockAddr, TaskMonitor.DUMMY);
|
||||
if (block != null) {
|
||||
blocks = new CodeBlock[1];
|
||||
blocks[0] = block;
|
||||
}
|
||||
else {
|
||||
blocks = blockModel.getCodeBlocksContaining(blockAddr, TaskMonitor.DUMMY);
|
||||
}
|
||||
}
|
||||
if (blocks != null && blocks.length > 0) {
|
||||
for (CodeBlock block : blocks) {
|
||||
addrSet.add(block);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addrSet.addRange(blockAddr, blockAddr);
|
||||
}
|
||||
addBlockAddresses(addrSet, vertex);
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
|
@ -147,6 +121,35 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
|||
return addrSet;
|
||||
}
|
||||
|
||||
private void addBlockAddresses(AddressSet addrSet, AttributedVertex vertex)
|
||||
throws CancelledException {
|
||||
|
||||
Address blockAddr = getAddress(vertex);
|
||||
if (!isValidAddress(blockAddr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CodeBlock blocks[] = null;
|
||||
if (blockModel != null) {
|
||||
CodeBlock block = blockModel.getCodeBlockAt(blockAddr, TaskMonitor.DUMMY);
|
||||
if (block != null) {
|
||||
blocks = new CodeBlock[1];
|
||||
blocks[0] = block;
|
||||
}
|
||||
else {
|
||||
blocks = blockModel.getCodeBlocksContaining(blockAddr, TaskMonitor.DUMMY);
|
||||
}
|
||||
}
|
||||
if (blocks != null && blocks.length > 0) {
|
||||
for (CodeBlock block : blocks) {
|
||||
addrSet.add(block);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addrSet.addRange(blockAddr, blockAddr);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isValidAddress(Address addr) {
|
||||
if (addr == null || program == null) {
|
||||
return false;
|
||||
|
@ -154,21 +157,6 @@ public class BlockModelGraphDisplayListener extends AddressBasedGraphDisplayList
|
|||
return program.getMemory().contains(addr) || addr.isExternalAddress();
|
||||
}
|
||||
|
||||
private void updateVertexName(VertexGraphActionContext context) {
|
||||
AttributedVertex vertex = context.getClickedVertex();
|
||||
Address address = getAddress(vertex);
|
||||
Symbol symbol = program.getSymbolTable().getPrimarySymbol(address);
|
||||
|
||||
if (symbol == null) {
|
||||
AddEditDialog dialog = new AddEditDialog("Create Label", tool);
|
||||
dialog.addLabel(address, program, context.getComponentProvider());
|
||||
}
|
||||
else {
|
||||
AddEditDialog dialog = new AddEditDialog("Edit Label", tool);
|
||||
dialog.editLabel(symbol, program, context.getComponentProvider());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDisplayListener cloneWith(GraphDisplay newGraphDisplay) {
|
||||
return new BlockModelGraphDisplayListener(tool, blockModel, newGraphDisplay);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue