summaryrefslogtreecommitdiff
path: root/src/registers.rs
blob: c42bb126ff56e30487373a017aa90900708c1ea5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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<Local>,
    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<Span> = 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)
    }
}