55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
use clap::clap_app;
|
|
use petgraph::dot::{Config as DotConfig, Dot};
|
|
|
|
use ppc750cl::{disasm_iter, Ins};
|
|
|
|
pub mod flow;
|
|
pub mod slices;
|
|
|
|
use crate::flow::FlowGraph;
|
|
use crate::slices::BasicSlices;
|
|
use dol::Dol;
|
|
|
|
fn main() {
|
|
let matches = clap_app!(myapp =>
|
|
(version: "1.0")
|
|
(about: "Control flow graph analysis for PowerPC 750CL")
|
|
(@arg START: --start +required +takes_value "Start address")
|
|
(@arg STOP: --stop +required +takes_value "Stop address")
|
|
(@arg INPUT: +required "Binary input file")
|
|
)
|
|
.get_matches();
|
|
|
|
let start_addr = matches.value_of("START").unwrap();
|
|
let start_addr: u32 = ::parse_int::parse(start_addr).expect("Invalid address flag");
|
|
let stop_addr = matches.value_of("STOP").unwrap();
|
|
let stop_addr: u32 = ::parse_int::parse(stop_addr).expect("Invalid address flag");
|
|
|
|
let file_path = matches.value_of("INPUT").unwrap();
|
|
let dol_file = std::fs::File::open(file_path).expect("Failed to read file");
|
|
let dol = Dol::read_from(&dol_file).expect("Invalid DOL file");
|
|
drop(dol_file);
|
|
let mut bytes = vec![0u8; (stop_addr - start_addr) as usize];
|
|
dol.virtual_read(&mut bytes, start_addr);
|
|
|
|
// Create control flow graph.
|
|
let ins_list: Vec<Ins> = disasm_iter(&bytes, start_addr).collect();
|
|
let basic_slices = BasicSlices::from_code(&ins_list);
|
|
let graph = FlowGraph::from_basic_slices(&basic_slices, &ins_list);
|
|
|
|
// Output graphviz.
|
|
let graphviz = Dot::with_config(
|
|
&graph.graph,
|
|
&[DotConfig::EdgeNoLabel, DotConfig::GraphContentOnly],
|
|
);
|
|
println!(
|
|
concat!(
|
|
"digraph func {{\n",
|
|
"node [shape=record fontname=Arial];\n",
|
|
"{:?}\n",
|
|
"}}"
|
|
),
|
|
graphviz
|
|
);
|
|
}
|