use chrono::{DateTime, Local}; use nix::libc::user_regs_struct; use owo_colors::OwoColorize; use ratatui::{ prelude::{Line, Span, Style}, style::{Color, Modifier}, }; #[cfg(all(target_arch = "x86_64", target_os = "linux"))] use crate::arch::linux::x86_64::*; #[cfg(not(all(target_arch = "x86_64", target_os = "linux")))] use crate::arch::syscall_name; /// Struct used to manipulate registers data from https://docs.rs/libc/0.2.147/libc/struct.user_regs_struct.html #[derive(Debug)] pub struct RegistersData { timestamp: DateTime, orig_rax: u64, rdi: u64, rsi: u64, rdx: u64, r10: u64, r8: u64, r9: u64, rax: u64, } impl RegistersData { /// Create new `RegistersData` from an `user_regs_struct`'C structure pub fn new(registers: user_regs_struct) -> RegistersData { RegistersData { timestamp: Local::now(), orig_rax: registers.orig_rax, rdi: registers.rdi, rsi: registers.rsi, rdx: registers.rdx, r10: registers.r10, r8: registers.r8, r9: registers.r9, rax: registers.rax, } } /// Get date in ISO 8601 / RFC 3339 date & time string format pub fn date(&self) -> String { self.timestamp.format("%+").to_string() } /// Return the rax name as syscall name pub fn name(&self) -> &str { syscall_name(self.orig_rax) } /// Returns a good string which shows the output for a line pub fn output(&self) -> String { let mut output = format!("[{}]: ", self.date()); if self.name().len() > 0 { output.push_str(&format!("{}(", self.name().bold())); } else { output.push_str(&format!("{}(", self.orig_rax.yellow().bold())); } let mut has_param = false; let params = [ (self.rdi, rdi(self.orig_rax)), (self.rsi, rsi(self.orig_rax)), (self.rdx, rdx(self.orig_rax)), (self.r10, r10(self.orig_rax)), (self.r8, r8(self.orig_rax)), (self.r9, r9(self.orig_rax)), ]; for param in params { if param.1.len() != 0 { let output_param = param.1.to_owned() + ":"; output.push_str(&format!("{} {}, ", output_param.blue(), param.0)); has_param = true; } } if has_param { output.remove(output.len() - 1); output.remove(output.len() - 1); } output.push_str(&format!(") = 0x{:x}", self.rax)[..]); output } /// Returns a good line for TUI pub fn output_ui(&self) -> Line { let mut spans: Vec = vec![]; spans.push(Span::raw(format!("[{}]: ", self.date()))); if self.name().len() > 0 { spans.push(Span::styled( format!("{}(", self.name()), Style::default().add_modifier(Modifier::BOLD), )); } else { spans.push(Span::styled( format!("{}(", self.orig_rax), Style::default() .fg(Color::Yellow) .add_modifier(Modifier::BOLD), )); } let params = [ (self.rdi, rdi(self.orig_rax)), (self.rsi, rsi(self.orig_rax)), (self.rdx, rdx(self.orig_rax)), (self.r10, r10(self.orig_rax)), (self.r8, r8(self.orig_rax)), (self.r9, r9(self.orig_rax)), ]; for param in params { if param.1.len() != 0 { let output_param = param.1.to_owned() + ":"; spans.push(Span::styled( format!("{} ", output_param), Style::default().fg(Color::Blue), )); spans.push(Span::styled(format!("{}, ", param.0), Style::default())); } } spans.push(Span::styled( format!(") = 0x{:x}", self.rax), Style::default(), )); Line::from(spans) } }