diff options
author | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 22:00:43 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 22:00:43 +0200 |
commit | f9207a326c7f0e5861ee9489313861fdcd7bbff0 (patch) | |
tree | a647f8da6f596a608efffff8170da8d8db3a3b22 | |
parent | d3095900b941d7b08d579f9dc5e9dac45690228b (diff) |
Add lines style
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 9 | ||||
-rw-r--r-- | src/registers.rs | 28 | ||||
-rw-r--r-- | src/trace.rs | 9 | ||||
-rw-r--r-- | src/ui.rs | 7 |
6 files changed, 50 insertions, 11 deletions
@@ -239,6 +239,12 @@ dependencies = [ ] [[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -332,6 +338,7 @@ dependencies = [ "crossterm", "fork", "nix", + "owo-colors", "ratatui", ] @@ -12,4 +12,5 @@ clap = { version = "4.4.6", features = ["derive"] } crossterm = "0.27.0" fork = "0.1.22" nix = { version = "0.27.1", features = ["ptrace"] } +owo-colors = "3.5.0" ratatui = "0.23.0" diff --git a/src/main.rs b/src/main.rs index 9e025b7..19a9533 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,13 +37,14 @@ fn main() -> anyhow::Result<()> { Ok(Fork::Parent(child)) => Pid::from_raw(child), Err(err) => panic!("fork() failed: {err}"), }; - let output = trace(pid, args.file_to_print)?; - let lines = str::from_utf8(&output)?.trim(); + let registers = trace(pid, args.file_to_print)?; if !args.no_tui { - run_tui(pid, lines)?; + run_tui(pid, ®isters)?; } else { - writeln!(io::stdout(), "{lines}")?; + for line in registers { + writeln!(io::stdout(), "{}", line.output())?; + } } Ok(()) diff --git a/src/registers.rs b/src/registers.rs index 80b4a9b..d73424d 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -1,4 +1,9 @@ use nix::libc::user_regs_struct; +use owo_colors::OwoColorize; +use ratatui::{ + prelude::{Line, Span, Style}, + style::Modifier, +}; /// Struct used to manipulate registers data from https://docs.rs/libc/0.2.147/libc/struct.user_regs_struct.html pub struct RegistersData { @@ -25,7 +30,28 @@ impl RegistersData { pub fn output(&self) -> String { format!( "{}({:x}, {:x}, {:x}, ...) = {:x}", - self.orig_rax, self.rdi, self.rsi, self.rdx, self.rax + self.orig_rax.bold(), + self.rdi, + self.rsi, + self.rdx, + self.rax ) } + + /// Returns a good line for TUI + pub fn output_ui(&self) -> Line { + Line::from(vec![ + Span::styled( + format!("{}", self.orig_rax), + Style::default().add_modifier(Modifier::BOLD), + ), + Span::styled( + format!( + "({:x}, {:x}, {:x}, ...) = {:x}", + self.rdi, self.rsi, self.rdx, self.rax + ), + Style::default(), + ), + ]) + } } diff --git a/src/trace.rs b/src/trace.rs index 399f1c6..3612519 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -25,8 +25,8 @@ pub fn exec(command: &str) -> anyhow::Result<()> { Ok(()) } -/// Trace a process with `pid` ID -pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<Vec<u8>> { +/// Trace a process with `pid` ID and returns a list of `RegistersData` +pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<Vec<RegistersData>> { // Since you have to do 2 syscalls (start and end) you have to alternate the print value, // because it could be equals except for the `rax` register. let mut have_to_print = true; @@ -41,7 +41,7 @@ pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<Vec<u8>> f = Some(File::create(filename)?); } - let mut lines = Vec::new(); + let mut lines: Vec<RegistersData> = Vec::new(); loop { have_to_print ^= true; @@ -59,11 +59,12 @@ pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<Vec<u8>> Signal::SIGTRAP => { if have_to_print { let reg = RegistersData::new(ptrace::getregs(pid)?); - writeln!(lines, "{}", reg.output())?; if let Some(ref mut f) = f { writeln!(f, "{}", reg.output())?; } + + lines.push(reg); } } _ => {} @@ -1,3 +1,4 @@ +use crate::registers::RegistersData; use crossterm::{ event::{self, Event, KeyCode}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, @@ -55,19 +56,21 @@ fn handle_events(ui: &mut UI) -> io::Result<bool> { Ok(false) } -pub fn run_tui(pid: Pid, lines: &str) -> anyhow::Result<()> { +pub fn run_tui(pid: Pid, registers: &Vec<RegistersData>) -> anyhow::Result<()> { enable_raw_mode()?; stdout().execute(EnterAlternateScreen)?; let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; let mut ui = UI::new(); - ui.max_lines = lines.split('\n').count() + 1; + ui.max_lines = registers.len() + 1; let mut should_quit = false; while !should_quit { ui.height = terminal.get_frame().size().height as usize; terminal.draw(move |frame| { let size = frame.size(); + let lines: Vec<Line> = registers.iter().map(|x| x.output_ui()).collect(); + frame.render_widget( Paragraph::new(lines) .block( |