From adbd39ab7c3d4e67e8709af43176e60f31141ba8 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Thu, 8 May 2025 21:39:12 -0400 Subject: [Rust] Flow graph API improvements - Fixed some misc bugs - Added real FlowGraphEdge type - Added accessors for node edges - Added interaction handler to the flow graph example to dump the flow graph to stdin - Split out the flow graph API into smaller files --- rust/examples/flowgraph.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) (limited to 'rust/examples') diff --git a/rust/examples/flowgraph.rs b/rust/examples/flowgraph.rs index 6666b7fb..515d52fe 100644 --- a/rust/examples/flowgraph.rs +++ b/rust/examples/flowgraph.rs @@ -1,9 +1,82 @@ +use binaryninja::flowgraph::edge::EdgeStyle; +use binaryninja::flowgraph::FlowGraphNode; +use binaryninja::function::FunctionViewType; +use binaryninja::interaction::form::Form; +use binaryninja::interaction::handler::{ + register_interaction_handler, InteractionHandler, InteractionHandlerTask, +}; +use binaryninja::interaction::{MessageBoxButtonResult, MessageBoxButtonSet, MessageBoxIcon}; use binaryninja::{ binary_view::{BinaryView, BinaryViewExt}, disassembly::{DisassemblyTextLine, InstructionTextToken, InstructionTextTokenKind}, - flowgraph::{BranchType, EdgePenStyle, EdgeStyle, FlowGraph, FlowGraphNode, ThemeColor}, + flowgraph::{BranchType, EdgePenStyle, FlowGraph, ThemeColor}, }; +pub struct GraphPrinter; + +impl GraphPrinter { + pub fn print_graph(&self, _view: &BinaryView, graph: &FlowGraph) { + println!("Printing flow graph:"); + for node in &graph.nodes() { + // Print all disassembly lines in the node + println!("Node @ {:?}:", node.position()); + println!("------------------"); + println!("Disassembly lines:"); + for line in &node.lines() { + println!(" {}", line); + } + + // Print outgoing edges + println!("Outgoing edges:"); + for edge in &node.outgoing_edges() { + println!(" {:?} => {:?}", edge.branch_type, edge.target.position()); + } + println!("------------------"); + } + } +} + +impl InteractionHandler for GraphPrinter { + fn show_message_box( + &mut self, + _title: &str, + _text: &str, + _buttons: MessageBoxButtonSet, + _icon: MessageBoxIcon, + ) -> MessageBoxButtonResult { + MessageBoxButtonResult::CancelButton + } + + fn open_url(&mut self, _url: &str) -> bool { + false + } + + fn run_progress_dialog( + &mut self, + _title: &str, + _can_cancel: bool, + _task: &InteractionHandlerTask, + ) -> bool { + false + } + + fn show_plain_text_report(&mut self, _view: &BinaryView, title: &str, contents: &str) { + println!("Plain text report"); + println!("Title: {}", title); + println!("Contents: {}", contents); + } + + fn show_graph_report(&mut self, view: &BinaryView, title: &str, graph: &FlowGraph) { + println!("Graph report"); + println!("Title: {}", title); + self.print_graph(view, graph); + } + + fn get_form_input(&mut self, _form: &mut Form) -> bool { + false + } +} + fn test_graph(view: &BinaryView) { let graph = FlowGraph::new(); @@ -15,8 +88,10 @@ fn test_graph(view: &BinaryView) { let node_a = FlowGraphNode::new(&graph); node_a.set_lines(disassembly_lines_a); + node_a.set_position(1337, 7331); let node_b = FlowGraphNode::new(&graph); + node_b.set_position(100, 200); let disassembly_lines_b = vec![DisassemblyTextLine::new(vec![ InstructionTextToken::new("Li", InstructionTextTokenKind::Text), InstructionTextToken::new("ne", InstructionTextTokenKind::Text), @@ -49,8 +124,16 @@ fn main() { .load("/bin/cat") .expect("Couldn't open `/bin/cat`"); - // TODO: Register BNInteractionHandlerCallbacks with showGraphReport pointing at our function - // TODO: Idea: register showGraphReport that dumps a dotgraph to stdin + // Register the interaction handler so we can see the graph report headlessly. + register_interaction_handler(GraphPrinter); test_graph(&bv); + + for func in bv.functions().iter().take(5) { + let graph = func.create_graph(FunctionViewType::MediumLevelIL, None); + assert!(!graph.nodes().is_empty()); + let func_name = func.symbol().short_name(); + let title = func_name.to_string_lossy(); + bv.show_graph_report(&title, &graph); + } } -- cgit v1.3.1